Merge branch 'dev' into user_management

This commit is contained in:
Michal Kváček
2016-01-29 12:27:03 +01:00
156 changed files with 6753 additions and 176 deletions
+21
View File
@@ -0,0 +1,21 @@
<?php
namespace App\Enumerations;
use App\Models\ActionLogType;
class ActionLogTypes extends BaseEnumeration
{
/**
* Init list of all action log types
*
* @throws Exceptions\EnumerationExistsException
*/
protected static function init()
{
$types = ActionLogType::all(['id', 'name']);
foreach ($types as $type) {
self::push($type->id, $type->name);
}
}
}
@@ -0,0 +1,16 @@
<?php
namespace App\Enumerations;
use App\Models\ActionLogType;
class ActionLogTypesForLogger extends BaseEnumeration
{
protected static function init()
{
$types = ActionLogType::all(['string_id', 'id']);
foreach ($types as $type) {
self::push($type->string_id, $type->id);
}
}
}
+5
View File
@@ -26,6 +26,11 @@ abstract class BaseEnumeration
$className::init(); $className::init();
} }
// it can happen that even after init no enumerations are available
if (empty(self::$items[$className])) {
self::$items[$className] = [];
}
self::$initiliazed[] = $className; self::$initiliazed[] = $className;
} }
} }
+21
View File
@@ -0,0 +1,21 @@
<?php
namespace App\Enumerations;
use App\Models\Content;
class ContentStatuses extends BaseEnumeration
{
protected static function init()
{
$roles = [
Content::STATUS_DRAFT => 'admin/contents.status_' . Content::STATUS_DRAFT,
Content::STATUS_DELETED => 'admin/contents.status_' . Content::STATUS_DELETED,
Content::STATUS_PROTECTED => 'admin/contents.status_' . Content::STATUS_PROTECTED,
Content::STATUS_PUBLIC => 'admin/contents.status_' . Content::STATUS_PUBLIC
];
foreach ($roles as $role => $translation) {
self::push($role, $translation);
}
}
}
+21
View File
@@ -0,0 +1,21 @@
<?php
namespace App\Enumerations;
use App\Models\Module;
class Modules extends BaseEnumeration
{
/**
* Init list of all installed modules
*
* @throws Exceptions\EnumerationExistsException
*/
protected static function init()
{
$modules = Module::all(['handler', 'name']);
foreach ($modules as $module) {
self::push($module->handler, $module->name);
}
}
}
+22
View File
@@ -0,0 +1,22 @@
<?php
namespace App\Events;
use App\Events\Event;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class ChangeSettings extends Event
{
use SerializesModels;
/**
* Create a new event instance.
*
* @return void
*/
public function __construct()
{
//
}
}
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace App\Events;
use App\Events\Event;
use App\Models\CustomField;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class CreateNewCustomField extends Event
{
use SerializesModels;
/**
* @var CustomField
*/
public $customField;
/**
* Create a new event instance.
*
* @param CustomField $customField
*/
public function __construct(CustomField $customField)
{
$this->customField = $customField;
}
}
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace App\Events;
use App\Events\Event;
use App\Models\User;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class CreateNewUser extends Event
{
use SerializesModels;
/**
* @var User
*/
public $user;
/**
* Create a new event instance.
*
* @param User $user
*/
public function __construct(User $user)
{
$this->user = $user;
}
}
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace App\Events;
use App\Events\Event;
use App\Models\CustomField;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class DeleteCustomField extends Event
{
use SerializesModels;
/**
* @var CustomField
*/
public $customField;
/**
* Create a new event instance.
*
* @param CustomField $customField
*/
public function __construct(CustomField $customField)
{
$this->customField = $customField;
}
}
+27
View File
@@ -0,0 +1,27 @@
<?php
namespace App\Events;
use App\Events\Event;
use App\Models\CustomField;
use Illuminate\Queue\SerializesModels;
use Illuminate\Contracts\Broadcasting\ShouldBroadcast;
class EditCustomField extends Event
{
use SerializesModels;
/**
* @var CustomField
*/
public $customField;
/**
* Create a new event instance.
*
* @param CustomField $customField
*/
public function __construct(CustomField $customField)
{
$this->customField = $customField;
}
}
+25
View File
@@ -0,0 +1,25 @@
<?php
namespace App\Events;
use App\Models\User;
use Illuminate\Queue\SerializesModels;
class EditUser extends Event
{
use SerializesModels;
/**
* @var User
*/
public $user;
/**
* Create a new event instance.
*
* @param User $user
*/
public function __construct(User $user)
{
$this->user = $user;
}
}
+6
View File
@@ -3,6 +3,7 @@
namespace App\Exceptions; namespace App\Exceptions;
use Exception; use Exception;
use Illuminate\Session\TokenMismatchException;
use Illuminate\Validation\ValidationException; use Illuminate\Validation\ValidationException;
use Illuminate\Auth\Access\AuthorizationException; use Illuminate\Auth\Access\AuthorizationException;
use Illuminate\Database\Eloquent\ModelNotFoundException; use Illuminate\Database\Eloquent\ModelNotFoundException;
@@ -45,6 +46,11 @@ class Handler extends ExceptionHandler
*/ */
public function render($request, Exception $e) public function render($request, Exception $e)
{ {
if ($e instanceof TokenMismatchException){
//redirect to form an example of how I handle mine
return redirect($request->fullUrl())->with('error', trans('validation.csrf'));
}
return parent::render($request, $e); return parent::render($request, $e);
} }
} }
+39
View File
@@ -0,0 +1,39 @@
<?php
namespace App\Handlers;
use App\Models\Content;
use App\Models\User;
use Illuminate\Support\Facades\Auth;
/**
* Class Handler
*
* Handler is a class which handles module-specific behaviour which cannot be done by module itself, resp. cannot be done by some abstract magic.
*
* @package App\Handlers
*/
abstract class 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
*/
abstract public function render(Content $content, $parameters);
/**
* 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)
{
//
}
}
@@ -4,8 +4,10 @@ namespace App\Http\Controllers\Admin;
use App\Enumerations\CustomFieldResources; use App\Enumerations\CustomFieldResources;
use App\Enumerations\CustomFieldTypes; use App\Enumerations\CustomFieldTypes;
use App\Events\CreateNewCustomField as CreateNewCustomFieldEvent;
use App\Http\Requests\NewCustomFieldRequest; use App\Http\Requests\NewCustomFieldRequest;
use App\Models\CustomField; use App\Models\CustomField;
use Illuminate\Support\Facades\Event;
class CreateNewCustomField extends Controller class CreateNewCustomField extends Controller
{ {
@@ -59,6 +61,9 @@ class CreateNewCustomField extends Controller
$customField->save(); $customField->save();
// fire event about creating new custom field
Event::fire(new CreateNewCustomFieldEvent($customField));
return redirect() return redirect()
->route('customfields.new') ->route('customfields.new')
->with('success', trans('admin/customFields.successfullyCreated')); ->with('success', trans('admin/customFields.successfullyCreated'));
+5 -1
View File
@@ -3,11 +3,12 @@
namespace App\Http\Controllers\Admin; namespace App\Http\Controllers\Admin;
use App\Enumerations\UserRoles; use App\Enumerations\UserRoles;
use App\Events\CreateNewUser as CreateNewUserEvent;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Http\Requests; use App\Http\Requests;
use App\Http\Requests\CreateNewUserRequest; use App\Http\Requests\CreateNewUserRequest;
use App\Models\User; use App\Models\User;
use Illuminate\Http\Request; use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
class CreateNewUser extends Controller class CreateNewUser extends Controller
@@ -51,6 +52,9 @@ class CreateNewUser extends Controller
// store user into database // store user into database
$user->save(); $user->save();
// fire event
Event::fire(new CreateNewUserEvent($user));
// refresh page with information about successfull registration // refresh page with information about successfull registration
return redirect() return redirect()
->route('users.new') ->route('users.new')
@@ -4,10 +4,13 @@ namespace App\Http\Controllers\Admin;
use App\Enumerations\CustomFieldResources; use App\Enumerations\CustomFieldResources;
use App\Enumerations\CustomFieldTypes; use App\Enumerations\CustomFieldTypes;
use App\Events\DeleteCustomField;
use App\Events\EditCustomField as EditCustomFieldEvent;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Http\Requests; use App\Http\Requests;
use App\Http\Requests\EditCustomFieldRequest; use App\Http\Requests\EditCustomFieldRequest;
use App\Models\CustomField; use App\Models\CustomField;
use Illuminate\Support\Facades\Event;
class EditCustomField extends Controller class EditCustomField extends Controller
{ {
@@ -60,6 +63,9 @@ class EditCustomField extends Controller
// save changes into database // save changes into database
$customField->save(); $customField->save();
// fire event about editing custom field
Event::fire(new EditCustomFieldEvent($customField));
return redirect() return redirect()
->route('customfields.edit', ['id' => $id]) ->route('customfields.edit', ['id' => $id])
->with('success', trans('admin/customFields.successfullyEdited')); ->with('success', trans('admin/customFields.successfullyEdited'));
@@ -89,6 +95,9 @@ class EditCustomField extends Controller
// delete item // delete item
$field->delete(); $field->delete();
// fire event about editing custom field
Event::fire(new DeleteCustomField($field));
// redirect back to overview // redirect back to overview
return redirect() return redirect()
->route('customfields.overview') ->route('customfields.overview')
+5
View File
@@ -4,11 +4,13 @@ namespace App\Http\Controllers\Admin;
use App\Enumerations\UserRoles; use App\Enumerations\UserRoles;
use App\Enumerations\UserStates; use App\Enumerations\UserStates;
use App\Events\EditUser as EditUserEvent;
use App\Http\Controllers\Controller; use App\Http\Controllers\Controller;
use App\Http\Requests; use App\Http\Requests;
use App\Http\Requests\EditUserRequest; use App\Http\Requests\EditUserRequest;
use App\Models\User; use App\Models\User;
use Illuminate\Support\Facades\Auth; use Illuminate\Support\Facades\Auth;
use Illuminate\Support\Facades\Event;
use Illuminate\Support\Facades\Hash; use Illuminate\Support\Facades\Hash;
class EditUser extends Controller class EditUser extends Controller
@@ -81,6 +83,9 @@ class EditUser extends Controller
$user->save(); $user->save();
// fire event about editing user
Event::fire(new EditUserEvent($user));
return redirect() return redirect()
->route('users.detail', ['id' => $id]) ->route('users.detail', ['id' => $id])
->with('success', trans('admin/userManagement.userSuccessfullyEdited')); ->with('success', trans('admin/userManagement.userSuccessfullyEdited'));
+2
View File
@@ -29,6 +29,7 @@ class Kernel extends HttpKernel
\Illuminate\Session\Middleware\StartSession::class, \Illuminate\Session\Middleware\StartSession::class,
\Illuminate\View\Middleware\ShareErrorsFromSession::class, \Illuminate\View\Middleware\ShareErrorsFromSession::class,
\App\Http\Middleware\VerifyCsrfToken::class, \App\Http\Middleware\VerifyCsrfToken::class,
\App\Http\Middleware\ModuleRegistrator::class
], ],
'api' => [ 'api' => [
@@ -45,6 +46,7 @@ class Kernel extends HttpKernel
*/ */
protected $routeMiddleware = [ protected $routeMiddleware = [
'auth' => \App\Http\Middleware\Authenticate::class, 'auth' => \App\Http\Middleware\Authenticate::class,
'onlyAdmin' => \App\Http\Middleware\RequireAdminRole::class,
// 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class, // 'auth.basic' => \Illuminate\Auth\Middleware\AuthenticateWithBasicAuth::class,
'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class, 'guest' => \App\Http\Middleware\RedirectIfAuthenticated::class,
'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class, 'throttle' => \Illuminate\Routing\Middleware\ThrottleRequests::class,
+33
View File
@@ -0,0 +1,33 @@
<?php
namespace App\Http\Middleware;
use Closure;
class ModuleRegistrator
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @return mixed
*/
public function handle($request, Closure $next)
{
$modules = \Module::enabled();
// iterate over all enabled modules
foreach ($modules as $key => $module) {
$handler = config($module->getName() . '.handler');
// try to register menus
if (method_exists($handler, 'registerAdminMenu') && \Auth::check()) {
call_user_func([$handler, 'registerAdminMenu'], \Auth::user());
}
}
return $next($request);
}
}
+28
View File
@@ -0,0 +1,28 @@
<?php
namespace App\Http\Middleware;
use App\Models\User;
use Closure;
class RequireAdminRole
{
/**
* Handle an incoming request.
*
* @param \Illuminate\Http\Request $request
* @param \Closure $next
*
* @return mixed
*/
public function handle($request, Closure $next)
{
if (\Auth::user()->role != User::ROLE_ADMIN) {
return redirect()
->back()
->with('error', trans('auth.accessDenied'));
}
return $next($request);
}
}
+43 -37
View File
@@ -28,22 +28,55 @@ Route::group([
'prefix' => 'admin' 'prefix' => 'admin'
], function () { ], function () {
// these routes are available only for user with role admin
Route::group(['middleware' => 'onlyAdmin'], function () {
// display form for creating new user
Route::get('users/new', 'CreateNewUser@getNewUser')
->name('users.new');
// POST methods
// display form for creating new user
Route::post('users/new', 'CreateNewUser@postRegistration')
->name('users.newPost');
// display form for edit of existing user
Route::get('users/edit/{id}', 'EditUser@getEditExistingUser')
->name('users.edit');
// form for adding new custom field
Route::get('customfields/new', 'CreateNewCustomField@getNew')
->name('customfields.new');
// form for editing custom field
Route::get('customfields/edit/{id}', 'EditCustomField@getEditCustomField')
->name('customfields.edit');
// form for adding new custom field
Route::post('customfields/new', 'CreateNewCustomField@postNew')
->name('customfields.newPost');
// form for editing custom field
Route::post('customfields/edit/{id}', 'EditCustomField@postEditCustomField')
->name('customfields.editPost');
Route::get('customfields/delete/{id}', 'EditCustomField@deleteCustomField')
->name('customfields.delete');
});
// these routes are available for all logged (authenticated) users
// display dashboard with some usefull information // display dashboard with some usefull information
Route::get('/', 'Dashboard@getIndex') Route::get('/', 'Dashboard@getIndex')
->name('admin.dashboard'); ->name('admin.dashboard');
// display form for creating new user
Route::get('users/new', 'CreateNewUser@getNewUser')
->name('users.new');
// display form for edit of existing user
Route::get('users/edit/{id}', 'EditUser@getEditExistingUser')
->name('users.edit');
// display user detail in admin // display user detail in admin
Route::get('users/detail/{id?}', 'UserDetail@getDetail') Route::get('users/detail/{id?}', 'UserDetail@getDetail')
->name('users.detail'); ->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 // display list of all users registered into our system
Route::get('users/overview/{state?}/{perPage?}', 'UsersOverview@getOverview') Route::get('users/overview/{state?}/{perPage?}', 'UsersOverview@getOverview')
->name('users.overview'); ->name('users.overview');
@@ -55,25 +88,6 @@ Route::group([
Route::get('customfields/overview', 'CustomFieldsOverview@getOverview') Route::get('customfields/overview', 'CustomFieldsOverview@getOverview')
->name('customfields.overview'); ->name('customfields.overview');
// form for adding new custom field
Route::get('customfields/new', 'CreateNewCustomField@getNew')
->name('customfields.new');
// form for editing custom field
Route::get('customfields/edit/{id}', 'EditCustomField@getEditCustomField')
->name('customfields.edit');
// form for adding new custom field
Route::post('customfields/new', 'CreateNewCustomField@postNew')
->name('customfields.newPost');
// form for editing custom field
Route::post('customfields/edit/{id}', 'EditCustomField@postEditCustomField')
->name('customfields.editPost');
Route::get('customfields/delete/{id}', 'EditCustomField@deleteCustomField')
->name('customfields.delete');
// logout method // logout method
Route::get('logout', function () { Route::get('logout', function () {
@@ -84,14 +98,6 @@ Route::group([
return redirect() return redirect()
->route('login') ->route('login')
->with('success', trans('admin/common.logoutSuccessfull')); ->with('success', trans('admin/common.logoutSuccessfull'));
})->name('logout'); })
->name('logout');
// POST methods
// display form for creating new user
Route::post('users/new', 'CreateNewUser@postRegistration')
->name('users.newPost');
// method for saving edited data of user
Route::post('users/edit/{id}', 'EditUser@postEdit')
->name('users.editPost');
}); });
+33
View File
@@ -0,0 +1,33 @@
<?php
namespace App\Listeners;
use App\Events\ChangeSettings;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class LogChangeSettings extends Logger
{
/**
* Handle the event.
*
* @param ChangeSettings $event
* @return void
*/
public function handle(ChangeSettings $event)
{
$parameters = [];
$this->saveLog($parameters);
}
/**
* Getter for action name. Used only internally
*
* @return mixed
*/
protected function getName()
{
return 'changeSettings';
}
}
+37
View File
@@ -0,0 +1,37 @@
<?php
namespace App\Listeners;
use App\Events\CreateNewCustomField;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class LogCreateCustomField extends Logger
{
/**
* Handle the event.
*
* @param CreateNewCustomField $event
* @return void
*/
public function handle(CreateNewCustomField $event)
{
$parameters = [
'id' => $event->customField->id,
'name' => $event->customField->name
];
$this->saveLog($parameters);
}
/**
* Getter for action name. Used only internally
*
* @return mixed
*/
protected function getName()
{
return 'newCustomField';
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace App\Listeners;
use App\Events\CreateNewUser;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class LogCreatedUser extends Logger
{
/**
* Handle the event.
*
* @param CreateNewUser $event
*/
public function handle(CreateNewUser $event)
{
$parameters = [
'id' => $event->user->id,
'name' => $event->user->name,
'email' => $event->user->email
];
$this->saveLog($parameters);
}
/**
* Getter for action name. Used only internally
*
* @return mixed
*/
protected function getName()
{
return 'createUser';
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace App\Listeners;
use App\Events\DeleteCustomField;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class LogDeleteField extends Logger
{
/**
* Handle the event.
*
* @param DeleteCustomField $event
* @return void
*/
public function handle(DeleteCustomField $event)
{
$parameters = [
'id' => $event->customField->id,
'name' => $event->customField->name
];
$this->saveLog($parameters);
}
/**
* Getter for action name. Used only internally
*
* @return mixed
*/
protected function getName()
{
return 'deleteCustomField';
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace App\Listeners;
use App\Events\EditCustomField;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class LogEditCustomField extends Logger
{
/**
* Handle the event.
*
* @param EditCustomField $event
* @return void
*/
public function handle(EditCustomField $event)
{
$parameters = [
'id' => $event->customField->id,
'name' => $event->customField->name
];
$this->saveLog($parameters);
}
/**
* Getter for action name. Used only internally
*
* @return mixed
*/
protected function getName()
{
return 'editCustomField';
}
}
+37
View File
@@ -0,0 +1,37 @@
<?php
namespace App\Listeners;
use App\Events\EditUser;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class LogEditUser extends Logger
{
/**
* Handle the event.
*
* @param EditUser $event
* @return void
*/
public function handle(EditUser $event)
{
$parameters = [
'id' => $event->user->id,
'name' => $event->user->name,
'email' => $event->user->email
];
$this->saveLog($parameters);
}
/**
* Getter for action name. Used only internally
*
* @return mixed
*/
protected function getName()
{
return 'userEdit';
}
}
+36
View File
@@ -0,0 +1,36 @@
<?php
namespace App\Listeners;
use Illuminate\Auth\Events\Login;
class LogLogin extends Logger
{
/**
* Handle the event.
*
* @param Login $event
*
* @return void
*/
public function handle(Login $event)
{
$parameters = [
'id' => $event->user->id,
'name' => $event->user->name,
'email' => $event->user->email
];
$this->saveLog($parameters);
}
/**
* Getter for action name. Used only internally
*
* @return mixed
*/
protected function getName()
{
return 'login';
}
}
+37
View File
@@ -0,0 +1,37 @@
<?php
namespace App\Listeners;
use Illuminate\Auth\Events\Logout;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
class LogLogout extends Logger
{
/**
* Handle the event.
*
* @param Logout $event
* @return void
*/
public function handle(Logout $event)
{
$parameters = [
'id' => $event->user->id,
'name' => $event->user->name,
'email' => $event->user->email
];
$this->saveLog($parameters);
}
/**
* Getter for action name. Used only internally
*
* @return mixed
*/
protected function getName()
{
return 'logout';
}
}
+74
View File
@@ -0,0 +1,74 @@
<?php
namespace App\Listeners;
use App\Enumerations\ActionLogTypesForLogger;
use App\Events\Event;
use App\Models\ActionLog;
use Illuminate\Support\Facades\Auth;
abstract class Logger
{
private $actionTypes = [];
/**
* Create the event listener.
*
* @return void
*/
public function __construct()
{
$this->actionTypes = ActionLogTypesForLogger::getWithTranslations();
}
/**
* Shortcut for loging events
*
* @param array $parameters
*/
protected function saveLog($parameters = [])
{
// try to translate string id into integer id
$typeId = $this->getTypeId();
// is user logged in and exists given type?
if (!Auth::check() || is_null($typeId)) {
return;
}
// get user id
$userId = Auth::user()->id;
// setup object for insertion
$data = [
'user_id' => $userId,
'type_id' => $typeId,
'parameters' => json_encode((array)$parameters)
];
// create new logged event
ActionLog::create($data);
}
/**
* Translate string id to integer id
*
* @return int|null ID of action type when exists, null otherwise
*/
private function getTypeId()
{
$name = $this->getName();
if (!isset($this->actionTypes[$name])) {
return null;
}
return $this->actionTypes[$name];
}
/**
* Getter for action name. Used only internally
*
* @return mixed
*/
abstract protected function getName();
}
+2 -1
View File
@@ -9,8 +9,9 @@ use Illuminate\Database\Eloquent\Model;
*/ */
class ActionLog extends Model class ActionLog extends Model
{ {
protected $table = 'action_log';
public $timestamps = true; public $timestamps = false;
protected $fillable = [ protected $fillable = [
'type_id', 'type_id',
+1
View File
@@ -14,6 +14,7 @@ class ActionLogType extends Model
protected $fillable = [ protected $fillable = [
'name', 'name',
'string_id',
'value' 'value'
]; ];
+97 -4
View File
@@ -3,15 +3,14 @@
namespace App\Models; namespace App\Models;
use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Facades\DB;
/** /**
* Class Content * Class Content
*/ */
class Content extends Model class Content extends Model
{ {
public $timestamps = true; public $timestamps = true;
protected $fillable = [ protected $fillable = [
'user_id', 'user_id',
'module_handler', 'module_handler',
@@ -26,8 +25,102 @@ class Content extends Model
'module_settings', 'module_settings',
'status' 'status'
]; ];
protected $guarded = []; protected $guarded = [];
const STATUS_DELETED = 'deleted';
const STATUS_DRAFT = 'draft';
const STATUS_PROTECTED = 'protected';
const STATUS_PUBLIC = 'public';
/**
* Getter for overview of all content pages of given handler (module type)
*
* @param $handler
* @param bool $joinAuthor
*
*/
public function getByType($handler, $joinAuthor = false)
{
$query = DB::table('contents')
->select('contents.*')
->where('contents.status', '<>', self::STATUS_DELETED)
->where('module_handler', $handler)
->orderBy('created_at');
// join user email and user name to results when needed
if ($joinAuthor) {
$query = $query->join('users', 'users.id', '=', 'contents.user_id')
->select('contents.*', 'users.name AS author_name', 'users.email AS author_email');
}
return $query;
}
/**
* Updates current model with information about changed columns
*
* @param array $fields
* @param array $request
*
* @return int number of changed columns
*/
public function updateWithHistory(array $fields, array $request)
{
$editBatch = uniqid();
$changed = 0;
foreach ($fields as $fieldDB => $fieldRequest) {
// ignore non-existing fields
if (!isset($this->$fieldDB) || !isset($request[$fieldRequest])) {
continue;
}
// remove any whitespaces around real content
$request[$fieldRequest] = trim($request[$fieldRequest]);
if ($this->$fieldDB != $request[$fieldRequest]) {
// setup history object
$history = [
'user_id' => \Auth::user()->id,
'content_id' => $this->id,
'edit_batch' => $editBatch,
'column' => $fieldRequest,
'old_value' => $this->$fieldDB,
'new_value' => $request[$fieldRequest]
];
// save history
ContentHistory::create($history);
// save change into database
$this->$fieldDB = $request[$fieldRequest];
$changed++;
}
}
$this->save();
return [$editBatch, $changed];
}
/**
* Mark relationship with its historical records
*
* @return \Illuminate\Database\Eloquent\Relations\HasMany
*/
public function history()
{
return $this->hasMany('App\Models\ContentHistory');
}
/**
* Mark relationship with users table
*
* @return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function author()
{
return $this->belongsTo('App\Models\User', 'user_id');
}
} }
+3 -2
View File
@@ -9,13 +9,14 @@ use Illuminate\Database\Eloquent\Model;
*/ */
class ContentHistory extends Model class ContentHistory extends Model
{ {
protected $table = 'content_history';
public $timestamps = true; // this table does not have created_at and updated_at fields
public $timestamps = false;
protected $fillable = [ protected $fillable = [
'user_id', 'user_id',
'content_id', 'content_id',
'changed_at',
'edit_batch', 'edit_batch',
'column', 'column',
'new_value', 'new_value',
+1 -1
View File
@@ -10,7 +10,7 @@ use Illuminate\Database\Eloquent\Model;
class Module extends Model class Module extends Model
{ {
public $timestamps = true; public $timestamps = false;
protected $fillable = [ protected $fillable = [
'handler', 'handler',
+24 -2
View File
@@ -13,8 +13,30 @@ class EventServiceProvider extends ServiceProvider
* @var array * @var array
*/ */
protected $listen = [ protected $listen = [
'App\Events\SomeEvent' => [ 'App\Events\CreateNewUser' => [
'App\Listeners\EventListener', 'App\Listeners\LogCreatedUser',
],
'App\Events\EditUser' => [
'App\Listeners\LogEditUser',
],
'App\Events\CreateNewCustomField' => [
'App\Listeners\LogCreateCustomField',
],
'App\Events\EditCustomField' => [
'App\Listeners\LogEditCustomField',
],
'App\Events\DeleteCustomField' => [
'App\Listeners\LogDeleteField',
],
'App\Events\ChangeSettings' => [
'App\Listeners\LogChangeSettings',
],
// internal Laravel events - should work as auth.login and auth.logout, however it doesn't...
'Illuminate\Auth\Events\Login' => [
'App\Listeners\LogLogin'
],
'Illuminate\Auth\Events\Logout' => [
'App\Listeners\LogLogout'
], ],
]; ];
+1
View File
@@ -182,6 +182,7 @@ return [
'Log' => Illuminate\Support\Facades\Log::class, 'Log' => Illuminate\Support\Facades\Log::class,
'Mail' => Illuminate\Support\Facades\Mail::class, 'Mail' => Illuminate\Support\Facades\Mail::class,
'Menu' => Pingpong\Menus\MenuFacade::class, 'Menu' => Pingpong\Menus\MenuFacade::class,
'Module' => Pingpong\Modules\Facades\Module::class,
'Password' => Illuminate\Support\Facades\Password::class, 'Password' => Illuminate\Support\Facades\Password::class,
'Queue' => Illuminate\Support\Facades\Queue::class, 'Queue' => Illuminate\Support\Facades\Queue::class,
'Redirect' => Illuminate\Support\Facades\Redirect::class, 'Redirect' => Illuminate\Support\Facades\Redirect::class,
+6
View File
@@ -0,0 +1,6 @@
<?php
return [
'name' => 'StaticPages',
'handler' => '\\Modules\\StaticPages\\Handlers\\StaticPage'
];
@@ -0,0 +1,33 @@
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
class AddStringIdForActionTypes extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::table('action_log_types', function (Blueprint $table) {
$table->string('string_id', 64)
->after('id')
->unique()->comment = 'String ID used for better readability in loggers';
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::table('action_log_types', function (Blueprint $table) {
$table->dropColumn('string_id');
});
}
}
+1
View File
@@ -14,5 +14,6 @@ class DatabaseSeeder extends Seeder
// fill up custom field types // fill up custom field types
$this->call(SeedCustomFieldTypes::class); $this->call(SeedCustomFieldTypes::class);
$this->call(SeedCustomFieldResources::class); $this->call(SeedCustomFieldResources::class);
$this->call(SeedActionLogTypes::class);
} }
} }
+34
View File
@@ -0,0 +1,34 @@
<?php
use Illuminate\Database\Seeder;
class SeedActionLogTypes extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
$types = [
'login',
'logout',
'userEdit',
'createUser',
'newCustomField',
'editCustomField',
'deleteCustomField',
'changeSettings'
];
foreach ($types as $type) {
\DB::table('action_log_types')
->insert([
'string_id' => $type,
'name' => 'admin/actionLog.name' . ucfirst($type),
'value' => 'admin/actionLog.' . $type
]);
}
}
}
+2 -1
View File
@@ -1,5 +1,6 @@
<?php <?php
return [ return [
'name' => 'StaticPages' 'name' => 'StaticPages',
'handler' => '\\Modules\\StaticPages\\Handlers\\StaticPage'
]; ];
@@ -0,0 +1,25 @@
<?php
namespace Modules\StaticPages\Events;
use App\Events\Event;
use App\Models\Content;
use Illuminate\Queue\SerializesModels;
class CreateNewStaticPage extends Event {
use SerializesModels;
/**
* @var Content
*/
public $page;
/**
* Create a new event instance.
*
* @param Content $page
*/
public function __construct(Content $page)
{
$this->page = $page;
}
}
@@ -0,0 +1,27 @@
<?php
namespace Modules\StaticPages\Events;
use App\Events\Event;
use App\Models\Content;
use Illuminate\Queue\SerializesModels;
class DeleteStaticPage extends Event {
use SerializesModels;
/**
* @var Content
*/
public $page;
public $revision;
/**
* Create a new event instance.
*
* @param Content $page
* @param $revision
*/
public function __construct(Content $page, $revision)
{
$this->page = $page;
$this->revision = $revision;
}
}
@@ -0,0 +1,28 @@
<?php
namespace Modules\StaticPages\Events;
use App\Events\Event;
use App\Models\Content;
use Illuminate\Queue\SerializesModels;
class EditStaticPage extends Event {
use SerializesModels;
/**
* @var Content
*/
public $page;
public $revision;
/**
* Create a new event instance.
*
* @param Content $page
* @param $revision
*/
public function __construct(Content $page, $revision)
{
$this->page = $page;
$this->revision = $revision;
}
}
@@ -0,0 +1,28 @@
<?php
namespace Modules\StaticPages\Events;
use App\Events\Event;
use App\Models\Content;
use Illuminate\Queue\SerializesModels;
class MakeDraftFromStaticPage extends Event {
use SerializesModels;
/**
* @var Content
*/
public $page;
public $revision;
/**
* Create a new event instance.
*
* @param Content $page
* @param $revision
*/
public function __construct(Content $page, $revision)
{
$this->page = $page;
$this->revision = $revision;
}
}
@@ -0,0 +1,29 @@
<?php
namespace Modules\StaticPages\Events;
use App\Events\Event;
use App\Models\Content;
use Illuminate\Queue\SerializesModels;
class PublishStaticPage extends Event {
use SerializesModels;
/**
* @var Content
*/
public $page;
public $revision;
/**
* Create a new event instance.
*
* @param Content $page
* @param $revision
*/
public function __construct(Content $page, $revision)
{
$this->page = $page;
$this->revision = $revision;
}
}
@@ -0,0 +1,36 @@
<?php
namespace Modules\StaticPages\Handlers;
use App\Handlers\Handler;
use App\Models\Content;
use App\Models\User;
class StaticPage extends Handler
{
public static function registerAdminMenu(User $user)
{
parent::registerAdminMenu($user);
// register links in admin menu
$menu = \Menu::instance('mainMenu');
$menu->dropdown(trans('staticpages::adminMenu.staticPages'), function ($submenu) use ($user) {
if ($user->role == User::ROLE_ADMIN) {
$submenu->route('staticpage.new', trans('staticpages::adminMenu.new'));
}
$submenu->route('staticpage.overview', trans('staticpages::adminMenu.overview'));
}, 15, ['icon' => 'fa fa-newspaper-o']);
}
/**
* 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)
{
// TODO: Implement render() method.
}
}
@@ -1,10 +1,60 @@
<?php <?php
namespace Modules\StaticPages\Http\Controllers\Admin; namespace Modules\StaticPages\Http\Controllers\Admin;
use App\Enumerations\ContentStatuses;
use App\Models\Content;
use Illuminate\Support\Facades\Event;
use Modules\StaticPages\Http\Requests\CreateNewStaticPageRequest;
class CreateNewStaticPage extends Controller class CreateNewStaticPage extends Controller
{ {
/**
* Display form for new static page
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function getNew() public function getNew()
{ {
return view('staticpages::index'); $statuses = ContentStatuses::getWithTranslations();
// we do not want to create deleted page
unset($statuses[Content::STATUS_DELETED]);
// render view
return view('staticpages::admin.new', [
'contentStatuses' => $statuses,
'selectedStatus' => Content::STATUS_DRAFT
]);
}
/**
* Save new static page
*
* @param CreateNewStaticPageRequest $request
*
* @return \Illuminate\Http\RedirectResponse
*/
public function postNew(CreateNewStaticPageRequest $request)
{
$page = new Content();
$page->user_id = \Auth::user()->id;
$page->title = $request->title;
$page->url = $request->url;
$page->published_from = $request->publishedFrom;
$page->published_to = $request->publishedTo;
$page->meta_keywords = $request->meta_description;
$page->meta_description = $request->meta_description;
$page->content = $request->pageContent;
$page->status = $request->status;
$page->module_handler = config('staticpages.handler');
$page->save();
Event::fire(new \Modules\StaticPages\Events\CreateNewStaticPage($page));
return redirect()
->route('staticpage.new')
->with('success', trans('staticpages::admin.successfullyCreated'));
} }
} }
@@ -1,10 +1,189 @@
<?php <?php
namespace Modules\StaticPages\Http\Controllers\Admin; namespace Modules\StaticPages\Http\Controllers\Admin;
use App\Enumerations\ContentStatuses;
use App\Models\Content;
use Illuminate\Support\Facades\Event;
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 EditStaticPage extends Controller class EditStaticPage extends Controller
{ {
/**
* Display form for editing static page
*
* @param $id
*
* @return \Illuminate\Contracts\View\Factory|\Illuminate\View\View
*/
public function getEdit($id) public function getEdit($id)
{ {
return view('staticpages::index'); // select all content statuses
$statuses = ContentStatuses::getWithTranslations();
// try to find requested page
$page = Content::where('module_handler', config('staticpages.handler'))
->findOrFail($id);
// render view
return view('staticpages::admin.edit', [
'contentStatuses' => $statuses,
'page' => $page
]);
}
/**
* Edit static page and save changes into history.
*
* @param EditStaticPageRequest $request
* @param $id
*
* @return \Illuminate\Http\RedirectResponse
*/
public function postEdit(EditStaticPageRequest $request, $id)
{
try {
$page = Content::where('module_handler', config('staticpages.handler'))
->findOrFail($id);
} catch (NotFoundHttpException $e) {
// page for editing not found
return redirect()
->route('staticpage.overview')
->with('error', trans('staticpages::admin.invalidPage'));
}
// array of fields in database and fields from request
$fields = [
'title' => 'title',
'url' => 'url',
'published_from' => 'publishedFrom',
'published_to' => 'publishedTo',
'meta_keywords' => 'metaKeywords',
'meta_description' => 'metaDescription',
'content' => 'pageContent',
'status' => 'status'
];
// save new values with history
list($revision, $changedColumns) = $page->updateWithHistory($fields, $request->all());
// was something changed?
if ($changedColumns == 0) {
return redirect()
->route('staticpage.edit', ['id' => $page->id])
->with('error', trans('staticpages::admin.nothingToEdit'));
}
// fire event with
Event::fire(new EditStaticPageEvent($page, $revision));
// something was changed, inform user
return redirect()
->route('staticpage.edit', ['id' => $page->id])
->with('success', trans('staticpages::admin.successfullyEdited'));
}
/**
* 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.
*
* @param $id
* @param $status
*
* @return \Illuminate\Http\RedirectResponse
*/
public function changeStatus($id, $status)
{
// get possible statuses
$statuses = ContentStatuses::getWithTranslations();
unset($statuses[Content::STATUS_DELETED]);
// check if given status is valid
if (!isset($statuses[$status])) {
return redirect()
->route('staticpage.overview')
->with('error', trans('staticpages::admin.invalidStatus'));
}
try {
// try to find this page
$page = Content::where('module_handler', config('staticpages.handler'))
->findOrFail($id);
} catch (NotFoundHttpException $e) {
// page not found
return redirect()
->route('staticpage.overview')
->with('error', trans('staticpages::admin.invalidPage'));
}
// try to change the page
list ($revision, $changedColumns) = $page->updateWithHistory(['status' => 'status'], ['status' => $status]);
// was something changed?
if ($changedColumns == 0) {
return redirect()
->route('staticpage.edit', ['id' => $page->id])
->with('error', trans('staticpages::admin.nothingToEdit'));
}
// fire events
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()
->route('staticpage.overview')
->with('success', trans('staticpages::admin.statusChanged'));
}
/**
* Delete page
*
* @param $id
*
* @return \Illuminate\Http\RedirectResponse
*/
public function deletePage($id)
{
try {
// try to find this page
$page = Content::where('module_handler', config('staticpages.handler'))
->findOrFail($id);
} catch (NotFoundHttpException $e) {
// page not found
return redirect()
->route('staticpage.overview')
->with('error', trans('staticpages::admin.invalidPage'));
}
list ($revision, $changedColumns) = $page->updateWithHistory(['status' => 'status'], ['status' => Content::STATUS_DELETED]);
// was something changed?
if ($changedColumns == 0) {
return redirect()
->route('staticpage.edit', ['id' => $page->id])
->with('error', trans('staticpages::admin.nothingToEdit'));
}
// trigger delete event
Event::fire(new DeleteStaticPage($page, $revision));
// redirect back to overview with info for user
return redirect()
->route('staticpage.overview')
->with('success', trans('staticpages::admin.pageDeleted', [
'name' => $page->title,
'url' => $page->url
]));
} }
} }
@@ -1,11 +1,22 @@
<?php <?php
namespace Modules\StaticPages\Http\Controllers\Admin; namespace Modules\StaticPages\Http\Controllers\Admin;
use App\Enumerations\ContentStatuses;
use App\Models\Content;
class StaticPageOverview extends Controller class StaticPageOverview extends Controller
{ {
public function getOverview() public function getOverview($perPage = 20, $status = null)
{ {
return view('staticpages::admin.overview'); $model = new Content();
$pages = $model->getByType(config('staticpages.handler'), true);
// add filtering by status
if (!is_null($status) && in_array($status, ContentStatuses::getSimple())) {
$pages = $pages->where('status', $status);
}
$pages = $pages->paginate($perPage);
return view('staticpages::admin.overview', ['pages' => $pages]);
} }
} }
@@ -0,0 +1,25 @@
<?php
namespace Modules\StaticPages\Http\Requests;
use App\Http\Requests\Request;
class CreateNewStaticPageRequest extends Request
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
return [
'title' => 'required',
'url' => 'required|unique:contents,url',
'published_from' => 'date',
'published_to' => 'date',
'title_photo' => 'exists:files,id',
'module_settings' => 'json',
'status' => 'required|in:draft,protected,public'
];
}
}
@@ -0,0 +1,29 @@
<?php
namespace Modules\StaticPages\Http\Requests;
use App\Enumerations\ContentStatuses;
use App\Http\Requests\Request;
class EditStaticPageRequest extends Request
{
/**
* Get the validation rules that apply to the request.
*
* @return array
*/
public function rules()
{
// get all available statuses
$statuses = ContentStatuses::getSimple();
$statuses = implode(',', $statuses);
return [
'title' => 'required',
'url' => 'required|unique:contents,url,'.$this->id,
'published_from' => 'date',
'published_to' => 'date',
'title_photo' => 'exists:files,id',
'status' => 'required|in:'.$statuses
];
}
}
+31 -1
View File
@@ -8,17 +8,47 @@ Route::group([
Route::get('/{url}', 'StaticPagesController@index'); Route::get('/{url}', 'StaticPagesController@index');
}); });
// routes group for admin area // routes group for admin area
Route::group([ Route::group([
'middleware' => ['web', 'auth'], 'middleware' => ['web', 'auth'],
'prefix' => 'admin/pages', 'prefix' => 'admin/pages',
'namespace' => 'Modules\StaticPages\Http\Controllers\Admin' 'namespace' => 'Modules\StaticPages\Http\Controllers\Admin'
], function () { ], function () {
// list of all static pages
Route::get('overview', 'StaticPageOverview@getOverview') Route::get('overview', 'StaticPageOverview@getOverview')
->name('staticpage.overview'); ->name('staticpage.overview');
// form for creating new static page
Route::get('new', 'CreateNewStaticPage@getNew') Route::get('new', 'CreateNewStaticPage@getNew')
->name('staticpage.new'); ->name('staticpage.new');
// form for editing existing static page
Route::get('edit/{id}', 'EditStaticPage@getEdit') Route::get('edit/{id}', 'EditStaticPage@getEdit')
->name('staticpage.edit'); ->name('staticpage.edit');
// post method for creating new static page
Route::post('new', 'CreateNewStaticPage@postNew')
->name('staticpage.newPost');
// post method for creating new static page
Route::post('edit/{id}', 'EditStaticPage@postEdit')
->name('staticpage.editPost');
// routes for quick actions
// change status of page (protected, public or draft)
Route::get('status/{id}/{status}', 'EditStaticPage@changeStatus')
->name('staticpage.changeStatus');
// delete page
Route::get('delete/{id}', 'EditStaticPage@deletePage')
->name('staticpage.delete');
// display change history of given page
// Route::get('history/{id}', 'StaticPageHistory@getHistory')->name('staticpage.history');
// Route::get('', '')->name('staticpage.');
}); });
@@ -0,0 +1,27 @@
<?php
namespace Modules\StaticPages\Listeners;
use App\Listeners\Logger;
use Modules\StaticPages\Events\CreateNewStaticPage;
class LogCreateNewStaticPage extends Logger {
/**
* Getter for action name. Used only internally
*
* @return mixed
*/
protected function getName()
{
return 'staticpages::createNew';
}
public function handle(CreateNewStaticPage $event) {
$parameters = [
'id' => $event->page->id,
'url' => $event->page->url,
'title' => $event->page->title
];
$this->saveLog($parameters);
}
}
@@ -0,0 +1,30 @@
<?php
namespace Modules\StaticPages\Listeners;
use App\Listeners\Logger;
use Modules\StaticPages\Events\DeleteStaticPage;
class LogDeleteStaticPage extends Logger
{
/**
* Getter for action name. Used only internally
*
* @return mixed
*/
protected function getName()
{
return 'staticpages::delete';
}
public function handle(DeleteStaticPage $event)
{
$parameters = [
'id' => $event->page->id,
'url' => $event->page->url,
'title' => $event->page->title,
'revision' => $event->revision
];
$this->saveLog($parameters);
}
}
@@ -0,0 +1,30 @@
<?php
namespace Modules\StaticPages\Listeners;
use App\Listeners\Logger;
use Modules\StaticPages\Events\EditStaticPage;
class LogEditStaticPage extends Logger
{
/**
* Getter for action name. Used only internally
*
* @return mixed
*/
protected function getName()
{
return 'staticpages::edit';
}
public function handle(EditStaticPage $event)
{
$parameters = [
'id' => $event->page->id,
'url' => $event->page->url,
'title' => $event->page->title,
'revision' => $event->revision
];
$this->saveLog($parameters);
}
}
@@ -0,0 +1,30 @@
<?php
namespace Modules\StaticPages\Listeners;
use App\Listeners\Logger;
use Modules\StaticPages\Events\MakeDraftFromStaticPage;
class LogMakeDraftFromStaticPage extends Logger
{
/**
* Getter for action name. Used only internally
*
* @return mixed
*/
protected function getName()
{
return 'staticpages::makeDraft';
}
public function handle(MakeDraftFromStaticPage $event)
{
$parameters = [
'id' => $event->page->id,
'url' => $event->page->url,
'title' => $event->page->title,
'revision' => $event->revision
];
$this->saveLog($parameters);
}
}
@@ -0,0 +1,30 @@
<?php
namespace Modules\StaticPages\Listeners;
use App\Listeners\Logger;
use Modules\StaticPages\Events\PublishStaticPage;
class LogPublishStaticPage extends Logger
{
/**
* Getter for action name. Used only internally
*
* @return mixed
*/
protected function getName()
{
return 'staticpages::publish';
}
public function handle(PublishStaticPage $event)
{
$parameters = [
'id' => $event->page->id,
'url' => $event->page->url,
'title' => $event->page->title,
'revision' => $event->revision
];
$this->saveLog($parameters);
}
}
@@ -0,0 +1,40 @@
<?php
namespace Modules\StaticPages\Providers;
use Illuminate\Contracts\Events\Dispatcher as DispatcherContract;
use Illuminate\Foundation\Support\Providers\EventServiceProvider as ServiceProvider;
class EventServiceProvider extends ServiceProvider
{
/**
* The event listener mappings for the application.
*
* @var array
*/
protected $listen = [
'Modules\StaticPages\Events\CreateNewStaticPage' => [
'Modules\StaticPages\Listeners\LogCreateNewStaticPage'
],
'Modules\StaticPages\Events\EditStaticPage' => [
'Modules\StaticPages\Listeners\LogEditStaticPage'
],
'Modules\StaticPages\Events\PublishStaticPage' => [
'Modules\StaticPages\Listeners\LogPublishStaticPage'
],
'Modules\StaticPages\Events\DeleteStaticPage' => [
'Modules\StaticPages\Listeners\LogDeleteStaticPage'
],
];
/**
* Register any other events for your application.
*
* @param \Illuminate\Contracts\Events\Dispatcher $events
* @return void
*/
public function boot(DispatcherContract $events)
{
parent::boot($events);
}
}
@@ -1,99 +1,129 @@
<?php namespace Modules\Staticpages\Providers; <?php namespace Modules\Staticpages\Providers;
use Illuminate\Support\Facades\Lang; use App\Enumerations\Modules;
use App\Models\ActionLogType;
use App\Models\Module;
use Illuminate\Support\ServiceProvider; use Illuminate\Support\ServiceProvider;
class StaticPagesServiceProvider extends ServiceProvider { class StaticPagesServiceProvider extends ServiceProvider
{
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
protected $defer = false;
/** /**
* Indicates if loading of the provider is deferred. * Boot the application events.
* *
* @var bool * @return void
*/ */
protected $defer = false; public function boot()
{
$this->install();
$this->registerTranslations();
$this->registerConfig();
$this->registerViews();
}
/** /**
* Boot the application events. * Register the service provider.
* *
* @return void * @return void
*/ */
public function boot() public function register()
{ {
$this->registerTranslations(); // register event provider for firing module-specific events
$this->registerConfig(); $this->app->register('Modules\StaticPages\Providers\EventServiceProvider');
$this->registerViews(); }
// register links in admin menu /**
$menu = \Menu::instance('mainMenu'); * Method for installing module into database
$menu->dropdown(trans('staticpages::adminMenu.staticPages'), function($submenu) { */
$submenu->route('staticpage.new', trans('staticpages::adminMenu.new')); protected function install()
$submenu->route('staticpage.overview', trans('staticpages::adminMenu.overview')); {
}, 15, ['icon' => 'fa fa-newspaper-o']); $handler = config('staticpages.handler');
} $installedModules = Modules::getWithTranslations();
if (!isset($installedModules[$handler])) {
/** // insert module into database
* Register the service provider. Module::create([
* 'handler' => $handler,
* @return void 'name' => 'staticpages::module.name',
*/ 'description' => 'staticpages::module.description'
public function register() ]);
{
//
}
/** // insert action log types into database
* Register config. ActionLogType::create([
* 'string_id' => 'staticpages::createNew',
* @return void 'name' => 'staticpages::log.nameCreateNew',
*/ 'value' => 'staticpages::log.nameCreateNew'
protected function registerConfig() ]);
{ ActionLogType::create([
$this->publishes([ 'string_id' => 'staticpages::edit',
__DIR__.'/../Config/config.php' => config_path('staticpages.php'), 'name' => 'staticpages::log.nameEdit',
]); 'value' => 'staticpages::log.edit'
$this->mergeConfigFrom( ]);
__DIR__.'/../Config/config.php', 'staticpages' ActionLogType::create([
); 'string_id' => 'staticpages::delete',
} 'name' => 'staticpages::log.nameDelete',
'value' => 'staticpages::log.delete'
]);
ActionLogType::create([
'string_id' => 'staticpages::makeDraft',
'name' => 'staticpages::log.nameMakeDraft',
'value' => 'staticpages::log.makeDraft'
]);
/** ActionLogType::create([
* Register views. 'string_id' => 'staticpages::publish',
* 'name' => 'staticpages::log.namePublish',
* @return void 'value' => 'staticpages::log.publish'
*/ ]);
public function registerViews() }
{ }
$viewPath = base_path('resources/views/modules/staticpages');
$sourcePath = __DIR__.'/../Resources/views'; /**
* Register config.
*
* @return void
*/
protected function registerConfig()
{
$this->publishes([
__DIR__ . '/../Config/config.php' => config_path('staticpages.php'),
]);
$this->mergeConfigFrom(__DIR__ . '/../Config/config.php', 'staticpages');
}
$this->publishes([ /**
$sourcePath => $viewPath * Register views.
]); *
* @return void
*/
public function registerViews()
{
$viewPath = base_path('resources/views/modules/staticpages');
$this->loadViewsFrom(array_merge(array_map(function ($path) { $sourcePath = __DIR__ . '/../Resources/views';
return $path . '/modules/staticpages';
}, \Config::get('view.paths')), [$sourcePath]), 'staticpages');
}
/** $this->publishes([
* Register translations. $sourcePath => $viewPath
* ]);
* @return void
*/
public function registerTranslations()
{
$this->loadTranslationsFrom(__DIR__ .'/../Resources/lang', 'staticpages');
}
/** $this->loadViewsFrom(array_merge(array_map(function ($path) {
* Get the services provided by the provider. return $path . '/modules/staticpages';
* }, \Config::get('view.paths')), [$sourcePath]), 'staticpages');
* @return array }
*/
public function provides()
{
return array();
}
/**
* Register translations.
*
* @return void
*/
public function registerTranslations()
{
$this->loadTranslationsFrom(__DIR__ . '/../Resources/lang', 'staticpages');
}
} }
@@ -1,5 +1,31 @@
<?php <?php
return [ return [
'overview' => 'List of all static pages', 'overview' => 'List of all static pages',
'new' => 'Create new static page' 'new' => 'Create new static page',
'content' => 'Page content',
'save' => 'Save new page',
'basicInfo' => 'Basic information',
'metaOptions' => 'Meta information',
'publicationOptions' => 'Publication setup',
'field_title' => 'Page title',
'field_url' => 'URL',
'field_meta_keywords' => 'Keywords',
'field_meta_description' => 'Page description',
'field_published_from' => 'Published from',
'field_published_to' => 'Published to',
'successfullyCreated' => 'Page successfully created',
'noPagesAvailable' => 'No static pages available. Try to create one first.',
'viewPage' => 'View page on web',
'edit' => 'Edit page :name',
'deletePage' => 'Delete page (ireversible!)',
'makePublic' => 'Publish page',
'makeProtected' => 'Publish page only for logged users',
'makeDraft' => 'Disable page and make it draft',
'invalidStatus' => 'Cannot change status to something undefined.',
'statusChanged' => 'Status successfully changed.',
'invalidPage' => 'Specified page does not exist.',
'pageDeleted' => 'Page :name (:url) successfully deleted.',
'nothingToEdit' => 'You did not submit any changes. Nothing was edited.',
'successfullyEdited' => 'Edit successfull'
]; ];
@@ -0,0 +1,5 @@
<?php
return [
'name' => 'Static pages',
'description' => 'Static pages are intended for displaying static content on webpage.'
];
@@ -0,0 +1,15 @@
@extends('admin.layout')
@section('pageName', @trans('staticpages::admin.edit', ['name' => $page->title]))
@section('content')
<div class="row">
<h2>@lang('staticpages::admin.edit', ['name' => $page->title])</h2>
</div>
<div class="row">
@include('staticpages::admin.editForm')
</div>
@stop
@@ -0,0 +1,162 @@
@if (session('success'))
<div data-alert class="callout success">
<strong>{{ session('success') }}</strong>
</div>
@endif
@if (session('error'))
<div data-alert class="callout alert">
<strong>{{ session('error') }}</strong>
</div>
@endif
<form method="POST" action="{{route('staticpage.editPost', ['id' => $page->id])}}">
{!! csrf_field() !!}
<ul class="tabs" data-tabs id="static-page-controls">
<li class="tabs-title is-active">
<a href="#basic-info" aria-selected="true">@lang('staticpages::admin.basicInfo')</a>
</li>
<li class="tabs-title">
<a href="#meta">@lang('staticpages::admin.metaOptions')</a>
</li>
<li class="tabs-title">
<a href="#publication">@lang('staticpages::admin.publicationOptions')</a>
</li>
</ul>
<div class="tabs-content" data-tabs-content="static-page-controls">
<div class="tabs-panel is-active" id="basic-info">
<div class="row">
<div class="columns large-6">
<label>
@lang('staticpages::admin.field_title')
<input type="text" name="title" placeholder="@lang('staticpages::admin.field_title')"
value="{{$page->title}}" />
</label>
</div>
<div class="columns large-6">
<label>
@lang('staticpages::admin.field_url')
<input type="text" name="url" placeholder="@lang('staticpages::admin.field_url')"
value="{{$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-12">
<label>
<select name="status">
@foreach($contentStatuses as $status => $translation)
<option value="{{$status}}" @if($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>
<div class="row">
<div class="columns large-12">
<label>
<textarea name="pageContent" id="pageContent" class="wysiwyg-editor">
{{$page->content}}
</textarea>
</label>
</div>
</div>
</div>
<div class="tabs-panel" id="publication">
<div class="row">
<div class="columns large-6">
<label>
@lang('staticpages::admin.field_published_from')
<input type="datetime" name="publishedFrom" value="{{$page->published_from}}"
placeholder="@lang('staticpages::admin.field_published_from')" />
@if (isset($errors) && $errors->has('published_from'))
<div class="callout alert">
{{ $errors->first('published_from') }}
</div>
@endif
</label>
</div>
<div class="columns large-6">
<label>
@lang('staticpages::admin.field_published_to')
<input type="datetime" name="publishedTo" value="{{$page->published_to}}"
placeholder="@lang('staticpages::admin.field_published_to')" />
@if (isset($errors) && $errors->has('published_to'))
<div class="callout alert">
{{ $errors->first('published_to') }}
</div>
@endif
</label>
</div>
</div>
</div>
<div class="tabs-panel" id="meta">
<div class="row">
<div class="columns large-12">
<label>
@lang('staticpages::admin.field_meta_keywords')
<input type="text" name="metaKeywords" value="{{$page->meta_keywords}}"
placeholder="@lang('staticpages::admin.field_meta_keywords')" />
</label>
</div>
</div>
<div class="row">
<div class="columns large-12">
<label>
@lang('staticpages::admin.field_meta_description')
<textarea name="metaDescription"
placeholder="@lang('staticpages::admin.field_meta_description')" rows="5">{{$page->meta_description}}</textarea>
</label>
</div>
</div>
</div>
</div>
<div class="row">
<div class="columns large-12">
<button type="submit" class="button success">@lang('staticpages::admin.edit', ['name' => $page->title])</button>
</div>
</div>
</form>
@section('head_stylesheets')
<link rel="stylesheet" href="{{asset('../resources/assets/js/vendor/trumbowyg/ui/trumbowyg.css')}}" />
@stop
@section('javascripts')
<script src="{{asset('../resources/assets/js/vendor/trumbowyg/trumbowyg.min.js')}}"></script>
<script type="application/javascript">
$('#pageContent').trumbowyg();
</script>
@stop
@@ -0,0 +1,15 @@
@extends('admin.layout')
@section('pageName', @trans('staticpages::admin.new'))
@section('content')
<div class="row">
<h2>@lang('staticpages::admin.new')</h2>
</div>
<div class="row">
@include('staticpages::admin.newForm')
</div>
@stop
@@ -0,0 +1,163 @@
@if (session('success'))
<div data-alert class="callout success">
<strong>{{ session('success') }}</strong>
</div>
@endif
@if (session('error'))
<div data-alert class="callout alert">
<strong>{{ session('error') }}</strong>
</div>
@endif
<form method="POST" action="{{route('staticpage.newPost')}}">
{!! csrf_field() !!}
<ul class="tabs" data-tabs id="static-page-controls">
<li class="tabs-title is-active">
<a href="#basic-info" aria-selected="true">@lang('staticpages::admin.basicInfo')</a>
</li>
<li class="tabs-title">
<a href="#meta">@lang('staticpages::admin.metaOptions')</a>
</li>
<li class="tabs-title">
<a href="#publication">@lang('staticpages::admin.publicationOptions')</a>
</li>
</ul>
<div class="tabs-content" data-tabs-content="static-page-controls">
<div class="tabs-panel is-active" id="basic-info">
<div class="row">
<div class="columns large-6">
<label>
@lang('staticpages::admin.field_title')
<input type="text" name="title" placeholder="@lang('staticpages::admin.field_title')"
value="{{old('title')}}" />
</label>
</div>
<div class="columns large-6">
<label>
@lang('staticpages::admin.field_url')
<input type="text" name="url" placeholder="@lang('staticpages::admin.field_url')"
value="{{old('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-12">
<label>
<select name="status">
@foreach($contentStatuses as $status => $translation)
<option value="{{$status}}" @if($selectedStatus== $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>
<div class="row">
<div class="columns large-12">
<label>
<textarea name="pageContent" id="pageContent" class="wysiwyg-editor">
{{old('pageContent')}}
</textarea>
</label>
</div>
</div>
</div>
<div class="tabs-panel" id="publication">
<div class="row">
<div class="columns large-6">
<label>
@lang('staticpages::admin.field_published_from')
<input type="datetime" name="published_from" value="{{old('published_from')}}"
placeholder="@lang('staticpages::admin.field_published_from')" />
@if (isset($errors) && $errors->has('published_from'))
<div class="callout alert">
{{ $errors->first('published_from') }}
</div>
@endif
</label>
</div>
<div class="columns large-6">
<label>
@lang('staticpages::admin.field_published_to')
<input type="datetime" name="published_to" value="{{old('published_to')}}"
placeholder="@lang('staticpages::admin.field_published_to')" />
@if (isset($errors) && $errors->has('published_to'))
<div class="callout alert">
{{ $errors->first('published_to') }}
</div>
@endif
</label>
</div>
</div>
</div>
<div class="tabs-panel" id="meta">
<div class="row">
<div class="columns large-12">
<label>
@lang('staticpages::admin.field_meta_keywords')
<input type="text" name="meta_keywords" value="{{old('meta_keywords')}}"
placeholder="@lang('staticpages::admin.field_meta_keywords')" />
</label>
</div>
</div>
<div class="row">
<div class="columns large-12">
<label>
@lang('staticpages::admin.field_meta_description')
<textarea name="meta_description"
placeholder="@lang('staticpages::admin.field_meta_description')" rows="5">{{old('meta_description')}}
</textarea>
</label>
</div>
</div>
</div>
</div>
<div class="row">
<div class="columns large-12">
<button type="submit" class="button success">@lang('staticpages::admin.save')</button>
</div>
</div>
</form>
@section('head_stylesheets')
<link rel="stylesheet" href="{{asset('../resources/assets/js/vendor/trumbowyg/ui/trumbowyg.css')}}" />
@stop
@section('javascripts')
<script src="{{asset('../resources/assets/js/vendor/trumbowyg/trumbowyg.min.js')}}"></script>
<script type="application/javascript">
$('#pageContent').trumbowyg();
</script>
@stop
@@ -3,5 +3,74 @@
@section('content') @section('content')
<div class="row"> <div class="row">
<h1>@lang('staticpages::admin.overview')</h1> <h1>@lang('staticpages::admin.overview')</h1>
@if (session('success'))
<div data-alert class="callout success">
<strong>{{ session('success') }}</strong>
</div>
@endif
@if (session('error'))
<div data-alert class="callout alert">
<strong>{{ session('error') }}</strong>
</div>
@endif
</div>
<div class="row" id="static-page-overview" data-equalizer>
@forelse($pages as $page)
<div class="columns large-3">
<div class="page callout" data-equalizer-watch>
{{--<div class="controls pull-right">--}}
{{--<button class="button tiny secondary" data-toggle="static-page-{{$page->id}}actions"><i class="fa fa-caret-down"></i></button>--}}
{{--<div class="dropdown-pane" id="static-page-{{$page->id}}actions" data-dropdown>--}}
{{----}}
{{--</div>--}}
{{--</div>--}}
<h4>{{$page->title}}</h4>
<span class="date">{{date('d.m.Y', strtotime($page->created_at))}}</span>
<span class="author">{{$page->author_name}}</span>
<p class="perex">
@if (trim($page->meta_description))
{{str_limit($page->meta_description)}}
@else
{{str_limit(strip_tags($page->content))}}
@endif
</p>
@if ($page->meta_keywords)
<p class="keywords">{{$page->meta_keywords}}</p>
@endif
<p class="controls row text-center">
{{--<a href="#" class="button tiny secondary has-tip" data-tooltip aria-haspopup="true" title="@lang('staticpages::admin.viewPage')"><i class="fa fa-desktop"></i></a>--}}
<a href="{{route('staticpage.edit', ['id' => $page->id])}}" class="button tiny success has-tip" data-tooltip aria-haspopup="true" title="@lang('staticpages::admin.edit')"><i class="fa fa-edit"></i></a>
@if($page->status == \App\Models\Content::STATUS_DRAFT)
<a href="{{route('staticpage.changeStatus', ['id' => $page->id, 'status' => \App\Models\Content::STATUS_PUBLIC])}}" class="button tiny success confirm has-tip" data-tooltip aria-haspopup="true" title="@lang('staticpages::admin.makePublic')"><i class="fa fa-eye"></i></a>
<a href="{{route('staticpage.changeStatus', ['id' => $page->id, 'status' => \App\Models\Content::STATUS_PROTECTED])}}" class="button tiny warning confirm has-tip" data-tooltip aria-haspopup="true" title="@lang('staticpages::admin.makeProtected')"><i class="fa fa-lock"></i></a>
@endif
@if(in_array($page->status, [\App\Models\Content::STATUS_PROTECTED, \App\Models\Content::STATUS_PUBLIC]))
<a href="{{route('staticpage.changeStatus', ['id' => $page->id, 'status' => \App\Models\Content::STATUS_DRAFT])}}" class="button tiny warning confirm has-tip" data-tooltip aria-haspopup="true" title="@lang('staticpages::admin.makeDraft')"><i class="fa fa-eye-slash"></i></a>
@endif
<a href="{{route('staticpage.delete', ['id' => $page->id])}}" class="button tiny alert confirm has-tip" data-tooltip aria-haspopup="true" title="@lang('staticpages::admin.deletePage')"><i class="fa fa-remove"></i></a>
</p>
</div>
</div>
@empty
<em>@lang('staticpages::admin.noPagesAvailable')</em>
@endforelse
</div>
<div class="row">
{{$pages->render()}}
</div> </div>
@stop @stop
@@ -1,11 +0,0 @@
@extends('staticpages::layouts.master')
@section('content')
<h1>Hello World</h1>
<p>
This view is loaded from module: {!! config('staticpages.name') !!}
</p>
@stop
+27
View File
@@ -34,6 +34,33 @@
list-style-type: none; list-style-type: none;
} }
#static-page-overview .page {
position: relative;
padding-bottom: 3em;
}
#static-page-overview .page .controls {
position: absolute;
bottom: 0;
}
#static-page-overview .page .controls .button {
margin-bottom: 10px;
}
#static-page-overview .date, #static-page-overview .author {
font-size: 80%;
}
#static-page-overview .perex {
}
#static-page-overview .keywords {
margin-bottom: 0;
font-size: 80%;
}
.red { .red {
color: red; color: red;
+9
View File
@@ -0,0 +1,9 @@
/* ===========================================================
* ar.js
* Arabic translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Abo Mokh ahmed (abomokhahmed)
* Github : https://github.com/abomokhahmed
*/
jQuery.trumbowyg.langs.ar={_dir:"rtl",viewHTML:"إعرض-HTML",formatting:"تصميم",p:"فقرة",blockquote:"اقتباس",code:"كود",header:"رئيسي",bold:"عريض",italic:"مائل",strikethrough:"مشطوب",underline:"خطّ سفلي",strong:"بارز",em:"تغميق",del:"حذف",unorderedList:"قائمة غير مرتّبة",orderedList:"قائمة مرتّبة",insertImage:"إدخال صورة",insertVideo:"إدخال فيديو",link:"رابط",createLink:"انشاء رابط",unlink:"حذف رابط",justifyLeft:"تصحيح للشمال",justifyCenter:"تصحيح للمركز",justifyRight:"تصحيح لليمين",justifyFull:"تصحيح لكلا الإتّجاهين",horizontalRule:"إدخال خطّ أفقي",fullscreen:"شاشة واسعة",close:"إغلاق",submit:"أرسل",reset:"تهيئة من حديد",required:"إلزامي",description:"وصف",title:"عنوان",text:"نصّ"};
+11
View File
@@ -0,0 +1,11 @@
/* ===========================================================
* ca.js
* Catalan translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Àlfons Sánchez (alsanan)
* Twitter : @alsanan
* Website : about.me/alsanan
* Github : https://github.com/alsanan
*/
jQuery.trumbowyg.langs.ca={viewHTML:"Veure HTML",formatting:"Formatar",p:"Paragraf",blockquote:"Citació",code:"Codi",header:"Títol",bold:"Negreta",italic:"Itàlica",strikethrough:"Suprimir",underline:"Subratllat",strong:"Forta",em:"Èmfasi",del:"Apagar",unorderedList:"Lista desordenada",orderedList:"Lista ordenada",insertImage:"Inserir imatge",insertVideo:"Inserir vídeo",link:"Enllaç",createLink:"Crear un enllaç",unlink:"Eliminar enllaç",justifyLeft:"Alinear a esquerra",justifyCenter:"Centrar",justifyRight:"Alinear a dreta",justifyFull:"Justificar",horizontalRule:"Inserir separador horitzontal",fullscreen:"Pantalla completa",close:"Tancar",submit:"Enviar",reset:"Reiniciar",required:"Obligatori",description:"Descripció",title:"Títol",text:"Text"};
+8
View File
@@ -0,0 +1,8 @@
/* ===========================================================
* cs.js
* Czech translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Jan Svoboda (https://github.com/svoboda-jan)
*/
jQuery.trumbowyg.langs.cs={viewHTML:"Zobrazit HTML",formatting:"Formátování",p:"Odstavec",blockquote:"Citace",code:"Kód",header:"Nadpis",bold:"Tučné",italic:"Kurzíva",strikethrough:"Přeškrtnuté",underline:"Podtržené",strong:"Tučné",em:"Zvýraznit",del:"Smazat",unorderedList:"Netříděný seznam",orderedList:"Tříděný seznam",insertImage:"Vložit obrázek",insertVideo:"Vložit video",link:"Odkaz",createLink:"Vložit odkaz",unlink:"Smazat odkaz",justifyLeft:"Zarovnat doleva",justifyCenter:"Zarovnat na střed",justifyRight:"Zarovnat doprava",justifyFull:"Zarovnat do bloku",horizontalRule:"Vložit vodorovnou čáru",fullscreen:"Režim celé obrazovky",close:"Zavřít",submit:"Potvrdit",reset:"Zrušit",required:"Povinné",description:"Popis",title:"Nadpis",text:"Text"};
+9
View File
@@ -0,0 +1,9 @@
/* ===========================================================
* da.js
* Danish translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Christian Pedersen
* Github : https://github.com/chripede
*/
jQuery.trumbowyg.langs.da={viewHTML:"Vis HTML",formatting:"Formatter",p:"Afsnit",blockquote:"Citat",code:"Kode",header:"Overskrift",bold:"Fed",italic:"Kursiv",strikethrough:"Gennemstreg",underline:"Understreg",strong:"Vigtig",em:"Fremhæv",del:"Slettet",unorderedList:"Uordnet liste",orderedList:"Ordnet liste",insertImage:"Indsæt billede",insertVideo:"Indsæt video",link:"Link",createLink:"Indsæt link",unlink:"Fjern link",justifyLeft:"Venstrestil",justifyCenter:"Centrer",justifyRight:"Højrestil",justifyFull:"Lige margener",horizontalRule:"Horisontal linie",fullscreen:"Fuld skærm",close:"Luk",submit:"Bekræft",reset:"Annuller",required:"Påkrævet",description:"Beskrivelse",title:"Titel",text:"Tekst"};
+9
View File
@@ -0,0 +1,9 @@
/* ===========================================================
* de.js
* German translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Manfred Timm
* Github : https://github.com/Manfred62
*/
jQuery.trumbowyg.langs.de={viewHTML:"HTML anzeigen",formatting:"Formatieren",p:"Absatz",blockquote:"Zitat",code:"Code",header:"Überschrift",bold:"Fett",italic:"Kursiv",strikethrough:"Durchgestrichen",underline:"Unterstrichen",strong:"Wichtig",em:"Betont",del:"Gelöscht",unorderedList:"Ungeordnete Liste",orderedList:"Geordnete Liste",insertImage:"Bild einfügen",insertVideo:"Video einfügen",link:"Link",createLink:"Link einfügen",unlink:"Link entfernen",justifyLeft:"Links ausrichten",justifyCenter:"Zentrieren",justifyRight:"Rechts ausrichten",justifyFull:"Blocksatz",horizontalRule:"Horizontale Linie einfügen",fullscreen:"Vollbild",close:"Schliessen",submit:"Bestätigen",reset:"Rücksetzen",required:"Erforderlich",description:"Beschreibung",title:"Titel",text:"Text"};
+12
View File
@@ -0,0 +1,12 @@
/* ===========================================================
* el.js
* Greek translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Merianos Nikos
* Twitter : @_webresources
* Website : http://www.wp-lion.com
* LinkedIn: https://gr.linkedin.com/in/merianosnikos
* Behance: https://www.behance.net/web_design_blog
*/
jQuery.trumbowyg.langs.es={viewHTML:"Προβολή κώδικα HTML",formatting:"Μορφοποίηση",p:"Παράγραφος",blockquote:"Παράθεση",code:"Κώδικας",header:"Επικεφαλίδα",bold:"Έντονα",italic:"Πλάγια",strikethrough:"Διαγραφή",underline:"Υπογράμμιση",strong:"Έντονα",em:"Πλάγια",del:"Διαγραφή",unorderedList:"Αταξινόμητη λίστα",orderedList:"Ταξινομημένη λίστα",insertImage:"Εισαγωγή εικόνας",insertVideo:"Εισαγωγή βίντεο",link:"Σύνδεσμος",createLink:"Δημιουργία συνδέσμου",unlink:"Διαγραφή συνδέσμου",justifyLeft:"Στοίχιση αριστερά",justifyCenter:"Στοίχιση στο κέντρο",justifyRight:"Στοίχιση δεξιά",justifyFull:"Πλήρης στοίχιση",horizontalRule:"Οριζόντια γραμμή",fullscreen:"Πλήρης οθόνη",close:"Κλείσιμο",submit:"Υποβολή",reset:"Επαναφορά",invalidUrl:"Λανθασμένο URL",required:"Απαραίτητο",description:"Περιγραφή",title:"Τίτλος",text:"Κείμενο"};
+9
View File
@@ -0,0 +1,9 @@
/* ===========================================================
* es.js
* Spanish translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Moisés Márquez
* Email : moises.marquez.g@gmail.com
*/
jQuery.trumbowyg.langs.es={viewHTML:"Ver HTML",formatting:"Formato",p:"Párrafo",blockquote:"Cita",code:"Código",header:"Título",bold:"Negrita",italic:"Cursiva",strikethrough:"Tachado",underline:"Subrayado",strong:"Negrita",em:"Énfasis",del:"Borrar",unorderedList:"Lista Desordenada",orderedList:"Lista Ordenada",insertImage:"Insertar una imagen",insertVideo:"Insertar un vídeo",link:"Enlace",createLink:"Insertar un enlace",unlink:"Suprimir un enlace",justifyLeft:"Izquierda",justifyCenter:"Centrar",justifyRight:"Derecha",justifyFull:"Justificado",horizontalRule:"Insertar separador horizontal",fullscreen:"Pantalla completa",close:"Cerrar",submit:"Enviar",reset:"Cancelar",required:"Obligatorio",description:"Descripción",title:"Título",text:"Texto"};
@@ -0,0 +1,9 @@
/* ===========================================================
* es_ar.js
* Spanish (Argentina) translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Félix Vera
* Email : felix.vera@gmail.com
*/
jQuery.trumbowyg.langs.es_ar={viewHTML:"Ver HTML",formatting:"Formato",p:"Párrafo",blockquote:"Cita",code:"Código",header:"Título",bold:"Negrita",italic:"Itálica",strikethrough:"Tachado",underline:"Subrayado",strong:"Fuere",em:"Énfasis",del:"Borrar",unorderedList:"Lista Desordenada",orderedList:"Lista Ordenada",insertImage:"Insertar una imagen",insertVideo:"Insertar un video",link:"Vínculo",createLink:"Insertar un vínculo",unlink:"Suprimir un vínculo",justifyLeft:"Alinear a la Izquierda",justifyCenter:"Centrar",justifyRight:"Alinear a la Derecha",justifyFull:"Justificado",horizontalRule:"Insertar separado Horizontal",fullscreen:"Pantalla Completa",close:"Cerrar",submit:"Enviar",reset:"Cancelar",required:"Obligatorio",description:"Descripción",title:"Título",text:"Texto"};
+10
View File
@@ -0,0 +1,10 @@
/* ===========================================================
* fa.js
* Persian translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Kiarash Soleimanzadeh
* Github : https://github.com/kiyarash
* Email : kiarash.s@hotmail.com
*/
jQuery.trumbowyg.langs.fa={viewHTML:"نمایش کد اچ تی ام ال",formatting:"قالب بندی",p:"پاراگراف",blockquote:"نقل قول",code:"کد",header:"سر تیتر",bold:"ضخیم",italic:"مورب",strikethrough:"میان خط دار",underline:"زیر خط دار",strong:"برجسته",em:"مورب",del:"حذف شده",unorderedList:"لیست نامرتب",orderedList:"لیست مرتب",insertImage:"درج تصویر",insertVideo:"درج ویدئو",link:"لینک",createLink:"درج لینک",unlink:"حذف لینک",justifyLeft:"تراز به چپ",justifyCenter:"تراز به وسط",justifyRight:"تراز به راست",justifyFull:"تراز به چپ و راست",horizontalRule:"درج خط افقی",fullscreen:"تمام صفحه",close:"بستن",submit:"تائید",reset:"انصراف",required:"اجباری",description:"توضیحات",title:"عنوان",text:"متن"};
+9
View File
@@ -0,0 +1,9 @@
/* ===========================================================
* fi.js
* Finnish translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Teppo Koivula (teppokoivula)
* Github : https://github.com/teppokoivula
*/
jQuery.trumbowyg.langs.fi={viewHTML:"Näytä HTML",formatting:"Muotoilu",p:"Kappale",blockquote:"Lainaus",code:"Koodi",header:"Otsikko",bold:"Lihavointi",italic:"Kursivointi",strikethrough:"Yliviivaus",underline:"Allevivaus",strong:"Vahvennus",em:"Painotus",del:"Poistettu",unorderedList:"Numeroimaton lista",orderedList:"Numeroitu lista",insertImage:"Lisää kuva",insertVideo:"Lisää video",link:"Linkki",createLink:"Luo linkki",unlink:"Poista linkki",justifyLeft:"Asemoi vasemmalle",justifyCenter:"Keskitä",justifyRight:"Asemoi oikealle",justifyFull:"Tasaa",horizontalRule:"Vaakaviiva",fullscreen:"Kokoruutu",close:"Sulje",submit:"Lähetä",reset:"Palauta",required:"Pakollinen",description:"Kuvaus",title:"Otsikko",text:"Teksti"};
+10
View File
@@ -0,0 +1,10 @@
/* ===========================================================
* fr.js
* French translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Alexandre Demode (Alex-D)
* Twitter : @AlexandreDemode
* Website : alex-d.fr
*/
jQuery.trumbowyg.langs.fr={viewHTML:"Voir le HTML",formatting:"Format",p:"Paragraphe",blockquote:"Citation",code:"Code",header:"Titre",bold:"Gras",italic:"Italique",strikethrough:"Rayé",underline:"Souligné",strong:"Fort",em:"Emphase",del:"Supprimé",unorderedList:"Liste à puces",orderedList:"Liste ordonnée",insertImage:"Insérer une image",insertVideo:"Insérer une video",link:"Lien",createLink:"Insérer un lien",unlink:"Supprimer le lien",justifyLeft:"Aligner à gauche",justifyCenter:"Centrer",justifyRight:"Aligner à droite",justifyFull:"Justifier",horizontalRule:"Insérer un séparateur horizontal",fullscreen:"Plein écran",close:"Fermer",submit:"Valider",reset:"Annuler",required:"Obligatoire",description:"Description",title:"Titre",text:"Texte"};
+9
View File
@@ -0,0 +1,9 @@
/* ===========================================================
* he.js
* Hebrew translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Udi Doron (udidoron)
* Github : https://github.com/udidoron
*/
jQuery.trumbowyg.langs.he={_dir:"rtl",viewHTML:"צפה ב-HTML",formatting:"פורמט",p:"פסקה",blockquote:"ציטוט",code:"קוד",header:"ראשית",bold:"מודגש",italic:"נטוי",strikethrough:"קו חוצה",underline:"קו תחתון",strong:"בולט",em:"הדגשה",del:"נמחק",unorderedList:"רשימה ללא סדר",orderedList:"רשימה מסודרת",insertImage:"הכנס תמונה",insertVideo:"הכנס סרטון",link:"קישור",createLink:"צור קישור",unlink:"הסר קישור",justifyLeft:"ישר לשמאל",justifyCenter:"מרכז",justifyRight:"ישר לימין",justifyFull:"ישר לשני הצדדים",horizontalRule:"הכנס קו אופקי",fullscreen:"מסך מלא",close:"סגור",submit:"שלח",reset:"אתחל מחדש",required:"נחוץ",description:"תיאור",title:"כותרת",text:"טקסט"};
+10
View File
@@ -0,0 +1,10 @@
/* ===========================================================
* hu.js
* Hungarian translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Peter MATO
* Web: http://fixme.hu
* GitHub: https://github.com/matopeter
*/
jQuery.trumbowyg.langs.hu={viewHTML:"HTML nézet",formatting:"Stílusok",p:"Bekezdés",blockquote:"Idézet",code:"Kód",header:"Címsor",bold:"Félkövér",italic:"Dőlt",strikethrough:"Áthúzott",underline:"Aláhúzott",strong:"Vastag",em:"Kiemelt",del:"Törölt",unorderedList:"Felsorolás",orderedList:"Számozás",insertImage:"Kép beszúrása",insertVideo:"Video beszúrása",link:"Link",createLink:"Link létrehozása",unlink:"Link eltávolítása",justifyLeft:"Balra igazítás",justifyCenter:"Középre igazítás",justifyRight:"Jobbra igazítás",justifyFull:"Sorkizárt",horizontalRule:"Vízszintes vonal",fullscreen:"Teljes képernyő",close:"Bezár",submit:"Beküldés",reset:"Alaphelyzet",required:"Kötelező",description:"Leírás",title:"Cím",text:"Szöveg",removeformat:"Formázás eltávolítása"};
+11
View File
@@ -0,0 +1,11 @@
/* ===========================================================
* id.js
* Indonesian translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Rezha Julio (kimiamania)
* Twitter : @kimiamania
* Website : http://rezhajulio.web.id
* Github : https://github.com/kimiamania
*/
jQuery.trumbowyg.langs.id={viewHTML:"Lihat HTML",formatting:"Penyusunan",p:"Paragraf",blockquote:"Kutipan",code:"Kode",header:"Kepala",bold:"Tebal",italic:"Miring",strikethrough:"Coret",underline:"Garis bawah",strong:"Tebal",em:"Miring",del:"Dicoret",unorderedList:"Daftar tak teratur",orderedList:"Daftar teratur",insertImage:"Sisipkan gambar",insertVideo:"Sisipkan video",link:"Tautan",createLink:"Sisipkan Tautan",unlink:"Singkirkan tautan",justifyLeft:"Rata kiri",justifyCenter:"Rata Tengah",justifyRight:"Rata kanan",justifyFull:"Rata kiri dan kanan",horizontalRule:"Sisipkan garis mendatar",fullscreen:"Layar penuh",close:"Tutup",submit:"Setuju",reset:"Batal",required:"Diperlukan",description:"Deskripsi",title:"Judul",text:"Teks"};
+8
View File
@@ -0,0 +1,8 @@
/* ===========================================================
* it.js
* Italian translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Mirko Buffoni
*/
jQuery.trumbowyg.langs.it={viewHTML:"Mostra HTML",formatting:"Formattazione",p:"Paragrafo",blockquote:"Citazione",code:"Codice",header:"Intestazione",bold:"Grassetto",italic:"Italico",strikethrough:"Barrato",underline:"Sottolineato",strong:"Rafforza",em:"Enfatizza",del:"Cancella",unorderedList:"Elenco puntato",orderedList:"Elenco numerato",insertImage:"Inserisci immagine",insertVideo:"Inserisci video",link:"Collegamento",createLink:"Crea un collegamento",unlink:"Elimina collegamento",justifyLeft:"Allinea a sinistra",justifyCenter:"Centra",justifyRight:"Allinea a destra",justifyFull:"Giustifica",horizontalRule:"Inserisci un separatore orizzontale",fullscreen:"Schermo intero",close:"Chiudi",submit:"Invia",reset:"Annulla",required:"Obbligatorio",description:"Descrizione",title:"Titolo",text:"Testo"};
+10
View File
@@ -0,0 +1,10 @@
/* ===========================================================
* ja.js
* Japanese translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Kouta Fukuhara (foo9)
* Twitter : @foo9
* Website : https://github.com/foo9
*/
jQuery.trumbowyg.langs.ja={viewHTML:"HTML表示",formatting:"フォーマット",p:"段落",blockquote:"引用",code:"コード",header:"見出し",bold:"太字",italic:"斜体",strikethrough:"取り消し線",underline:"下線",strong:"太字",em:"斜体",del:"取り消し線",unorderedList:"順序なしリスト",orderedList:"順序ありリスト",insertImage:"画像の挿入",insertVideo:"動画の挿入",link:"リンク",createLink:"リンクの作成",unlink:"リンクの削除",justifyLeft:"左揃え",justifyCenter:"中央揃え",justifyRight:"右揃え",justifyFull:"両端揃え",horizontalRule:"横罫線",fullscreen:"全画面表示",close:"閉じる",submit:"送信",reset:"キャンセル",required:"必須",description:"説明",title:"タイトル",text:"テキスト"};
+10
View File
@@ -0,0 +1,10 @@
/* ===========================================================
* ko.js
* Korean translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : JoongSeob Vito Kim (dorajistyle)
* Blog : http://dorajistyle.pe.kr
* Github : https://github.com/dorajistyle
*/
jQuery.trumbowyg.langs.ko={viewHTML:"HTML로 보기",formatting:"양식",p:"문단",blockquote:"인용부호",code:"코드",header:"머릿말",bold:"진하게",italic:"기울임",strikethrough:"취소선",underline:"밑줄",strong:"굵게",em:"강조",del:"취소",unorderedList:"순차 목록",orderedList:"비순차 목록",insertImage:"이미지 넣기",insertVideo:"비디오 넣기",link:"링크",createLink:"링크 넣기",unlink:"링크 없애기",justifyLeft:"왼쪽 정렬",justifyCenter:"가운데 정렬",justifyRight:"오른쪽 정렬",justifyFull:"혼합 정렬",horizontalRule:"가로줄 넣기",fullscreen:"전체 화면",close:"닫기",submit:"전송",reset:"초기화",required:"꼭 입력해야 합니다.",description:"설명",title:"제목",text:"본문 내용"};
+8
View File
@@ -0,0 +1,8 @@
/* ===========================================================
* my.js
* Malaysian translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : JohnPozy
*/
jQuery.trumbowyg.langs.id={viewHTML:"Lihat HTML",formatting:"Pemformatan",p:"Perenggan",blockquote:"Blockquote",code:"Kod",header:"Pengepala",bold:"Tebal",italic:"Condong",strikethrough:"Garis batal",underline:"Garis bawah",strong:"Kuat",em:"Condong",del:"Hapus",unorderedList:"Senarai tidak tertib",orderedList:"Senarai tertib",insertImage:"Masukkan imej",insertVideo:"Masukkan video",link:"Pautan",createLink:"Cipta pautan",unlink:"Hapus pautan",justifyLeft:"Mengimbangkan ke kiri",justifyCenter:"Mengimbangkan ke tengah",justifyRight:"Mengimbangkan ke kanan",justifyFull:"Mengimbangkan ke kiri dan kanan",horizontalRule:"Masukkan garis mendatar",fullscreen:"Skrin penuh",close:"Tutup",submit:"Hantar",reset:"Batal",required:"Diperlukan",description:"Perihal",title:"Tajuk",text:"Teks"};
+9
View File
@@ -0,0 +1,9 @@
/* ===========================================================
* nl.js
* Dutch translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Danny Hiemstra
* Github : https://github.com/dhiemstra
*/
jQuery.trumbowyg.langs.nl={viewHTML:"HTML bekijken",formatting:"Opmaak",p:"Paragraaf",blockquote:"Citaat",code:"Code",header:"Kop",bold:"Vet",italic:"Cursief",strikethrough:"Doorhalen",underline:"Onderlijnen",strong:"Sterk",em:"Nadruk",del:"Verwijderd",unorderedList:"Ongenummerde lijst",orderedList:"Genummerde lijst",insertImage:"Afbeelding invoegen",insertVideo:"Video invoegen",link:"Link",createLink:"Link maken",unlink:"Link verwijderen",justifyLeft:"Links uitlijnen",justifyCenter:"Centreren",justifyRight:"Rechts uitlijnen",justifyFull:"Uitvullen",horizontalRule:"Horizontale lijn",removeFormat:"Opmaak verwijderen",fullscreen:"Volledig scherm",close:"Sluiten",submit:"Verzenden",reset:"Herstellen",required:"Verplicht",description:"Omschrijving",title:"Titel",text:"Tekst"};
+9
View File
@@ -0,0 +1,9 @@
/* ===========================================================
* pl.js
* Polish translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Paweł Abramowicz
* Github : https://github.com/pawelabrams
*/
jQuery.trumbowyg.langs.pl={viewHTML:"Pokaż HTML",formatting:"Format",p:"Akapit",blockquote:"Cytat",code:"Kod",header:"Nagłówek",bold:"Pogrubienie",italic:"Pochylenie",strikethrough:"Przekreślenie",underline:"Podkreślenie",strong:"Wytłuszczenie",em:"Uwydatnienie",del:"Usunięte",unorderedList:"Lista nieuporządkowana",orderedList:"Lista uporządkowana",insertImage:"Wstaw obraz",insertVideo:"Wstaw film",link:"Link",createLink:"Wstaw link",unlink:"Usuń link",justifyLeft:"Wyrównaj do lewej",justifyCenter:"Wyśrodkuj",justifyRight:"Wyrównaj do prawej",justifyFull:"Wyjustuj",horizontalRule:"Odkreśl linią",fullscreen:"Pełny ekran",close:"Zamknij",submit:"Zastosuj",reset:"Przywróć",required:"Wymagane",description:"Opis",title:"Tytuł",text:"Tekst"};
+11
View File
@@ -0,0 +1,11 @@
/* ===========================================================
* pt.js
* Portuguese translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Ramiro Varandas Jr (ramirovjr)
* Twitter : @ramirovjnr
* Website : about.me/ramirovjnr
* Github : https://github.com/ramirovjr
*/
jQuery.trumbowyg.langs.pt={viewHTML:"Ver HTML",formatting:"Formatar",p:"Paragráfo",blockquote:"Citação",code:"Código",header:"Título",bold:"Negrito",italic:"Itálico",strikethrough:"Suprimir",underline:"Sublinhado",strong:"Forte",em:"Ênfase",del:"Apagar",unorderedList:"Lista não ordenada",orderedList:"Liste ordenada",insertImage:"Inserir imagem",insertVideo:"Inserir vídeo",link:"Link",createLink:"Criar um link",unlink:"Remover link",justifyLeft:"Alinhar a esquerda",justifyCenter:"Centralizar",justifyRight:"Alinhar a direita",justifyFull:"Justificar",horizontalRule:"Inserir separador horizontal",fullscreen:"Tela cheia",close:"Fechar",submit:"Enviar",reset:"Limpar",required:"Obrigatório",description:"Descrição",title:"Título",text:"Texto"};
+12
View File
@@ -0,0 +1,12 @@
/* ===========================================================
* ro.js
* Romanian translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Vladut Radulescu (pacMakaveli)
* Email: pacMakaveli90@gmail.com
* Twitter : @pacMakaveli90
* Website : creative-studio51.co.uk
* Github : https://github.com/pacMakaveli
*/
jQuery.trumbowyg.langs.pt={viewHTML:"Vizualizare HTML",formatting:"Format",p:"Paragraf",blockquote:"Citație",code:"Cod",header:"Titlu",bold:"Bold",italic:"Italic",strikethrough:"Tăiat",underline:"Subliniat",strong:"Puternic",em:"Accentuat",del:"Sterge",unorderedList:"Lista dezordonată",orderedList:"Liste ordonată",insertImage:"Adăugare Imagine",insertVideo:"Adăugare Video",link:"Link",createLink:"Crează link",unlink:"Remover link",justifyLeft:"Aliniază stânga",justifyCenter:"Aliniază centru",justifyRight:"Aliniază dreapta",justifyFull:"Justificare",horizontalRule:"Linie orizontală",fullscreen:"Tot ecranul",close:"Închide",submit:"Procesează",reset:"Resetează",required:"Obligatoriu",description:"Descriere",title:"Titlu",text:"Text"};
+8
View File
@@ -0,0 +1,8 @@
/* ===========================================================
* rs.js
* Serbian (Cyrlic) translation for Trumbowyg
* https://www.github.com/johonunu
* ===========================================================
* Author : Nikola Trifunovic (https://www.github.com/johonunu)
*/
jQuery.trumbowyg.langs.rs={viewHTML:"Погледај HTML кóд",formatting:"Форматирање",p:"Параграф",blockquote:"Цитат",code:"Кóд",header:"Наслов",bold:"Подебљано",italic:"Курзив",strikethrough:"Прецртано",underline:"Подвучено",strong:"Подебљано",em:"Истакнуто",del:"Обрисано",unorderedList:"Ненабројива листа",orderedList:"Набројива листа",insertImage:"Унеси слику",insertVideo:"Унеси видео",link:"Линк",createLink:"Унеси линк",unlink:"Уклони линк",justifyLeft:"Лево равнање",justifyCenter:"Централно равнање",justifyRight:"Десно равнање",justifyFull:"Обострано равнање",horizontalRule:"Хоризонтална линија",fullscreen:"Режим читавог екрана",close:"Затвори",submit:"Унеси",reset:"Откажи",required:"Обавезно поље",invalidUrl:"URL",description:"Опис",title:"Наслов",text:"Текст"};
@@ -0,0 +1,8 @@
/* ===========================================================
* rs_latin.js
* Serbian (Latin) translation for Trumbowyg
* https://www.github.com/johonunu
* ===========================================================
* Author : Nikola Trifunovic (https://www.github.com/johonunu)
*/
jQuery.trumbowyg.langs.rs_latin={viewHTML:"Poglеdaj HTML kód",formatting:"Formatiranjе",p:"Paragraf",blockquote:"Citat",code:"Kód",header:"Naslov",bold:"Podеbljano",italic:"Kurziv",strikethrough:"Prеcrtano",underline:"Podvučеno",strong:"Podеbljano",em:"Istaknuto",del:"Obrisano",unorderedList:"Nеnabrojiva lista",orderedList:"Nabrojiva lista",insertImage:"Unеsi sliku",insertVideo:"Unеsi vidеo",link:"Link",createLink:"Unеsi link",unlink:"Ukloni link",justifyLeft:"Lеvo ravnanjе",justifyCenter:"Cеntralno ravnanjе",justifyRight:"Dеsno ravnanjе",justifyFull:"Obostrano ravnanjе",horizontalRule:"Horizontalna linija",fullscreen:"Rеžim čitavog еkrana",close:"Zatvori",submit:"Unеsi",reset:"Otkaži",required:"Obavеzno poljе",invalidUrl:"URL",description:"Opis",title:"Naslov",text:"Tеkst"};
+8
View File
@@ -0,0 +1,8 @@
/* ===========================================================
* ru.js
* Russion translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Yuri Lya
*/
jQuery.trumbowyg.langs.ru={viewHTML:"Посмотреть HTML",formatting:"Форматирование",p:"Обычный",blockquote:"Цитата",code:"Код",header:"Заголовок",bold:"Полужирный",italic:"Курсив",strikethrough:"Зачеркнутый",underline:"Подчеркнутый",strong:"Полужирный",em:"Курсив",del:"Зачеркнутый",unorderedList:"Обычный список",orderedList:"Нумерованный список",insertImage:"Вставить изображение",insertVideo:"Вставить видео",link:"Ссылка",createLink:"Вставить ссылку",unlink:"Удалить ссылку",justifyLeft:"По левому краю",justifyCenter:"По центру",justifyRight:"По правому краю",justifyFull:"По ширине",horizontalRule:"Горизонтальная линия",fullscreen:"Во весь экран",close:"Закрыть",submit:"Вставить",reset:"Отменить",required:"Обязательное",description:"Описание",title:"Подсказка",text:"Текст"};
+8
View File
@@ -0,0 +1,8 @@
/* ===========================================================
* sk.js
* Slovak translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : VeeeneX (https://github.com/VeeeneX)
*/
jQuery.trumbowyg.langs.sk={viewHTML:"Zobraziť HTML",formatting:"Formátovanie",p:"Paragraf",blockquote:"Citácia",code:"Kód",header:"Nadpis",bold:"Tučné",italic:"Kurzíva",strikethrough:"Preškrtnuté",underline:"Podčiarknuté",strong:"Tučné",em:"Zvýrazniť",del:"Zmazať",unorderedList:"Netriedený zoznam",orderedList:"Triedený zoznam",insertImage:"Vložiť obrázok",insertVideo:"Vložiť video",link:"Odkaz",createLink:"Vložiť odkaz",unlink:"Zmazať odkaz",justifyLeft:"Zarovnať doľava",justifyCenter:"Zarovnať na stred",justifyRight:"Zarovnať doprava",justifyFull:"Zarovnať do bloku",horizontalRule:"Vložit vodorovnú čiaru",fullscreen:"Režim celej obrazovky",close:"Zavrieť",submit:"Potvrdiť",reset:"Zrušiť",required:"Povinné",description:"Popis",title:"Nadpis",text:"Text"};
+9
View File
@@ -0,0 +1,9 @@
/* ===========================================================
* sv.js
* Swedish translation for Trumbowyg
* http://www.tim-international.net
* ===========================================================
* Author : T. Almroth
* Github : https://github.com/timint
*/
jQuery.trumbowyg.langs.sv={viewHTML:"Visa HTML",formatting:"Formatera",p:"Avsnitt",blockquote:"Citat",code:"Kod",header:"Överskrift",bold:"Fet",italic:"Kursiv",strikethrough:"Genomstruken",underline:"Understreck",strong:"Viktig",em:"Framhäv",del:"Rensa formatering",unorderedList:"Lista",orderedList:"Numrerad lista",insertImage:"Infoga bild",insertVideo:"Infoga video",link:"Länk",createLink:"Infoga länk",unlink:"Ta bort länk",justifyLeft:"Vänsterjustera",justifyCenter:"Centrera",justifyRight:"Högerjustera",justifyFull:"Marginaljustera",horizontalRule:"Horisontell linje",fullscreen:"Fullskärm",close:"Stäng",submit:"Bekräfta",reset:"Återställ",required:"Obligatorisk",description:"Beskrivning",title:"Titel",text:"Text"};
+9
View File
@@ -0,0 +1,9 @@
/* ===========================================================
* tr.js
* Turkish translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Emrah Bilbay (munzur)
* Github : https://github.com/munzur
*/
jQuery.trumbowyg.langs.tr={viewHTML:"HTML Kodu",formatting:"Biçimlendirme",p:"Paragraf",blockquote:"Alıntı",code:"Kod",header:"Başlık",bold:"Kalın",italic:"İtalik",strikethrough:"Üzeri çizgili",underline:"Altı çizgili",strong:"Koyu",em:"Vurgulu",del:"Üzeri çizgili",unorderedList:"Simgeli liste",orderedList:"Numaralı liste",insertImage:"Resim yerleştir",insertVideo:"Video yerleştir",link:"Link",createLink:"Link yerleştir",unlink:"Linki sil",justifyLeft:"Sola hizala",justifyCenter:"Ortaya hizala",justifyRight:"Sağa hizala",justifyFull:"Yasla",horizontalRule:"Yatay satır ekle",fullscreen:"Tam ekran",close:"Kapat",submit:"Onayla",reset:"Sıfırla",required:"Gerekli",description:"Açıklama",title:"Başlık",text:"Metin"};
+8
View File
@@ -0,0 +1,8 @@
/* ===========================================================
* ua.js
* Ukrainian translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : Igor Buksha
*/
jQuery.trumbowyg.langs.ua={viewHTML:"Подивитись HTML",formatting:"Форматування",p:"Звичайний",blockquote:"Витяг",code:"Код",header:"Заголовок",bold:"Напівжирний",italic:"Курсив",strikethrough:"Закреслений",underline:"Підкреслений",strong:"Напівжирний",em:"Курсив",del:"Закреслений",unorderedList:"Звичайний список",orderedList:"Нумерований список",insertImage:"Вставити зображення",insertVideo:"Вставити відео",link:"Посилання",createLink:"Вставити посилання",unlink:"Видалити посилання",justifyLeft:"По лівому краю",justifyCenter:"В центрі",justifyRight:"По правому краю",justifyFull:"По ширині",horizontalRule:"Горизонтальна лінія",fullscreen:"На весь екран",close:"Закрити",submit:"Вставити",reset:"Скасувати",required:"Обов'язкове",description:"Опис",title:"Підказка",text:"Текст"};
+9
View File
@@ -0,0 +1,9 @@
/* ===========================================================
* vi.js
* Vietnamese translation for Trumbowyg
* http://alex-d.github.com/Trumbowyg
* ===========================================================
* Author : heocoi
* Github: https://github.com/heocoi
*/
jQuery.trumbowyg.langs.vi={viewHTML:"Hiển thị HTML",formatting:"Định dạng",p:"Đoạn",blockquote:"Trích dẫn",code:"Code",header:"Đầu trang",bold:"In đậm",italic:"In nghiêng",strikethrough:"Gạch ngang",underline:"Gạch chân",strong:"In đậm",em:"In nghiêng",del:"Gạch ngang",unorderedList:"Danh sách không thứ tự",orderedList:"Danh sách có thứ tự",insertImage:"Chèn hình ảnh",insertVideo:"Chèn video",link:"Đường dẫn",createLink:"Tạo đường dẫn",unlink:"Hủy đường dẫn",justifyLeft:"Canh lề trái",justifyCenter:"Canh giữa",justifyRight:"Canh lề phải",justifyFull:"Canh đều",horizontalRule:"Thêm đường kẻ ngang",fullscreen:"Toàn màn hình",close:"Đóng",submit:"Đồng ý",reset:"Hủy bỏ",required:"Bắt buộc",description:"Mô tả",title:"Tiêu đề",text:"Nội dung"};

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