mirror of
https://github.com/BookStackApp/BookStack.git
synced 2025-02-22 00:21:11 +08:00
Merge branch 'laravel_upgrade'
This commit is contained in:
commit
c9c4dbcb5b
4
.github/workflows/phpunit.yml
vendored
4
.github/workflows/phpunit.yml
vendored
@ -13,12 +13,12 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
php: ['7.3', '7.4', '8.0']
|
||||
php: ['7.3', '7.4', '8.0', '8.1']
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@b7d1d9c9a92d8d8463ce36d7f60da34d461724f8
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
extensions: gd, mbstring, json, curl, xml, mysql, ldap
|
||||
|
4
.github/workflows/test-migrations.yml
vendored
4
.github/workflows/test-migrations.yml
vendored
@ -13,12 +13,12 @@ jobs:
|
||||
runs-on: ubuntu-20.04
|
||||
strategy:
|
||||
matrix:
|
||||
php: ['7.3', '7.4', '8.0']
|
||||
php: ['7.3', '7.4', '8.0', '8.1']
|
||||
steps:
|
||||
- uses: actions/checkout@v1
|
||||
|
||||
- name: Setup PHP
|
||||
uses: shivammathur/setup-php@b7d1d9c9a92d8d8463ce36d7f60da34d461724f8
|
||||
uses: shivammathur/setup-php@v2
|
||||
with:
|
||||
php-version: ${{ matrix.php }}
|
||||
extensions: gd, mbstring, json, curl, xml, mysql, ldap
|
||||
|
@ -61,7 +61,7 @@ class Activity extends Model
|
||||
/**
|
||||
* Checks if another Activity matches the general information of another.
|
||||
*/
|
||||
public function isSimilarTo(Activity $activityB): bool
|
||||
public function isSimilarTo(self $activityB): bool
|
||||
{
|
||||
return [$this->type, $this->entity_type, $this->entity_id] === [$activityB->type, $activityB->entity_type, $activityB->entity_id];
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ namespace BookStack\Actions;
|
||||
|
||||
use BookStack\Model;
|
||||
use BookStack\Traits\HasCreatorAndUpdater;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
|
||||
/**
|
||||
@ -15,6 +16,7 @@ use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
*/
|
||||
class Comment extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasCreatorAndUpdater;
|
||||
|
||||
protected $fillable = ['text', 'parent_id'];
|
||||
|
@ -3,10 +3,13 @@
|
||||
namespace BookStack\Actions;
|
||||
|
||||
use BookStack\Model;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphTo;
|
||||
|
||||
class Tag extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = ['name', 'value', 'order'];
|
||||
protected $hidden = ['id', 'entity_id', 'entity_type', 'created_at', 'updated_at'];
|
||||
|
||||
|
@ -43,7 +43,7 @@ class ApiToken extends Model implements Loggable
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function logDescriptor(): string
|
||||
{
|
||||
|
@ -42,7 +42,7 @@ class ApiTokenGuard implements Guard
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function user()
|
||||
{
|
||||
@ -152,7 +152,7 @@ class ApiTokenGuard implements Guard
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function validate(array $credentials = [])
|
||||
{
|
||||
|
@ -7,6 +7,7 @@ use BookStack\Auth\Permissions\RolePermission;
|
||||
use BookStack\Interfaces\Loggable;
|
||||
use BookStack\Model;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
|
||||
@ -23,6 +24,8 @@ use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
*/
|
||||
class Role extends Model implements Loggable
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $fillable = ['display_name', 'description', 'external_auth_id'];
|
||||
|
||||
/**
|
||||
@ -83,7 +86,7 @@ class Role extends Model implements Loggable
|
||||
/**
|
||||
* Get the role of the specified display name.
|
||||
*/
|
||||
public static function getRole(string $displayName): ?Role
|
||||
public static function getRole(string $displayName): ?self
|
||||
{
|
||||
return static::query()->where('display_name', '=', $displayName)->first();
|
||||
}
|
||||
@ -91,7 +94,7 @@ class Role extends Model implements Loggable
|
||||
/**
|
||||
* Get the role object for the specified system role.
|
||||
*/
|
||||
public static function getSystemRole(string $systemName): ?Role
|
||||
public static function getSystemRole(string $systemName): ?self
|
||||
{
|
||||
return static::query()->where('system_name', '=', $systemName)->first();
|
||||
}
|
||||
@ -116,7 +119,7 @@ class Role extends Model implements Loggable
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function logDescriptor(): string
|
||||
{
|
||||
|
@ -21,7 +21,7 @@ class SocialAccount extends Model implements Loggable
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function logDescriptor(): string
|
||||
{
|
||||
|
@ -18,6 +18,7 @@ use Illuminate\Auth\Passwords\CanResetPassword;
|
||||
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
|
||||
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
@ -43,6 +44,7 @@ use Illuminate\Support\Collection;
|
||||
*/
|
||||
class User extends Model implements AuthenticatableContract, CanResetPasswordContract, Loggable, Sluggable
|
||||
{
|
||||
use HasFactory;
|
||||
use Authenticatable;
|
||||
use CanResetPassword;
|
||||
use Notifiable;
|
||||
@ -90,7 +92,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
||||
/**
|
||||
* Returns the default public user.
|
||||
*/
|
||||
public static function getDefault(): User
|
||||
public static function getDefault(): self
|
||||
{
|
||||
if (!is_null(static::$defaultUser)) {
|
||||
return static::$defaultUser;
|
||||
@ -336,7 +338,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function logDescriptor(): string
|
||||
{
|
||||
@ -344,7 +346,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritDoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function refreshSlug(): string
|
||||
{
|
||||
|
11
app/Config/app.php
Executable file → Normal file
11
app/Config/app.php
Executable file → Normal file
@ -143,7 +143,6 @@ return [
|
||||
|
||||
// Class aliases, Registered on application start
|
||||
'aliases' => [
|
||||
|
||||
// Laravel
|
||||
'App' => Illuminate\Support\Facades\App::class,
|
||||
'Arr' => Illuminate\Support\Arr::class,
|
||||
@ -155,21 +154,23 @@ return [
|
||||
'Config' => Illuminate\Support\Facades\Config::class,
|
||||
'Cookie' => Illuminate\Support\Facades\Cookie::class,
|
||||
'Crypt' => Illuminate\Support\Facades\Crypt::class,
|
||||
'Date' => Illuminate\Support\Facades\Date::class,
|
||||
'DB' => Illuminate\Support\Facades\DB::class,
|
||||
'Eloquent' => Illuminate\Database\Eloquent\Model::class,
|
||||
'Event' => Illuminate\Support\Facades\Event::class,
|
||||
'File' => Illuminate\Support\Facades\File::class,
|
||||
'Gate' => Illuminate\Support\Facades\Gate::class,
|
||||
'Hash' => Illuminate\Support\Facades\Hash::class,
|
||||
'Input' => Illuminate\Support\Facades\Input::class,
|
||||
'Inspiring' => Illuminate\Foundation\Inspiring::class,
|
||||
'Http' => Illuminate\Support\Facades\Http::class,
|
||||
'Lang' => Illuminate\Support\Facades\Lang::class,
|
||||
'Log' => Illuminate\Support\Facades\Log::class,
|
||||
'Mail' => Illuminate\Support\Facades\Mail::class,
|
||||
'Notification' => Illuminate\Support\Facades\Notification::class,
|
||||
'Password' => Illuminate\Support\Facades\Password::class,
|
||||
'Queue' => Illuminate\Support\Facades\Queue::class,
|
||||
'RateLimiter' => Illuminate\Support\Facades\RateLimiter::class,
|
||||
'Redirect' => Illuminate\Support\Facades\Redirect::class,
|
||||
'Redis' => Illuminate\Support\Facades\Redis::class,
|
||||
// 'Redis' => Illuminate\Support\Facades\Redis::class,
|
||||
'Request' => Illuminate\Support\Facades\Request::class,
|
||||
'Response' => Illuminate\Support\Facades\Response::class,
|
||||
'Route' => Illuminate\Support\Facades\Route::class,
|
||||
@ -180,6 +181,8 @@ return [
|
||||
'URL' => Illuminate\Support\Facades\URL::class,
|
||||
'Validator' => Illuminate\Support\Facades\Validator::class,
|
||||
'View' => Illuminate\Support\Facades\View::class,
|
||||
|
||||
// Laravel Packages
|
||||
'Socialite' => Laravel\Socialite\Facades\Socialite::class,
|
||||
|
||||
// Third Party
|
||||
|
@ -10,7 +10,6 @@
|
||||
|
||||
return [
|
||||
|
||||
// Method of authentication to use
|
||||
// Options: standard, ldap, saml2, oidc
|
||||
'method' => env('AUTH_METHOD', 'standard'),
|
||||
|
||||
@ -45,7 +44,7 @@ return [
|
||||
'provider' => 'external',
|
||||
],
|
||||
'api' => [
|
||||
'driver' => 'api-token',
|
||||
'driver' => 'api-token',
|
||||
],
|
||||
],
|
||||
|
||||
@ -58,10 +57,16 @@ return [
|
||||
'driver' => 'eloquent',
|
||||
'model' => \BookStack\Auth\User::class,
|
||||
],
|
||||
|
||||
'external' => [
|
||||
'driver' => 'external-users',
|
||||
'model' => \BookStack\Auth\User::class,
|
||||
],
|
||||
|
||||
// 'users' => [
|
||||
// 'driver' => 'database',
|
||||
// 'table' => 'users',
|
||||
// ],
|
||||
],
|
||||
|
||||
// Resetting Passwords
|
||||
@ -78,4 +83,10 @@ return [
|
||||
],
|
||||
],
|
||||
|
||||
// Password Confirmation Timeout
|
||||
// Here you may define the amount of seconds before a password confirmation
|
||||
// times out and the user is prompted to re-enter their password via the
|
||||
// confirmation screen. By default, the timeout lasts for three hours.
|
||||
'password_timeout' => 10800,
|
||||
|
||||
];
|
||||
|
@ -1,51 +1,79 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Broadcasting configuration options.
|
||||
* Caching configuration options.
|
||||
*
|
||||
* Changes to these config files are not supported by BookStack and may break upon updates.
|
||||
* Configuration should be altered via the `.env` file or environment variables.
|
||||
* Do not edit this file unless you're happy to maintain any changes yourself.
|
||||
*/
|
||||
|
||||
// MEMCACHED - Split out configuration into an array
|
||||
if (env('CACHE_DRIVER') === 'memcached') {
|
||||
$memcachedServerKeys = ['host', 'port', 'weight'];
|
||||
$memcachedServers = explode(',', trim(env('MEMCACHED_SERVERS', '127.0.0.1:11211:100'), ','));
|
||||
foreach ($memcachedServers as $index => $memcachedServer) {
|
||||
$memcachedServerDetails = explode(':', $memcachedServer);
|
||||
if (count($memcachedServerDetails) < 2) {
|
||||
$memcachedServerDetails[] = '11211';
|
||||
}
|
||||
if (count($memcachedServerDetails) < 3) {
|
||||
$memcachedServerDetails[] = '100';
|
||||
}
|
||||
$memcachedServers[$index] = array_combine($memcachedServerKeys, $memcachedServerDetails);
|
||||
}
|
||||
}
|
||||
|
||||
return [
|
||||
|
||||
// Default Broadcaster
|
||||
// This option controls the default broadcaster that will be used by the
|
||||
// framework when an event needs to be broadcast. This can be set to
|
||||
// any of the connections defined in the "connections" array below.
|
||||
'default' => env('BROADCAST_DRIVER', 'pusher'),
|
||||
// Default cache store to use
|
||||
// Can be overridden at cache call-time
|
||||
'default' => env('CACHE_DRIVER', 'file'),
|
||||
|
||||
// Broadcast Connections
|
||||
// Here you may define all of the broadcast connections that will be used
|
||||
// to broadcast events to other systems or over websockets. Samples of
|
||||
// each available type of connection are provided inside this array.
|
||||
'connections' => [
|
||||
// Available caches stores
|
||||
'stores' => [
|
||||
|
||||
'pusher' => [
|
||||
'driver' => 'pusher',
|
||||
'key' => env('PUSHER_APP_KEY'),
|
||||
'secret' => env('PUSHER_APP_SECRET'),
|
||||
'app_id' => env('PUSHER_APP_ID'),
|
||||
'options' => [
|
||||
'cluster' => env('PUSHER_APP_CLUSTER'),
|
||||
'useTLS' => true,
|
||||
],
|
||||
'apc' => [
|
||||
'driver' => 'apc',
|
||||
],
|
||||
|
||||
'array' => [
|
||||
'driver' => 'array',
|
||||
'serialize' => false,
|
||||
],
|
||||
|
||||
'database' => [
|
||||
'driver' => 'database',
|
||||
'table' => 'cache',
|
||||
'connection' => null,
|
||||
'lock_connection' => null,
|
||||
],
|
||||
|
||||
'file' => [
|
||||
'driver' => 'file',
|
||||
'path' => storage_path('framework/cache'),
|
||||
],
|
||||
|
||||
'memcached' => [
|
||||
'driver' => 'memcached',
|
||||
'servers' => env('CACHE_DRIVER') === 'memcached' ? $memcachedServers : [],
|
||||
'options' => [],
|
||||
],
|
||||
|
||||
'redis' => [
|
||||
'driver' => 'redis',
|
||||
'connection' => 'default',
|
||||
'driver' => 'redis',
|
||||
'connection' => 'default',
|
||||
'lock_connection' => 'default',
|
||||
],
|
||||
|
||||
'log' => [
|
||||
'driver' => 'log',
|
||||
],
|
||||
|
||||
'null' => [
|
||||
'driver' => 'null',
|
||||
'octane' => [
|
||||
'driver' => 'octane',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
// Cache key prefix
|
||||
// Used to prevent collisions in shared cache systems.
|
||||
'prefix' => env('CACHE_PREFIX', 'bookstack_cache'),
|
||||
|
||||
];
|
||||
|
@ -1,36 +1,36 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Caching configuration options.
|
||||
*
|
||||
* Changes to these config files are not supported by BookStack and may break upon updates.
|
||||
* Configuration should be altered via the `.env` file or environment variables.
|
||||
* Do not edit this file unless you're happy to maintain any changes yourself.
|
||||
*/
|
||||
|
||||
// MEMCACHED - Split out configuration into an array
|
||||
if (env('CACHE_DRIVER') === 'memcached') {
|
||||
$memcachedServerKeys = ['host', 'port', 'weight'];
|
||||
$memcachedServers = explode(',', trim(env('MEMCACHED_SERVERS', '127.0.0.1:11211:100'), ','));
|
||||
foreach ($memcachedServers as $index => $memcachedServer) {
|
||||
$memcachedServerDetails = explode(':', $memcachedServer);
|
||||
if (count($memcachedServerDetails) < 2) {
|
||||
$memcachedServerDetails[] = '11211';
|
||||
}
|
||||
if (count($memcachedServerDetails) < 3) {
|
||||
$memcachedServerDetails[] = '100';
|
||||
}
|
||||
$memcachedServers[$index] = array_combine($memcachedServerKeys, $memcachedServerDetails);
|
||||
}
|
||||
}
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
return [
|
||||
|
||||
// Default cache store to use
|
||||
// Can be overridden at cache call-time
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Default Cache Store
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| This option controls the default cache connection that gets used while
|
||||
| using this caching library. This connection is used when another is
|
||||
| not explicitly specified when executing a given caching function.
|
||||
|
|
||||
*/
|
||||
|
||||
'default' => env('CACHE_DRIVER', 'file'),
|
||||
|
||||
// Available caches stores
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Cache Stores
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may define all of the cache "stores" for your application as
|
||||
| well as their drivers. You may even define multiple stores for the
|
||||
| same cache driver to group types of items stored in your caches.
|
||||
|
|
||||
| Supported drivers: "apc", "array", "database", "file",
|
||||
| "memcached", "redis", "dynamodb", "octane", "null"
|
||||
|
|
||||
*/
|
||||
|
||||
'stores' => [
|
||||
|
||||
'apc' => [
|
||||
@ -38,13 +38,15 @@ return [
|
||||
],
|
||||
|
||||
'array' => [
|
||||
'driver' => 'array',
|
||||
'driver' => 'array',
|
||||
'serialize' => false,
|
||||
],
|
||||
|
||||
'database' => [
|
||||
'driver' => 'database',
|
||||
'table' => 'cache',
|
||||
'connection' => null,
|
||||
'driver' => 'database',
|
||||
'table' => 'cache',
|
||||
'connection' => null,
|
||||
'lock_connection' => null,
|
||||
],
|
||||
|
||||
'file' => [
|
||||
@ -53,19 +55,50 @@ return [
|
||||
],
|
||||
|
||||
'memcached' => [
|
||||
'driver' => 'memcached',
|
||||
'driver' => 'memcached',
|
||||
'persistent_id' => env('MEMCACHED_PERSISTENT_ID'),
|
||||
'sasl' => [
|
||||
env('MEMCACHED_USERNAME'),
|
||||
env('MEMCACHED_PASSWORD'),
|
||||
],
|
||||
'options' => [
|
||||
// Memcached::OPT_CONNECT_TIMEOUT => 2000,
|
||||
],
|
||||
'servers' => env('CACHE_DRIVER') === 'memcached' ? $memcachedServers : [],
|
||||
],
|
||||
|
||||
'redis' => [
|
||||
'driver' => 'redis',
|
||||
'connection' => 'default',
|
||||
'driver' => 'redis',
|
||||
'connection' => 'default',
|
||||
'lock_connection' => 'default',
|
||||
],
|
||||
|
||||
'dynamodb' => [
|
||||
'driver' => 'dynamodb',
|
||||
'key' => env('AWS_ACCESS_KEY_ID'),
|
||||
'secret' => env('AWS_SECRET_ACCESS_KEY'),
|
||||
'region' => env('AWS_DEFAULT_REGION', 'us-east-1'),
|
||||
'table' => env('DYNAMODB_CACHE_TABLE', 'cache'),
|
||||
'endpoint' => env('DYNAMODB_ENDPOINT'),
|
||||
],
|
||||
|
||||
'octane' => [
|
||||
'driver' => 'octane',
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
// Cache key prefix
|
||||
// Used to prevent collisions in shared cache systems.
|
||||
'prefix' => env('CACHE_PREFIX', 'bookstack_cache'),
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Cache Key Prefix
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| When utilizing a RAM based store such as APC or Memcached, there might
|
||||
| be other applications utilizing the same cache. So, we'll specify a
|
||||
| value to get prefixed to all our keys so we can avoid collisions.
|
||||
|
|
||||
*/
|
||||
|
||||
'prefix' => env('CACHE_PREFIX', Str::slug(env('APP_NAME', 'laravel'), '_') . '_cache'),
|
||||
|
||||
];
|
||||
|
415
app/Config/clockwork.php
Normal file
415
app/Config/clockwork.php
Normal file
@ -0,0 +1,415 @@
|
||||
<?php
|
||||
|
||||
return [
|
||||
|
||||
/*
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
| Enable Clockwork
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
| Clockwork is enabled by default only when your application is in debug mode. Here you can explicitly enable or
|
||||
| disable Clockwork. When disabled, no data is collected and the api and web ui are inactive.
|
||||
|
|
||||
*/
|
||||
|
||||
'enable' => env('CLOCKWORK_ENABLE', false),
|
||||
|
||||
/*
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
| Features
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
| You can enable or disable various Clockwork features here. Some features have additional settings (eg. slow query
|
||||
| threshold for database queries).
|
||||
|
|
||||
*/
|
||||
|
||||
'features' => [
|
||||
|
||||
// Cache usage stats and cache queries including results
|
||||
'cache' => [
|
||||
'enabled' => true,
|
||||
|
||||
// Collect cache queries
|
||||
'collect_queries' => true,
|
||||
|
||||
// Collect values from cache queries (high performance impact with a very high number of queries)
|
||||
'collect_values' => false
|
||||
],
|
||||
|
||||
// Database usage stats and queries
|
||||
'database' => [
|
||||
'enabled' => true,
|
||||
|
||||
// Collect database queries (high performance impact with a very high number of queries)
|
||||
'collect_queries' => true,
|
||||
|
||||
// Collect details of models updates (high performance impact with a lot of model updates)
|
||||
'collect_models_actions' => true,
|
||||
|
||||
// Collect details of retrieved models (very high performance impact with a lot of models retrieved)
|
||||
'collect_models_retrieved' => false,
|
||||
|
||||
// Query execution time threshold in miliseconds after which the query will be marked as slow
|
||||
'slow_threshold' => null,
|
||||
|
||||
// Collect only slow database queries
|
||||
'slow_only' => false,
|
||||
|
||||
// Detect and report duplicate (N+1) queries
|
||||
'detect_duplicate_queries' => false
|
||||
],
|
||||
|
||||
// Dispatched events
|
||||
'events' => [
|
||||
'enabled' => true,
|
||||
|
||||
// Ignored events (framework events are ignored by default)
|
||||
'ignored_events' => [
|
||||
// App\Events\UserRegistered::class,
|
||||
// 'user.registered'
|
||||
],
|
||||
],
|
||||
|
||||
// Laravel log (you can still log directly to Clockwork with laravel log disabled)
|
||||
'log' => [
|
||||
'enabled' => true
|
||||
],
|
||||
|
||||
// Sent notifications
|
||||
'notifications' => [
|
||||
'enabled' => true,
|
||||
],
|
||||
|
||||
// Performance metrics
|
||||
'performance' => [
|
||||
// Allow collecting of client metrics. Requires separate clockwork-browser npm package.
|
||||
'client_metrics' => true
|
||||
],
|
||||
|
||||
// Dispatched queue jobs
|
||||
'queue' => [
|
||||
'enabled' => true
|
||||
],
|
||||
|
||||
// Redis commands
|
||||
'redis' => [
|
||||
'enabled' => true
|
||||
],
|
||||
|
||||
// Routes list
|
||||
'routes' => [
|
||||
'enabled' => false,
|
||||
|
||||
// Collect only routes from particular namespaces (only application routes by default)
|
||||
'only_namespaces' => [ 'App' ]
|
||||
],
|
||||
|
||||
// Rendered views
|
||||
'views' => [
|
||||
'enabled' => true,
|
||||
|
||||
// Collect views including view data (high performance impact with a high number of views)
|
||||
'collect_data' => false,
|
||||
|
||||
// Use Twig profiler instead of Laravel events for apps using laravel-twigbridge (more precise, but does
|
||||
// not support collecting view data)
|
||||
'use_twig_profiler' => false
|
||||
]
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
| Enable web UI
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
| Clockwork comes with a web UI accessibla via http://your.app/clockwork. Here you can enable or disable this
|
||||
| feature. You can also set a custom path for the web UI.
|
||||
|
|
||||
*/
|
||||
|
||||
'web' => true,
|
||||
|
||||
/*
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
| Enable toolbar
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
| Clockwork can show a toolbar with basic metrics on all responses. Here you can enable or disable this feature.
|
||||
| Requires a separate clockwork-browser npm library.
|
||||
| For installation instructions see https://underground.works/clockwork/#docs-viewing-data
|
||||
|
|
||||
*/
|
||||
|
||||
'toolbar' => true,
|
||||
|
||||
/*
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
| HTTP requests collection
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
| Clockwork collects data about HTTP requests to your app. Here you can choose which requests should be collected.
|
||||
|
|
||||
*/
|
||||
|
||||
'requests' => [
|
||||
// With on-demand mode enabled, Clockwork will only profile requests when the browser extension is open or you
|
||||
// manually pass a "clockwork-profile" cookie or get/post data key.
|
||||
// Optionally you can specify a "secret" that has to be passed as the value to enable profiling.
|
||||
'on_demand' => false,
|
||||
|
||||
// Collect only errors (requests with HTTP 4xx and 5xx responses)
|
||||
'errors_only' => false,
|
||||
|
||||
// Response time threshold in miliseconds after which the request will be marked as slow
|
||||
'slow_threshold' => null,
|
||||
|
||||
// Collect only slow requests
|
||||
'slow_only' => false,
|
||||
|
||||
// Sample the collected requests (eg. set to 100 to collect only 1 in 100 requests)
|
||||
'sample' => false,
|
||||
|
||||
// List of URIs that should not be collected
|
||||
'except' => [
|
||||
'/horizon/.*', // Laravel Horizon requests
|
||||
'/telescope/.*', // Laravel Telescope requests
|
||||
'/_debugbar/.*', // Laravel DebugBar requests
|
||||
],
|
||||
|
||||
// List of URIs that should be collected, any other URI will not be collected if not empty
|
||||
'only' => [
|
||||
// '/api/.*'
|
||||
],
|
||||
|
||||
// Don't collect OPTIONS requests, mostly used in the CSRF pre-flight requests and are rarely of interest
|
||||
'except_preflight' => true
|
||||
],
|
||||
|
||||
/*
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
| Artisan commands collection
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
| Clockwork can collect data about executed artisan commands. Here you can enable and configure which commands
|
||||
| should be collected.
|
||||
|
|
||||
*/
|
||||
|
||||
'artisan' => [
|
||||
// Enable or disable collection of executed Artisan commands
|
||||
'collect' => false,
|
||||
|
||||
// List of commands that should not be collected (built-in commands are not collected by default)
|
||||
'except' => [
|
||||
// 'inspire'
|
||||
],
|
||||
|
||||
// List of commands that should be collected, any other command will not be collected if not empty
|
||||
'only' => [
|
||||
// 'inspire'
|
||||
],
|
||||
|
||||
// Enable or disable collection of command output
|
||||
'collect_output' => false,
|
||||
|
||||
// Enable or disable collection of built-in Laravel commands
|
||||
'except_laravel_commands' => true
|
||||
],
|
||||
|
||||
/*
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
| Queue jobs collection
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
| Clockwork can collect data about executed queue jobs. Here you can enable and configure which queue jobs should
|
||||
| be collected.
|
||||
|
|
||||
*/
|
||||
|
||||
'queue' => [
|
||||
// Enable or disable collection of executed queue jobs
|
||||
'collect' => false,
|
||||
|
||||
// List of queue jobs that should not be collected
|
||||
'except' => [
|
||||
// App\Jobs\ExpensiveJob::class
|
||||
],
|
||||
|
||||
// List of queue jobs that should be collected, any other queue job will not be collected if not empty
|
||||
'only' => [
|
||||
// App\Jobs\BuggyJob::class
|
||||
]
|
||||
],
|
||||
|
||||
/*
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
| Tests collection
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
| Clockwork can collect data about executed tests. Here you can enable and configure which tests should be
|
||||
| collected.
|
||||
|
|
||||
*/
|
||||
|
||||
'tests' => [
|
||||
// Enable or disable collection of ran tests
|
||||
'collect' => false,
|
||||
|
||||
// List of tests that should not be collected
|
||||
'except' => [
|
||||
// Tests\Unit\ExampleTest::class
|
||||
]
|
||||
],
|
||||
|
||||
/*
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
| Enable data collection when Clockwork is disabled
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
| You can enable this setting to collect data even when Clockwork is disabled. Eg. for future analysis.
|
||||
|
|
||||
*/
|
||||
|
||||
'collect_data_always' => false,
|
||||
|
||||
/*
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
| Metadata storage
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
| Configure how is the metadata collected by Clockwork stored. Two options are available:
|
||||
| - files - A simple fast storage implementation storing data in one-per-request files.
|
||||
| - sql - Stores requests in a sql database. Supports MySQL, Postgresql, Sqlite and requires PDO.
|
||||
|
|
||||
*/
|
||||
|
||||
'storage' => 'files',
|
||||
|
||||
// Path where the Clockwork metadata is stored
|
||||
'storage_files_path' => storage_path('clockwork'),
|
||||
|
||||
// Compress the metadata files using gzip, trading a little bit of performance for lower disk usage
|
||||
'storage_files_compress' => false,
|
||||
|
||||
// SQL database to use, can be a name of database configured in database.php or a path to a sqlite file
|
||||
'storage_sql_database' => storage_path('clockwork.sqlite'),
|
||||
|
||||
// SQL table name to use, the table is automatically created and udpated when needed
|
||||
'storage_sql_table' => 'clockwork',
|
||||
|
||||
// Maximum lifetime of collected metadata in minutes, older requests will automatically be deleted, false to disable
|
||||
'storage_expiration' => 60 * 24 * 7,
|
||||
|
||||
/*
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
| Authentication
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
| Clockwork can be configured to require authentication before allowing access to the collected data. This might be
|
||||
| useful when the application is publicly accessible. Setting to true will enable a simple authentication with a
|
||||
| pre-configured password. You can also pass a class name of a custom implementation.
|
||||
|
|
||||
*/
|
||||
|
||||
'authentication' => false,
|
||||
|
||||
// Password for the simple authentication
|
||||
'authentication_password' => 'VerySecretPassword',
|
||||
|
||||
/*
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
| Stack traces collection
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
| Clockwork can collect stack traces for log messages and certain data like database queries. Here you can set
|
||||
| whether to collect stack traces, limit the number of collected frames and set further configuration. Collecting
|
||||
| long stack traces considerably increases metadata size.
|
||||
|
|
||||
*/
|
||||
|
||||
'stack_traces' => [
|
||||
// Enable or disable collecting of stack traces
|
||||
'enabled' => true,
|
||||
|
||||
// Limit the number of frames to be collected
|
||||
'limit' => 10,
|
||||
|
||||
// List of vendor names to skip when determining caller, common vendors are automatically added
|
||||
'skip_vendors' => [
|
||||
// 'phpunit'
|
||||
],
|
||||
|
||||
// List of namespaces to skip when determining caller
|
||||
'skip_namespaces' => [
|
||||
// 'Laravel'
|
||||
],
|
||||
|
||||
// List of class names to skip when determining caller
|
||||
'skip_classes' => [
|
||||
// App\CustomLog::class
|
||||
]
|
||||
|
||||
],
|
||||
|
||||
/*
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
| Serialization
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
| Clockwork serializes the collected data to json for storage and transfer. Here you can configure certain aspects
|
||||
| of serialization. Serialization has a large effect on the cpu time and memory usage.
|
||||
|
|
||||
*/
|
||||
|
||||
// Maximum depth of serialized multi-level arrays and objects
|
||||
'serialization_depth' => 10,
|
||||
|
||||
// A list of classes that will never be serialized (eg. a common service container class)
|
||||
'serialization_blackbox' => [
|
||||
\Illuminate\Container\Container::class,
|
||||
\Illuminate\Foundation\Application::class,
|
||||
],
|
||||
|
||||
/*
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
| Register helpers
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
| Clockwork comes with a "clock" global helper function. You can use this helper to quickly log something and to
|
||||
| access the Clockwork instance.
|
||||
|
|
||||
*/
|
||||
|
||||
'register_helpers' => true,
|
||||
|
||||
/*
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
| Send Headers for AJAX request
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
| When trying to collect data the AJAX method can sometimes fail if it is missing required headers. For example, an
|
||||
| API might require a version number using Accept headers to route the HTTP request to the correct codebase.
|
||||
|
|
||||
*/
|
||||
|
||||
'headers' => [
|
||||
// 'Accept' => 'application/vnd.com.whatever.v1+json',
|
||||
],
|
||||
|
||||
/*
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
| Server-Timing
|
||||
|------------------------------------------------------------------------------------------------------------------
|
||||
|
|
||||
| Clockwork supports the W3C Server Timing specification, which allows for collecting a simple performance metrics
|
||||
| in a cross-browser way. Eg. in Chrome, your app, database and timeline event timings will be shown in the Dev
|
||||
| Tools network tab. This setting specifies the max number of timeline events that will be sent. Setting to false
|
||||
| will disable the feature.
|
||||
|
|
||||
*/
|
||||
|
||||
'server_timing' => 10
|
||||
|
||||
];
|
@ -25,9 +25,6 @@ return [
|
||||
// file storage service, such as s3, to store publicly accessible assets.
|
||||
'url' => env('STORAGE_URL', false),
|
||||
|
||||
// Default Cloud Filesystem Disk
|
||||
'cloud' => 's3',
|
||||
|
||||
// Available filesystem disks
|
||||
// Only local, local_secure & s3 are supported by BookStack
|
||||
'disks' => [
|
||||
@ -35,6 +32,7 @@ return [
|
||||
'local' => [
|
||||
'driver' => 'local',
|
||||
'root' => public_path(),
|
||||
'visibility' => 'public',
|
||||
],
|
||||
|
||||
'local_secure_attachments' => [
|
||||
@ -45,6 +43,7 @@ return [
|
||||
'local_secure_images' => [
|
||||
'driver' => 'local',
|
||||
'root' => storage_path('uploads/images/'),
|
||||
'visibility' => 'public',
|
||||
],
|
||||
|
||||
's3' => [
|
||||
@ -59,4 +58,12 @@ return [
|
||||
|
||||
],
|
||||
|
||||
// Symbolic Links
|
||||
// Here you may configure the symbolic links that will be created when the
|
||||
// `storage:link` Artisan command is executed. The array keys should be
|
||||
// the locations of the links and the values should be their targets.
|
||||
'links' => [
|
||||
public_path('storage') => storage_path('app/public'),
|
||||
],
|
||||
|
||||
];
|
||||
|
@ -49,16 +49,9 @@ return [
|
||||
'days' => 7,
|
||||
],
|
||||
|
||||
'slack' => [
|
||||
'driver' => 'slack',
|
||||
'url' => env('LOG_SLACK_WEBHOOK_URL'),
|
||||
'username' => 'Laravel Log',
|
||||
'emoji' => ':boom:',
|
||||
'level' => 'critical',
|
||||
],
|
||||
|
||||
'stderr' => [
|
||||
'driver' => 'monolog',
|
||||
'level' => 'debug',
|
||||
'handler' => StreamHandler::class,
|
||||
'with' => [
|
||||
'stream' => 'php://stderr',
|
||||
@ -99,6 +92,10 @@ return [
|
||||
'testing' => [
|
||||
'driver' => 'testing',
|
||||
],
|
||||
|
||||
'emergency' => [
|
||||
'path' => storage_path('logs/laravel.log'),
|
||||
],
|
||||
],
|
||||
|
||||
// Failed Login Message
|
||||
|
@ -11,6 +11,8 @@
|
||||
return [
|
||||
|
||||
// Mail driver to use.
|
||||
// From Laravel 7+ this is MAIL_MAILER in laravel.
|
||||
// Kept as MAIL_DRIVER in BookStack to prevent breaking change.
|
||||
// Options: smtp, sendmail, log, array
|
||||
'driver' => env('MAIL_DRIVER', 'smtp'),
|
||||
|
||||
|
@ -22,25 +22,29 @@ return [
|
||||
],
|
||||
|
||||
'database' => [
|
||||
'driver' => 'database',
|
||||
'table' => 'jobs',
|
||||
'queue' => 'default',
|
||||
'retry_after' => 90,
|
||||
'driver' => 'database',
|
||||
'table' => 'jobs',
|
||||
'queue' => 'default',
|
||||
'retry_after' => 90,
|
||||
'after_commit' => false,
|
||||
],
|
||||
|
||||
'redis' => [
|
||||
'driver' => 'redis',
|
||||
'connection' => 'default',
|
||||
'queue' => env('REDIS_QUEUE', 'default'),
|
||||
'retry_after' => 90,
|
||||
'block_for' => null,
|
||||
'driver' => 'redis',
|
||||
'connection' => 'default',
|
||||
'queue' => env('REDIS_QUEUE', 'default'),
|
||||
'retry_after' => 90,
|
||||
'block_for' => null,
|
||||
'after_commit' => false,
|
||||
],
|
||||
|
||||
],
|
||||
|
||||
// Failed queue job logging
|
||||
'failed' => [
|
||||
'database' => 'mysql', 'table' => 'failed_jobs',
|
||||
'driver' => 'database-uuids',
|
||||
'database' => 'mysql',
|
||||
'table' => 'failed_jobs',
|
||||
],
|
||||
|
||||
];
|
||||
|
@ -4,6 +4,7 @@ namespace BookStack\Entities\Models;
|
||||
|
||||
use BookStack\Uploads\Image;
|
||||
use Exception;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
@ -21,6 +22,8 @@ use Illuminate\Support\Collection;
|
||||
*/
|
||||
class Book extends Entity implements HasCoverImage
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $searchFactor = 2;
|
||||
|
||||
protected $fillable = ['name', 'description'];
|
||||
|
@ -3,11 +3,14 @@
|
||||
namespace BookStack\Entities\Models;
|
||||
|
||||
use BookStack\Uploads\Image;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
|
||||
|
||||
class Bookshelf extends Entity implements HasCoverImage
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
protected $table = 'bookshelves';
|
||||
|
||||
public $searchFactor = 3;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
namespace BookStack\Entities\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
/**
|
||||
@ -12,6 +13,8 @@ use Illuminate\Support\Collection;
|
||||
*/
|
||||
class Chapter extends BookChild
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public $searchFactor = 1.3;
|
||||
|
||||
protected $fillable = ['name', 'description', 'priority', 'book_id'];
|
||||
|
@ -32,7 +32,7 @@ class Deletion extends Model implements Loggable
|
||||
/**
|
||||
* Create a new deletion record for the provided entity.
|
||||
*/
|
||||
public static function createForEntity(Entity $entity): Deletion
|
||||
public static function createForEntity(Entity $entity): self
|
||||
{
|
||||
$record = (new self())->forceFill([
|
||||
'deleted_by' => user()->id,
|
||||
|
@ -106,7 +106,7 @@ abstract class Entity extends Model implements Sluggable, Favouritable, Viewable
|
||||
* Compares this entity to another given entity.
|
||||
* Matches by comparing class and id.
|
||||
*/
|
||||
public function matches(Entity $entity): bool
|
||||
public function matches(self $entity): bool
|
||||
{
|
||||
return [get_class($this), $this->id] === [get_class($entity), $entity->id];
|
||||
}
|
||||
@ -114,7 +114,7 @@ abstract class Entity extends Model implements Sluggable, Favouritable, Viewable
|
||||
/**
|
||||
* Checks if the current entity matches or contains the given.
|
||||
*/
|
||||
public function matchesOrContains(Entity $entity): bool
|
||||
public function matchesOrContains(self $entity): bool
|
||||
{
|
||||
if ($this->matches($entity)) {
|
||||
return true;
|
||||
@ -270,7 +270,7 @@ abstract class Entity extends Model implements Sluggable, Favouritable, Viewable
|
||||
* This is the "static" parent and does not include dynamic
|
||||
* relations such as shelves to books.
|
||||
*/
|
||||
public function getParent(): ?Entity
|
||||
public function getParent(): ?self
|
||||
{
|
||||
if ($this instanceof Page) {
|
||||
return $this->chapter_id ? $this->chapter()->withTrashed()->first() : $this->book()->withTrashed()->first();
|
||||
@ -300,7 +300,7 @@ abstract class Entity extends Model implements Sluggable, Favouritable, Viewable
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function refreshSlug(): string
|
||||
{
|
||||
@ -310,7 +310,7 @@ abstract class Entity extends Model implements Sluggable, Favouritable, Viewable
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function favourites(): MorphMany
|
||||
{
|
||||
|
@ -6,6 +6,7 @@ use BookStack\Entities\Tools\PageContent;
|
||||
use BookStack\Uploads\Attachment;
|
||||
use Illuminate\Database\Eloquent\Builder;
|
||||
use Illuminate\Database\Eloquent\Collection;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\HasMany;
|
||||
use Permissions;
|
||||
@ -25,6 +26,8 @@ use Permissions;
|
||||
*/
|
||||
class Page extends BookChild
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
public static $listAttributes = ['name', 'id', 'slug', 'book_id', 'chapter_id', 'draft', 'template', 'text', 'created_at', 'updated_at', 'priority'];
|
||||
public static $contentAttributes = ['name', 'id', 'slug', 'book_id', 'chapter_id', 'draft', 'template', 'html', 'text', 'created_at', 'updated_at', 'priority'];
|
||||
|
||||
@ -129,7 +132,7 @@ class Page extends BookChild
|
||||
/**
|
||||
* Get this page for JSON display.
|
||||
*/
|
||||
public function forJsonDisplay(): Page
|
||||
public function forJsonDisplay(): self
|
||||
{
|
||||
$refreshed = $this->refresh()->unsetRelations()->load(['tags', 'createdBy', 'updatedBy', 'ownedBy']);
|
||||
$refreshed->setHidden(array_diff($refreshed->getHidden(), ['html', 'markdown']));
|
||||
|
@ -29,7 +29,7 @@ class SearchOptions
|
||||
/**
|
||||
* Create a new instance from a search string.
|
||||
*/
|
||||
public static function fromString(string $search): SearchOptions
|
||||
public static function fromString(string $search): self
|
||||
{
|
||||
$decoded = static::decode($search);
|
||||
$instance = new static();
|
||||
@ -45,7 +45,7 @@ class SearchOptions
|
||||
* Will look for a classic string term and use that
|
||||
* Otherwise we'll use the details from an advanced search form.
|
||||
*/
|
||||
public static function fromRequest(Request $request): SearchOptions
|
||||
public static function fromRequest(Request $request): self
|
||||
{
|
||||
if (!$request->has('search') && !$request->has('term')) {
|
||||
return static::fromString('');
|
||||
|
@ -196,7 +196,7 @@ class SearchRunner
|
||||
$escapedOperators[] = preg_quote($operator);
|
||||
}
|
||||
|
||||
return join('|', $escapedOperators);
|
||||
return implode('|', $escapedOperators);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -9,6 +9,7 @@ use Illuminate\Http\JsonResponse;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\ValidationException;
|
||||
use Symfony\Component\HttpKernel\Exception\HttpException;
|
||||
use Throwable;
|
||||
|
||||
class Handler extends ExceptionHandler
|
||||
{
|
||||
@ -27,6 +28,7 @@ class Handler extends ExceptionHandler
|
||||
* @var array
|
||||
*/
|
||||
protected $dontFlash = [
|
||||
'current_password',
|
||||
'password',
|
||||
'password_confirmation',
|
||||
];
|
||||
@ -34,13 +36,13 @@ class Handler extends ExceptionHandler
|
||||
/**
|
||||
* Report or log an exception.
|
||||
*
|
||||
* @param Exception $exception
|
||||
* @param \Throwable $exception
|
||||
*
|
||||
* @throws Exception
|
||||
* @throws \Throwable
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function report(Exception $exception)
|
||||
public function report(Throwable $exception)
|
||||
{
|
||||
parent::report($exception);
|
||||
}
|
||||
@ -53,7 +55,7 @@ class Handler extends ExceptionHandler
|
||||
*
|
||||
* @return \Illuminate\Http\Response
|
||||
*/
|
||||
public function render($request, Exception $e)
|
||||
public function render($request, Throwable $e)
|
||||
{
|
||||
if ($this->isApiRequest($request)) {
|
||||
return $this->renderApiException($e);
|
||||
|
@ -23,7 +23,7 @@ class NotifyException extends Exception implements Responsable
|
||||
/**
|
||||
* Send the response for this type of exception.
|
||||
*
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toResponse($request)
|
||||
{
|
||||
|
@ -20,7 +20,7 @@ class PrettyException extends Exception implements Responsable
|
||||
/**
|
||||
* Render a response for when this exception occurs.
|
||||
*
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toResponse($request)
|
||||
{
|
||||
|
@ -23,7 +23,7 @@ class StoppedAuthenticationException extends \Exception implements Responsable
|
||||
}
|
||||
|
||||
/**
|
||||
* @inheritdoc
|
||||
* {@inheritdoc}
|
||||
*/
|
||||
public function toResponse($request)
|
||||
{
|
||||
|
@ -176,7 +176,7 @@ class PageController extends Controller
|
||||
{
|
||||
$page = $this->pageRepo->getById($pageId);
|
||||
$page->setHidden(array_diff($page->getHidden(), ['html', 'markdown']));
|
||||
$page->addHidden(['book']);
|
||||
$page->makeHidden(['book']);
|
||||
|
||||
return response()->json($page);
|
||||
}
|
||||
|
@ -11,7 +11,7 @@ class Kernel extends HttpKernel
|
||||
* These middleware are run during every request to your application.
|
||||
*/
|
||||
protected $middleware = [
|
||||
\BookStack\Http\Middleware\CheckForMaintenanceMode::class,
|
||||
\BookStack\Http\Middleware\PreventRequestsDuringMaintenance::class,
|
||||
\Illuminate\Foundation\Http\Middleware\ValidatePostSize::class,
|
||||
\BookStack\Http\Middleware\TrimStrings::class,
|
||||
\BookStack\Http\Middleware\TrustProxies::class,
|
||||
|
@ -2,9 +2,9 @@
|
||||
|
||||
namespace BookStack\Http\Middleware;
|
||||
|
||||
use Illuminate\Foundation\Http\Middleware\CheckForMaintenanceMode as Middleware;
|
||||
use Illuminate\Foundation\Http\Middleware\PreventRequestsDuringMaintenance as Middleware;
|
||||
|
||||
class CheckForMaintenanceMode extends Middleware
|
||||
class PreventRequestsDuringMaintenance extends Middleware
|
||||
{
|
||||
/**
|
||||
* The URIs that should be reachable while maintenance mode is enabled.
|
@ -2,45 +2,31 @@
|
||||
|
||||
namespace BookStack\Http\Middleware;
|
||||
|
||||
use BookStack\Providers\RouteServiceProvider;
|
||||
use Closure;
|
||||
use Illuminate\Contracts\Auth\Guard;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class RedirectIfAuthenticated
|
||||
{
|
||||
/**
|
||||
* The Guard implementation.
|
||||
*
|
||||
* @var Guard
|
||||
*/
|
||||
protected $auth;
|
||||
|
||||
/**
|
||||
* Create a new filter instance.
|
||||
*
|
||||
* @param Guard $auth
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function __construct(Guard $auth)
|
||||
{
|
||||
$this->auth = $auth;
|
||||
}
|
||||
|
||||
/**
|
||||
* Handle an incoming request.
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
*
|
||||
* @param \Illuminate\Http\Request $request
|
||||
* @param \Closure $next
|
||||
* @param string|null ...$guards
|
||||
* @return mixed
|
||||
*/
|
||||
public function handle($request, Closure $next)
|
||||
public function handle(Request $request, Closure $next, ...$guards)
|
||||
{
|
||||
$requireConfirmation = setting('registration-confirmation');
|
||||
if ($this->auth->check() && (!$requireConfirmation || ($requireConfirmation && $this->auth->user()->email_confirmed))) {
|
||||
return redirect('/');
|
||||
$guards = empty($guards) ? [null] : $guards;
|
||||
|
||||
foreach ($guards as $guard) {
|
||||
if (Auth::guard($guard)->check()) {
|
||||
return redirect(RouteServiceProvider::HOME);
|
||||
}
|
||||
}
|
||||
|
||||
return $next($request);
|
||||
}
|
||||
}
|
||||
}
|
20
app/Http/Middleware/TrustHosts.php
Normal file
20
app/Http/Middleware/TrustHosts.php
Normal file
@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
namespace BookStack\Http\Middleware;
|
||||
|
||||
use Illuminate\Http\Middleware\TrustHosts as Middleware;
|
||||
|
||||
class TrustHosts extends Middleware
|
||||
{
|
||||
/**
|
||||
* Get the host patterns that should be trusted.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function hosts()
|
||||
{
|
||||
return [
|
||||
$this->allSubdomainsOfApplicationUrl(),
|
||||
];
|
||||
}
|
||||
}
|
@ -3,7 +3,7 @@
|
||||
namespace BookStack\Http\Middleware;
|
||||
|
||||
use Closure;
|
||||
use Fideloper\Proxy\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Middleware\TrustProxies as Middleware;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class TrustProxies extends Middleware
|
||||
@ -20,7 +20,7 @@ class TrustProxies extends Middleware
|
||||
*
|
||||
* @var int
|
||||
*/
|
||||
protected $headers = Request::HEADER_X_FORWARDED_ALL;
|
||||
protected $headers = Request::HEADER_X_FORWARDED_FOR | Request::HEADER_X_FORWARDED_HOST | Request::HEADER_X_FORWARDED_PORT | Request::HEADER_X_FORWARDED_PROTO | Request::HEADER_X_FORWARDED_AWS_ELB;
|
||||
|
||||
/**
|
||||
* Handle the request, Set the correct user-configured proxy information.
|
||||
|
@ -16,6 +16,7 @@ use BookStack\Util\CspService;
|
||||
use GuzzleHttp\Client;
|
||||
use Illuminate\Contracts\Cache\Repository;
|
||||
use Illuminate\Database\Eloquent\Relations\Relation;
|
||||
use Illuminate\Pagination\Paginator;
|
||||
use Illuminate\Support\Facades\Blade;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
use Illuminate\Support\Facades\URL;
|
||||
@ -60,6 +61,9 @@ class AppServiceProvider extends ServiceProvider
|
||||
|
||||
// View Composers
|
||||
View::composer('entities.breadcrumbs', BreadcrumbsViewComposer::class);
|
||||
|
||||
// Set paginator to use bootstrap-style pagination
|
||||
Paginator::useBootstrap();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -30,6 +30,5 @@ class EventServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
parent::boot();
|
||||
}
|
||||
}
|
||||
|
@ -2,11 +2,23 @@
|
||||
|
||||
namespace BookStack\Providers;
|
||||
|
||||
use Illuminate\Cache\RateLimiting\Limit;
|
||||
use Illuminate\Foundation\Support\Providers\RouteServiceProvider as ServiceProvider;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Support\Facades\RateLimiter;
|
||||
use Illuminate\Support\Facades\Route;
|
||||
|
||||
class RouteServiceProvider extends ServiceProvider
|
||||
{
|
||||
/**
|
||||
* The path to the "home" route for your application.
|
||||
*
|
||||
* This is used by Laravel authentication to redirect users after login.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
public const HOME = '/';
|
||||
|
||||
/**
|
||||
* This namespace is applied to the controller routes in your routes file.
|
||||
*
|
||||
@ -14,7 +26,6 @@ class RouteServiceProvider extends ServiceProvider
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $namespace = 'BookStack\Http\Controllers';
|
||||
|
||||
/**
|
||||
* Define your route model bindings, pattern filters, etc.
|
||||
@ -23,18 +34,12 @@ class RouteServiceProvider extends ServiceProvider
|
||||
*/
|
||||
public function boot()
|
||||
{
|
||||
parent::boot();
|
||||
}
|
||||
$this->configureRateLimiting();
|
||||
|
||||
/**
|
||||
* Define the routes for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function map()
|
||||
{
|
||||
$this->mapWebRoutes();
|
||||
$this->mapApiRoutes();
|
||||
$this->routes(function () {
|
||||
$this->mapWebRoutes();
|
||||
$this->mapApiRoutes();
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
@ -71,4 +76,16 @@ class RouteServiceProvider extends ServiceProvider
|
||||
require base_path('routes/api.php');
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Configure the rate limiters for the application.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
protected function configureRateLimiting()
|
||||
{
|
||||
RateLimiter::for('api', function (Request $request) {
|
||||
return Limit::perMinute(60)->by(optional($request->user())->id ?: $request->ip());
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -93,7 +93,7 @@ class Attachment extends Model
|
||||
|
||||
return $permissionService->filterRelatedEntity(
|
||||
Page::class,
|
||||
Attachment::query(),
|
||||
self::query(),
|
||||
'attachments',
|
||||
'uploaded_to'
|
||||
);
|
||||
|
@ -5,6 +5,7 @@ namespace BookStack\Uploads;
|
||||
use BookStack\Entities\Models\Page;
|
||||
use BookStack\Model;
|
||||
use BookStack\Traits\HasCreatorAndUpdater;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
|
||||
/**
|
||||
* @property int $id
|
||||
@ -18,6 +19,7 @@ use BookStack\Traits\HasCreatorAndUpdater;
|
||||
*/
|
||||
class Image extends Model
|
||||
{
|
||||
use HasFactory;
|
||||
use HasCreatorAndUpdater;
|
||||
|
||||
protected $fillable = ['name'];
|
||||
|
@ -1,7 +1,10 @@
|
||||
{
|
||||
"name": "bookstackapp/bookstack",
|
||||
"description": "BookStack documentation platform",
|
||||
"keywords": ["BookStack", "Documentation"],
|
||||
"keywords": [
|
||||
"BookStack",
|
||||
"Documentation"
|
||||
],
|
||||
"license": "MIT",
|
||||
"type": "project",
|
||||
"require": {
|
||||
@ -16,48 +19,47 @@
|
||||
"bacon/bacon-qr-code": "^2.0",
|
||||
"barryvdh/laravel-dompdf": "^0.9.0",
|
||||
"barryvdh/laravel-snappy": "^0.4.8",
|
||||
"doctrine/dbal": "^2.12.1",
|
||||
"fideloper/proxy": "^4.4.1",
|
||||
"doctrine/dbal": "^3.1",
|
||||
"filp/whoops": "^2.14",
|
||||
"intervention/image": "^2.5.1",
|
||||
"laravel/framework": "^6.20.33",
|
||||
"laravel/socialite": "^5.1",
|
||||
"league/commonmark": "^1.5",
|
||||
"guzzlehttp/guzzle": "^7.4",
|
||||
"intervention/image": "^2.7",
|
||||
"laravel/framework": "^8.68",
|
||||
"laravel/socialite": "^5.2",
|
||||
"laravel/tinker": "^2.6",
|
||||
"laravel/ui": "^3.3",
|
||||
"league/commonmark": "^1.6",
|
||||
"league/flysystem-aws-s3-v3": "^1.0.29",
|
||||
"league/html-to-markdown": "^5.0.0",
|
||||
"league/oauth2-client": "^2.6",
|
||||
"nunomaduro/collision": "^3.1",
|
||||
"onelogin/php-saml": "^4.0",
|
||||
"phpseclib/phpseclib": "~3.0",
|
||||
"pragmarx/google2fa": "^8.0",
|
||||
"predis/predis": "^1.1.6",
|
||||
"predis/predis": "^1.1",
|
||||
"socialiteproviders/discord": "^4.1",
|
||||
"socialiteproviders/gitlab": "^4.1",
|
||||
"socialiteproviders/microsoft-azure": "^5.0.1",
|
||||
"socialiteproviders/okta": "^4.1",
|
||||
"socialiteproviders/slack": "^4.1",
|
||||
"socialiteproviders/twitch": "^5.3",
|
||||
"ssddanbrown/htmldiff": "^v1.0.1"
|
||||
"ssddanbrown/htmldiff": "^1.0.1"
|
||||
},
|
||||
"require-dev": {
|
||||
"barryvdh/laravel-debugbar": "^3.5.1",
|
||||
"barryvdh/laravel-ide-helper": "^2.8.2",
|
||||
"fakerphp/faker": "^1.13.0",
|
||||
"mockery/mockery": "^1.3.3",
|
||||
"phpunit/phpunit": "^9.5.3",
|
||||
"symfony/dom-crawler": "^5.3"
|
||||
"fakerphp/faker": "^1.16",
|
||||
"itsgoingd/clockwork": "^5.1",
|
||||
"mockery/mockery": "^1.4",
|
||||
"phpunit/phpunit": "^9.5",
|
||||
"symfony/dom-crawler": "^5.3",
|
||||
"nunomaduro/collision": "^5.10"
|
||||
},
|
||||
"autoload": {
|
||||
"classmap": [
|
||||
"database/seeds",
|
||||
"database/factories"
|
||||
],
|
||||
"psr-4": {
|
||||
"BookStack\\": "app/"
|
||||
"BookStack\\": "app/",
|
||||
"Database\\Factories\\": "database/factories/",
|
||||
"Database\\Seeders\\": "database/seeders/"
|
||||
},
|
||||
"files": [
|
||||
"app/helpers.php"
|
||||
]
|
||||
"files": [
|
||||
"app/helpers.php"
|
||||
]
|
||||
},
|
||||
"autoload-dev": {
|
||||
"psr-4": {
|
||||
@ -65,6 +67,10 @@
|
||||
}
|
||||
},
|
||||
"scripts": {
|
||||
"post-autoload-dump": [
|
||||
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||
"@php artisan package:discover --ansi"
|
||||
],
|
||||
"post-root-package-install": [
|
||||
"@php -r \"file_exists('.env') || copy('.env.example', '.env');\""
|
||||
],
|
||||
@ -78,10 +84,6 @@
|
||||
"@php artisan cache:clear",
|
||||
"@php artisan view:clear"
|
||||
],
|
||||
"post-autoload-dump": [
|
||||
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
|
||||
"@php artisan package:discover --ansi"
|
||||
],
|
||||
"refresh-test-database": [
|
||||
"@php artisan migrate:refresh --database=mysql_testing",
|
||||
"@php artisan db:seed --class=DummyContentSeeder --database=mysql_testing"
|
||||
|
3144
composer.lock
generated
3144
composer.lock
generated
File diff suppressed because it is too large
Load Diff
32
database/factories/Actions/CommentFactory.php
Normal file
32
database/factories/Actions/CommentFactory.php
Normal file
@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories\Actions;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class CommentFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = \BookStack\Actions\Comment::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition()
|
||||
{
|
||||
$text = $this->faker->paragraph(1);
|
||||
$html = '<p>' . $text . '</p>';
|
||||
|
||||
return [
|
||||
'html' => $html,
|
||||
'text' => $text,
|
||||
'parent_id' => null,
|
||||
];
|
||||
}
|
||||
}
|
28
database/factories/Actions/TagFactory.php
Normal file
28
database/factories/Actions/TagFactory.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories\Actions;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class TagFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = \BookStack\Actions\Tag::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition()
|
||||
{
|
||||
return [
|
||||
'name' => $this->faker->city,
|
||||
'value' => $this->faker->sentence(3),
|
||||
];
|
||||
}
|
||||
}
|
28
database/factories/Auth/RoleFactory.php
Normal file
28
database/factories/Auth/RoleFactory.php
Normal file
@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories\Auth;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class RoleFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = \BookStack\Auth\Role::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition()
|
||||
{
|
||||
return [
|
||||
'display_name' => $this->faker->sentence(3),
|
||||
'description' => $this->faker->sentence(10),
|
||||
];
|
||||
}
|
||||
}
|
35
database/factories/Auth/UserFactory.php
Normal file
35
database/factories/Auth/UserFactory.php
Normal file
@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories\Auth;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class UserFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = \BookStack\Auth\User::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition()
|
||||
{
|
||||
$name = $this->faker->name;
|
||||
|
||||
return [
|
||||
'name' => $name,
|
||||
'email' => $this->faker->email,
|
||||
'slug' => \Illuminate\Support\Str::slug($name . '-' . \Illuminate\Support\Str::random(5)),
|
||||
'password' => Str::random(10),
|
||||
'remember_token' => Str::random(10),
|
||||
'email_confirmed' => 1,
|
||||
];
|
||||
}
|
||||
}
|
30
database/factories/Entities/Models/BookFactory.php
Normal file
30
database/factories/Entities/Models/BookFactory.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories\Entities\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class BookFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = \BookStack\Entities\Models\Book::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition()
|
||||
{
|
||||
return [
|
||||
'name' => $this->faker->sentence,
|
||||
'slug' => Str::random(10),
|
||||
'description' => $this->faker->paragraph,
|
||||
];
|
||||
}
|
||||
}
|
30
database/factories/Entities/Models/BookshelfFactory.php
Normal file
30
database/factories/Entities/Models/BookshelfFactory.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories\Entities\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class BookshelfFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = \BookStack\Entities\Models\Bookshelf::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition()
|
||||
{
|
||||
return [
|
||||
'name' => $this->faker->sentence,
|
||||
'slug' => Str::random(10),
|
||||
'description' => $this->faker->paragraph,
|
||||
];
|
||||
}
|
||||
}
|
30
database/factories/Entities/Models/ChapterFactory.php
Normal file
30
database/factories/Entities/Models/ChapterFactory.php
Normal file
@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories\Entities\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class ChapterFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = \BookStack\Entities\Models\Chapter::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition()
|
||||
{
|
||||
return [
|
||||
'name' => $this->faker->sentence,
|
||||
'slug' => Str::random(10),
|
||||
'description' => $this->faker->paragraph,
|
||||
];
|
||||
}
|
||||
}
|
34
database/factories/Entities/Models/PageFactory.php
Normal file
34
database/factories/Entities/Models/PageFactory.php
Normal file
@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories\Entities\Models;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class PageFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = \BookStack\Entities\Models\Page::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition()
|
||||
{
|
||||
$html = '<p>' . implode('</p>', $this->faker->paragraphs(5)) . '</p>';
|
||||
|
||||
return [
|
||||
'name' => $this->faker->sentence,
|
||||
'slug' => Str::random(10),
|
||||
'html' => $html,
|
||||
'text' => strip_tags($html),
|
||||
'revision_count' => 1,
|
||||
];
|
||||
}
|
||||
}
|
@ -1,96 +0,0 @@
|
||||
<?php
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Model Factories
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Here you may define all of your model factories. Model factories give
|
||||
| you a convenient way to create models for testing and seeding your
|
||||
| database. Just tell the factory how a default model should look.
|
||||
|
|
||||
*/
|
||||
|
||||
$factory->define(\BookStack\Auth\User::class, function ($faker) {
|
||||
$name = $faker->name;
|
||||
|
||||
return [
|
||||
'name' => $name,
|
||||
'email' => $faker->email,
|
||||
'slug' => \Illuminate\Support\Str::slug($name . '-' . \Illuminate\Support\Str::random(5)),
|
||||
'password' => Str::random(10),
|
||||
'remember_token' => Str::random(10),
|
||||
'email_confirmed' => 1,
|
||||
];
|
||||
});
|
||||
|
||||
$factory->define(\BookStack\Entities\Models\Bookshelf::class, function ($faker) {
|
||||
return [
|
||||
'name' => $faker->sentence,
|
||||
'slug' => Str::random(10),
|
||||
'description' => $faker->paragraph,
|
||||
];
|
||||
});
|
||||
|
||||
$factory->define(\BookStack\Entities\Models\Book::class, function ($faker) {
|
||||
return [
|
||||
'name' => $faker->sentence,
|
||||
'slug' => Str::random(10),
|
||||
'description' => $faker->paragraph,
|
||||
];
|
||||
});
|
||||
|
||||
$factory->define(\BookStack\Entities\Models\Chapter::class, function ($faker) {
|
||||
return [
|
||||
'name' => $faker->sentence,
|
||||
'slug' => Str::random(10),
|
||||
'description' => $faker->paragraph,
|
||||
];
|
||||
});
|
||||
|
||||
$factory->define(\BookStack\Entities\Models\Page::class, function ($faker) {
|
||||
$html = '<p>' . implode('</p>', $faker->paragraphs(5)) . '</p>';
|
||||
|
||||
return [
|
||||
'name' => $faker->sentence,
|
||||
'slug' => Str::random(10),
|
||||
'html' => $html,
|
||||
'text' => strip_tags($html),
|
||||
'revision_count' => 1,
|
||||
];
|
||||
});
|
||||
|
||||
$factory->define(\BookStack\Auth\Role::class, function ($faker) {
|
||||
return [
|
||||
'display_name' => $faker->sentence(3),
|
||||
'description' => $faker->sentence(10),
|
||||
];
|
||||
});
|
||||
|
||||
$factory->define(\BookStack\Actions\Tag::class, function ($faker) {
|
||||
return [
|
||||
'name' => $faker->city,
|
||||
'value' => $faker->sentence(3),
|
||||
];
|
||||
});
|
||||
|
||||
$factory->define(\BookStack\Uploads\Image::class, function ($faker) {
|
||||
return [
|
||||
'name' => $faker->slug . '.jpg',
|
||||
'url' => $faker->url,
|
||||
'path' => $faker->url,
|
||||
'type' => 'gallery',
|
||||
'uploaded_to' => 0,
|
||||
];
|
||||
});
|
||||
|
||||
$factory->define(\BookStack\Actions\Comment::class, function ($faker) {
|
||||
$text = $faker->paragraph(1);
|
||||
$html = '<p>' . $text . '</p>';
|
||||
|
||||
return [
|
||||
'html' => $html,
|
||||
'text' => $text,
|
||||
'parent_id' => null,
|
||||
];
|
||||
});
|
31
database/factories/Uploads/ImageFactory.php
Normal file
31
database/factories/Uploads/ImageFactory.php
Normal file
@ -0,0 +1,31 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Factories\Uploads;
|
||||
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
|
||||
class ImageFactory extends Factory
|
||||
{
|
||||
/**
|
||||
* The name of the factory's corresponding model.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $model = \BookStack\Uploads\Image::class;
|
||||
|
||||
/**
|
||||
* Define the model's default state.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function definition()
|
||||
{
|
||||
return [
|
||||
'name' => $this->faker->slug . '.jpg',
|
||||
'url' => $this->faker->url,
|
||||
'path' => $this->faker->url,
|
||||
'type' => 'gallery',
|
||||
'uploaded_to' => 0,
|
||||
];
|
||||
}
|
||||
}
|
@ -2,6 +2,7 @@
|
||||
|
||||
use Illuminate\Database\Migrations\Migration;
|
||||
use Illuminate\Database\Schema\Blueprint;
|
||||
use Illuminate\Support\Facades\DB;
|
||||
use Illuminate\Support\Facades\Schema;
|
||||
|
||||
class CreateBookshelvesTable extends Migration
|
||||
|
@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use Illuminate\Database\Eloquent\Model;
|
||||
use Illuminate\Database\Seeder;
|
||||
|
@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use BookStack\Api\ApiToken;
|
||||
use BookStack\Auth\Permissions\PermissionService;
|
||||
use BookStack\Auth\Permissions\RolePermission;
|
||||
@ -10,6 +12,7 @@ use BookStack\Entities\Models\Chapter;
|
||||
use BookStack\Entities\Models\Page;
|
||||
use BookStack\Entities\Tools\SearchIndex;
|
||||
use Illuminate\Database\Seeder;
|
||||
use Illuminate\Support\Facades\Hash;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class DummyContentSeeder extends Seeder
|
||||
@ -22,36 +25,36 @@ class DummyContentSeeder extends Seeder
|
||||
public function run()
|
||||
{
|
||||
// Create an editor user
|
||||
$editorUser = factory(User::class)->create();
|
||||
$editorUser = User::factory()->create();
|
||||
$editorRole = Role::getRole('editor');
|
||||
$editorUser->attachRole($editorRole);
|
||||
|
||||
// Create a viewer user
|
||||
$viewerUser = factory(User::class)->create();
|
||||
$viewerUser = User::factory()->create();
|
||||
$role = Role::getRole('viewer');
|
||||
$viewerUser->attachRole($role);
|
||||
|
||||
$byData = ['created_by' => $editorUser->id, 'updated_by' => $editorUser->id, 'owned_by' => $editorUser->id];
|
||||
|
||||
factory(\BookStack\Entities\Models\Book::class, 5)->create($byData)
|
||||
\BookStack\Entities\Models\Book::factory()->count(5)->create($byData)
|
||||
->each(function ($book) use ($byData) {
|
||||
$chapters = factory(Chapter::class, 3)->create($byData)
|
||||
$chapters = Chapter::factory()->count(3)->create($byData)
|
||||
->each(function ($chapter) use ($book, $byData) {
|
||||
$pages = factory(Page::class, 3)->make(array_merge($byData, ['book_id' => $book->id]));
|
||||
$pages = Page::factory()->count(3)->make(array_merge($byData, ['book_id' => $book->id]));
|
||||
$chapter->pages()->saveMany($pages);
|
||||
});
|
||||
$pages = factory(Page::class, 3)->make($byData);
|
||||
$pages = Page::factory()->count(3)->make($byData);
|
||||
$book->chapters()->saveMany($chapters);
|
||||
$book->pages()->saveMany($pages);
|
||||
});
|
||||
|
||||
$largeBook = factory(\BookStack\Entities\Models\Book::class)->create(array_merge($byData, ['name' => 'Large book' . Str::random(10)]));
|
||||
$pages = factory(Page::class, 200)->make($byData);
|
||||
$chapters = factory(Chapter::class, 50)->make($byData);
|
||||
$largeBook = \BookStack\Entities\Models\Book::factory()->create(array_merge($byData, ['name' => 'Large book' . Str::random(10)]));
|
||||
$pages = Page::factory()->count(200)->make($byData);
|
||||
$chapters = Chapter::factory()->count(50)->make($byData);
|
||||
$largeBook->pages()->saveMany($pages);
|
||||
$largeBook->chapters()->saveMany($chapters);
|
||||
|
||||
$shelves = factory(Bookshelf::class, 10)->create($byData);
|
||||
$shelves = Bookshelf::factory()->count(10)->create($byData);
|
||||
$largeBook->shelves()->attach($shelves->pluck('id'));
|
||||
|
||||
// Assign API permission to editor role and create an API key
|
@ -1,5 +1,7 @@
|
||||
<?php
|
||||
|
||||
namespace Database\Seeders;
|
||||
|
||||
use BookStack\Auth\Permissions\PermissionService;
|
||||
use BookStack\Auth\Role;
|
||||
use BookStack\Auth\User;
|
||||
@ -19,13 +21,13 @@ class LargeContentSeeder extends Seeder
|
||||
public function run()
|
||||
{
|
||||
// Create an editor user
|
||||
$editorUser = factory(User::class)->create();
|
||||
$editorUser = User::factory()->create();
|
||||
$editorRole = Role::getRole('editor');
|
||||
$editorUser->attachRole($editorRole);
|
||||
|
||||
$largeBook = factory(\BookStack\Entities\Models\Book::class)->create(['name' => 'Large book' . Str::random(10), 'created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
|
||||
$pages = factory(Page::class, 200)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
|
||||
$chapters = factory(Chapter::class, 50)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
|
||||
$largeBook = \BookStack\Entities\Models\Book::factory()->create(['name' => 'Large book' . Str::random(10), 'created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
|
||||
$pages = Page::factory()->count(200)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
|
||||
$chapters = Chapter::factory()->count(50)->make(['created_by' => $editorUser->id, 'updated_by' => $editorUser->id]);
|
||||
$largeBook->pages()->saveMany($pages);
|
||||
$largeBook->chapters()->saveMany($chapters);
|
||||
app(PermissionService::class)->buildJointPermissions();
|
@ -7,6 +7,6 @@
|
||||
"order": 2,
|
||||
"created_by": 1,
|
||||
"updated_by": 1,
|
||||
"created_at": "2021-10-20 06:35:46",
|
||||
"updated_at": "2021-10-20 06:35:46"
|
||||
"created_at": "2021-10-20T06:35:46.000000Z",
|
||||
"updated_at": "2021-10-20T06:35:46.000000Z"
|
||||
}
|
@ -7,8 +7,8 @@
|
||||
"uploaded_to": 8,
|
||||
"external": false,
|
||||
"order": 1,
|
||||
"created_at": "2021-10-11 06:18:49",
|
||||
"updated_at": "2021-10-20 06:31:10",
|
||||
"created_at": "2021-10-11T06:18:49.000000Z",
|
||||
"updated_at": "2021-10-20T06:31:10.000000Z",
|
||||
"created_by": 1,
|
||||
"updated_by": 1
|
||||
},
|
||||
@ -19,8 +19,8 @@
|
||||
"uploaded_to": 9,
|
||||
"external": true,
|
||||
"order": 1,
|
||||
"created_at": "2021-10-20 06:30:11",
|
||||
"updated_at": "2021-10-20 06:30:11",
|
||||
"created_at": "2021-10-20T06:30:11.000000Z",
|
||||
"updated_at": "2021-10-20T06:30:11.000000Z",
|
||||
"created_by": 1,
|
||||
"updated_by": 1
|
||||
}
|
||||
|
@ -15,8 +15,8 @@
|
||||
"name": "Admin",
|
||||
"slug": "admin"
|
||||
},
|
||||
"created_at": "2021-10-20 06:35:46",
|
||||
"updated_at": "2021-10-20 06:37:11",
|
||||
"created_at": "2021-10-20T06:35:46.000000Z",
|
||||
"updated_at": "2021-10-20T06:37:11.000000Z",
|
||||
"links": {
|
||||
"html": "<a target=\"_blank\" href=\"https://bookstack.local/attachments/5\">My updated attachment</a>",
|
||||
"markdown": "[My updated attachment](https://bookstack.local/attachments/5)"
|
||||
|
@ -7,6 +7,6 @@
|
||||
"order": 2,
|
||||
"created_by": 1,
|
||||
"updated_by": 1,
|
||||
"created_at": "2021-10-20 06:35:46",
|
||||
"updated_at": "2021-10-20 06:37:11"
|
||||
"created_at": "2021-10-20T06:35:46.000000Z",
|
||||
"updated_at": "2021-10-20T06:37:11.000000Z"
|
||||
}
|
@ -5,7 +5,7 @@
|
||||
"updated_by": 1,
|
||||
"owned_by": 1,
|
||||
"slug": "my-new-book",
|
||||
"updated_at": "2020-01-12 14:05:11",
|
||||
"created_at": "2020-01-12 14:05:11",
|
||||
"updated_at": "2020-01-12T14:05:11.000000Z",
|
||||
"created_at": "2020-01-12T14:05:11.000000Z",
|
||||
"id": 15
|
||||
}
|
@ -5,8 +5,8 @@
|
||||
"name": "BookStack User Guide",
|
||||
"slug": "bookstack-user-guide",
|
||||
"description": "This is a general guide on using BookStack on a day-to-day basis.",
|
||||
"created_at": "2019-05-05 21:48:46",
|
||||
"updated_at": "2019-12-11 20:57:31",
|
||||
"created_at": "2019-05-05T21:48:46.000000Z",
|
||||
"updated_at": "2019-12-11T20:57:31.000000Z",
|
||||
"created_by": 1,
|
||||
"updated_by": 1,
|
||||
"owned_by": 1,
|
||||
@ -17,8 +17,8 @@
|
||||
"name": "Inventore inventore quia voluptatem.",
|
||||
"slug": "inventore-inventore-quia-voluptatem",
|
||||
"description": "Veniam nihil voluptas enim laborum corporis quos sint. Ab rerum voluptas ut iste voluptas magni quibusdam ut. Amet omnis enim voluptate neque facilis.",
|
||||
"created_at": "2019-05-05 22:10:14",
|
||||
"updated_at": "2019-12-11 20:57:23",
|
||||
"created_at": "2019-05-05T22:10:14.000000Z",
|
||||
"updated_at": "2019-12-11T20:57:23.000000Z",
|
||||
"created_by": 4,
|
||||
"updated_by": 3,
|
||||
"owned_by": 3,
|
||||
|
@ -3,8 +3,8 @@
|
||||
"name": "My own book",
|
||||
"slug": "my-own-book",
|
||||
"description": "This is my own little book",
|
||||
"created_at": "2020-01-12 14:09:59",
|
||||
"updated_at": "2020-01-12 14:11:51",
|
||||
"created_at": "2020-01-12T14:09:59.000000Z",
|
||||
"updated_at": "2020-01-12T14:11:51.000000Z",
|
||||
"created_by": {
|
||||
"id": 1,
|
||||
"name": "Admin"
|
||||
@ -29,8 +29,8 @@
|
||||
"id": 452,
|
||||
"name": "sjovall_m117hUWMu40.jpg",
|
||||
"url": "http:\/\/bookstack.local\/uploads\/images\/cover_book\/2020-01\/sjovall_m117hUWMu40.jpg",
|
||||
"created_at": "2020-01-12 14:11:51",
|
||||
"updated_at": "2020-01-12 14:11:51",
|
||||
"created_at": "2020-01-12T14:11:51.000000Z",
|
||||
"updated_at": "2020-01-12T14:11:51.000000Z",
|
||||
"created_by": 1,
|
||||
"updated_by": 1,
|
||||
"path": "\/uploads\/images\/cover_book\/2020-01\/sjovall_m117hUWMu40.jpg",
|
||||
|
@ -3,8 +3,8 @@
|
||||
"name": "My own book",
|
||||
"slug": "my-own-book",
|
||||
"description": "This is my own little book - updated",
|
||||
"created_at": "2020-01-12 14:09:59",
|
||||
"updated_at": "2020-01-12 14:16:10",
|
||||
"created_at": "2020-01-12T14:09:59.000000Z",
|
||||
"updated_at": "2020-01-12T14:16:10.000000Z",
|
||||
"created_by": 1,
|
||||
"updated_by": 1,
|
||||
"owned_by": 1,
|
||||
|
@ -7,16 +7,16 @@
|
||||
"updated_by": 1,
|
||||
"owned_by": 1,
|
||||
"slug": "my-fantastic-new-chapter",
|
||||
"updated_at": "2020-05-22 22:59:55",
|
||||
"created_at": "2020-05-22 22:59:55",
|
||||
"updated_at": "2020-05-22T22:59:55.000000Z",
|
||||
"created_at": "2020-05-22T22:59:55.000000Z",
|
||||
"id": 74,
|
||||
"book": {
|
||||
"id": 1,
|
||||
"name": "BookStack User Guide",
|
||||
"slug": "bookstack-user-guide",
|
||||
"description": "This is a general guide on using BookStack on a day-to-day basis.",
|
||||
"created_at": "2019-05-05 21:48:46",
|
||||
"updated_at": "2019-12-11 20:57:31",
|
||||
"created_at": "2019-05-05T21:48:46.000000Z",
|
||||
"updated_at": "2019-12-11T20:57:31.000000Z",
|
||||
"created_by": 1,
|
||||
"updated_by": 1
|
||||
},
|
||||
@ -25,15 +25,15 @@
|
||||
"name": "Category",
|
||||
"value": "Top Content",
|
||||
"order": 0,
|
||||
"created_at": "2020-05-22 22:59:55",
|
||||
"updated_at": "2020-05-22 22:59:55"
|
||||
"created_at": "2020-05-22T22:59:55.000000Z",
|
||||
"updated_at": "2020-05-22T22:59:55.000000Z"
|
||||
},
|
||||
{
|
||||
"name": "Rating",
|
||||
"value": "Highest",
|
||||
"order": 0,
|
||||
"created_at": "2020-05-22 22:59:55",
|
||||
"updated_at": "2020-05-22 22:59:55"
|
||||
"created_at": "2020-05-22T22:59:55.000000Z",
|
||||
"updated_at": "2020-05-22T22:59:55.000000Z"
|
||||
}
|
||||
]
|
||||
}
|
@ -7,8 +7,8 @@
|
||||
"slug": "content-creation",
|
||||
"description": "How to create documentation on whatever subject you need to write about.",
|
||||
"priority": 3,
|
||||
"created_at": "2019-05-05 21:49:56",
|
||||
"updated_at": "2019-09-28 11:24:23",
|
||||
"created_at": "2019-05-05:",
|
||||
"updated_at": "2019-09-28T11:24:23.000000Z",
|
||||
"created_by": 1,
|
||||
"updated_by": 1,
|
||||
"owned_by": 1
|
||||
@ -20,8 +20,8 @@
|
||||
"slug": "managing-content",
|
||||
"description": "How to keep things organised and orderly in the system for easier navigation and better user experience.",
|
||||
"priority": 5,
|
||||
"created_at": "2019-05-05 21:58:07",
|
||||
"updated_at": "2019-10-17 15:05:34",
|
||||
"created_at": "2019-05-05T21:58:07.000000Z",
|
||||
"updated_at": "2019-10-17T15:05:34.000000Z",
|
||||
"created_by": 3,
|
||||
"updated_by": 3,
|
||||
"owned_by": 3
|
||||
|
@ -5,8 +5,8 @@
|
||||
"name": "Content Creation",
|
||||
"description": "How to create documentation on whatever subject you need to write about.",
|
||||
"priority": 3,
|
||||
"created_at": "2019-05-05 21:49:56",
|
||||
"updated_at": "2019-09-28 11:24:23",
|
||||
"created_at": "2019-05-05T21:49:56.000000Z",
|
||||
"updated_at": "2019-09-28T11:24:23.000000Z",
|
||||
"created_by": {
|
||||
"id": 1,
|
||||
"name": "Admin"
|
||||
@ -34,8 +34,8 @@
|
||||
"name": "How to create page content",
|
||||
"slug": "how-to-create-page-content",
|
||||
"priority": 0,
|
||||
"created_at": "2019-05-05 21:49:58",
|
||||
"updated_at": "2019-08-26 14:32:59",
|
||||
"created_at": "2019-05-05T21:49:58.000000Z",
|
||||
"updated_at": "2019-08-26T14:32:59.000000Z",
|
||||
"created_by": 1,
|
||||
"updated_by": 1,
|
||||
"draft": false,
|
||||
@ -49,8 +49,8 @@
|
||||
"name": "Good book structure",
|
||||
"slug": "good-book-structure",
|
||||
"priority": 1,
|
||||
"created_at": "2019-05-05 22:01:55",
|
||||
"updated_at": "2019-06-06 12:03:04",
|
||||
"created_at": "2019-05-05T22:01:55.000000Z",
|
||||
"updated_at": "2019-06-06T12:03:04.000000Z",
|
||||
"created_by": 3,
|
||||
"updated_by": 3,
|
||||
"draft": false,
|
||||
|
@ -5,8 +5,8 @@
|
||||
"name": "My fantastic updated chapter",
|
||||
"description": "This is an updated chapter that I've altered via the API",
|
||||
"priority": 7,
|
||||
"created_at": "2020-05-22 23:03:35",
|
||||
"updated_at": "2020-05-22 23:07:20",
|
||||
"created_at": "2020-05-22T23:03:35.000000Z",
|
||||
"updated_at": "2020-05-22T23:07:20.000000Z",
|
||||
"created_by": 1,
|
||||
"updated_by": 1,
|
||||
"owned_by": 1,
|
||||
@ -15,8 +15,8 @@
|
||||
"name": "BookStack User Guide",
|
||||
"slug": "bookstack-user-guide",
|
||||
"description": "This is a general guide on using BookStack on a day-to-day basis.",
|
||||
"created_at": "2019-05-05 21:48:46",
|
||||
"updated_at": "2019-12-11 20:57:31",
|
||||
"created_at": "2019-05-05T21:48:46.000000Z",
|
||||
"updated_at": "2019-12-11T20:57:31.000000Z",
|
||||
"created_by": 1,
|
||||
"updated_by": 1
|
||||
},
|
||||
@ -25,15 +25,15 @@
|
||||
"name": "Category",
|
||||
"value": "Kinda Good Content",
|
||||
"order": 0,
|
||||
"created_at": "2020-05-22 23:07:20",
|
||||
"updated_at": "2020-05-22 23:07:20"
|
||||
"created_at": "2020-05-22T23:07:20.000000Z",
|
||||
"updated_at": "2020-05-22T23:07:20.000000Z"
|
||||
},
|
||||
{
|
||||
"name": "Rating",
|
||||
"value": "Medium",
|
||||
"order": 0,
|
||||
"created_at": "2020-05-22 23:07:20",
|
||||
"updated_at": "2020-05-22 23:07:20"
|
||||
"created_at": "2020-05-22T23:07:20.000000Z",
|
||||
"updated_at": "2020-05-22T23:07:20.000000Z"
|
||||
}
|
||||
]
|
||||
}
|
@ -6,8 +6,8 @@
|
||||
"slug": "my-api-page",
|
||||
"html": "<p id=\"bkmrk-my-new-api-page\">my new API page</p>",
|
||||
"priority": 14,
|
||||
"created_at": "2020-11-28 15:01:39",
|
||||
"updated_at": "2020-11-28 15:01:39",
|
||||
"created_at": "2020-11-28T15:01:39.000000Z",
|
||||
"updated_at": "2020-11-28T15:01:39.000000Z",
|
||||
"created_by": {
|
||||
"id": 1,
|
||||
"name": "Admin"
|
||||
|
@ -9,8 +9,8 @@
|
||||
"priority": 0,
|
||||
"draft": false,
|
||||
"template": false,
|
||||
"created_at": "2019-05-05 21:49:58",
|
||||
"updated_at": "2020-07-04 15:50:58",
|
||||
"created_at": "2019-05-05T21:49:58.000000Z",
|
||||
"updated_at": "2020-07-04T15:50:58.000000Z",
|
||||
"created_by": 1,
|
||||
"updated_by": 1,
|
||||
"owned_by": 1
|
||||
@ -24,8 +24,8 @@
|
||||
"priority": 2,
|
||||
"draft": false,
|
||||
"template": false,
|
||||
"created_at": "2019-05-05 21:53:30",
|
||||
"updated_at": "2019-06-06 12:03:04",
|
||||
"created_at": "2019-05-05T21:53:30.000000Z",
|
||||
"updated_at": "2019-06-06T12:03:04.000000Z",
|
||||
"created_by": 1,
|
||||
"updated_by": 1,
|
||||
"owned_by": 1
|
||||
@ -39,8 +39,8 @@
|
||||
"priority": 3,
|
||||
"draft": false,
|
||||
"template": false,
|
||||
"created_at": "2019-05-05 21:53:49",
|
||||
"updated_at": "2019-12-18 21:56:52",
|
||||
"created_at": "2019-05-05T21:53:49.000000Z",
|
||||
"updated_at": "2019-12-18T21:56:52.000000Z",
|
||||
"created_by": 1,
|
||||
"updated_by": 1,
|
||||
"owned_by": 1
|
||||
|
@ -6,8 +6,8 @@
|
||||
"slug": "a-page-written-in-markdown",
|
||||
"html": "<h1 id=\"bkmrk-how-this-is-built\">How this is built</h1>\r\n<p id=\"bkmrk-this-page-is-written\">This page is written in markdown. BookStack stores the page data in HTML.</p>\r\n<p id=\"bkmrk-here%27s-a-cute-pictur\">Here's a cute picture of my cat:</p>\r\n<p id=\"bkmrk-\"><a href=\"http://example.com/uploads/images/gallery/2020-04/yXSrubes.jpg\"><img src=\"http://example.com/uploads/images/gallery/2020-04/scaled-1680-/yXSrubes.jpg\" alt=\"yXSrubes.jpg\"></a></p>",
|
||||
"priority": 13,
|
||||
"created_at": "2020-02-02 21:40:38",
|
||||
"updated_at": "2020-11-28 14:43:20",
|
||||
"created_at": "2020-02-02T21:40:38.000000Z",
|
||||
"updated_at": "2020-11-28T14:43:20.000000Z",
|
||||
"created_by": {
|
||||
"id": 1,
|
||||
"name": "Admin"
|
||||
|
@ -6,8 +6,8 @@
|
||||
"slug": "my-updated-api-page",
|
||||
"html": "<p id=\"bkmrk-my-new-api-page---up\">my new API page - Updated</p>",
|
||||
"priority": 16,
|
||||
"created_at": "2020-11-28 15:10:54",
|
||||
"updated_at": "2020-11-28 15:13:03",
|
||||
"created_at": "2020-11-28T15:10:54.000000Z",
|
||||
"updated_at": "2020-11-28T15:13:03.000000Z",
|
||||
"created_by": {
|
||||
"id": 1,
|
||||
"name": "Admin"
|
||||
|
@ -5,7 +5,7 @@
|
||||
"updated_by": 1,
|
||||
"owned_by": 1,
|
||||
"slug": "my-shelf",
|
||||
"updated_at": "2020-04-10 13:24:09",
|
||||
"created_at": "2020-04-10 13:24:09",
|
||||
"updated_at": "2020-04-10T13:24:09.000000Z",
|
||||
"created_at": "2020-04-10T13:24:09.000000Z",
|
||||
"id": 14
|
||||
}
|
@ -5,8 +5,8 @@
|
||||
"name": "Qui qui aspernatur autem molestiae libero necessitatibus molestias.",
|
||||
"slug": "qui-qui-aspernatur-autem-molestiae-libero-necessitatibus-molestias",
|
||||
"description": "Enim dolor ut quia error dolores est. Aut distinctio consequuntur non nisi nostrum. Labore cupiditate error labore aliquid provident impedit voluptatibus. Quaerat impedit excepturi eius qui eius voluptatem reiciendis.",
|
||||
"created_at": "2019-05-05 22:10:16",
|
||||
"updated_at": "2020-04-10 13:00:45",
|
||||
"created_at": "2019-05-05T22:10:16.000000Z",
|
||||
"updated_at": "2020-04-10T13:00:45.000000Z",
|
||||
"created_by": 4,
|
||||
"updated_by": 1,
|
||||
"owned_by": 1,
|
||||
@ -17,8 +17,8 @@
|
||||
"name": "Ipsum aut inventore fuga libero non facilis.",
|
||||
"slug": "ipsum-aut-inventore-fuga-libero-non-facilis",
|
||||
"description": "Labore culpa modi perspiciatis harum sit. Maxime non et nam est. Quae ut laboriosam repellendus sunt quisquam. Velit at est perspiciatis nesciunt adipisci nobis illo. Sed possimus odit optio officiis nisi voluptates officiis dolor.",
|
||||
"created_at": "2019-05-05 22:10:16",
|
||||
"updated_at": "2020-04-10 13:00:58",
|
||||
"created_at": "2019-05-05T22:10:16.000000Z",
|
||||
"updated_at": "2020-04-10T13:00:58.000000Z",
|
||||
"created_by": 4,
|
||||
"updated_by": 1,
|
||||
"owned_by": 1,
|
||||
@ -29,8 +29,8 @@
|
||||
"name": "Omnis reiciendis aut molestias sint accusantium.",
|
||||
"slug": "omnis-reiciendis-aut-molestias-sint-accusantium",
|
||||
"description": "Qui ea occaecati alias est dolores voluptatem doloribus. Ad reiciendis corporis vero nostrum omnis et. Non doloribus ut eaque ut quos dolores.",
|
||||
"created_at": "2019-05-05 22:10:16",
|
||||
"updated_at": "2020-04-10 13:00:53",
|
||||
"created_at": "2019-05-05T22:10:16.000000Z",
|
||||
"updated_at": "2020-04-10T13:00:53.000000Z",
|
||||
"created_by": 4,
|
||||
"updated_by": 1,
|
||||
"owned_by": 4,
|
||||
|
@ -15,8 +15,8 @@
|
||||
"id": 1,
|
||||
"name": "Admin"
|
||||
},
|
||||
"created_at": "2020-04-10 13:24:09",
|
||||
"updated_at": "2020-04-10 13:31:04",
|
||||
"created_at": "2020-04-10T13:24:09.000000Z",
|
||||
"updated_at": "2020-04-10T13:31:04.000000Z",
|
||||
"tags": [
|
||||
{
|
||||
"id": 16,
|
||||
@ -29,8 +29,8 @@
|
||||
"id": 501,
|
||||
"name": "anafrancisconi_Sp04AfFCPNM.jpg",
|
||||
"url": "http://bookstack.local/uploads/images/cover_book/2020-04/anafrancisconi_Sp04AfFCPNM.jpg",
|
||||
"created_at": "2020-04-10 13:31:04",
|
||||
"updated_at": "2020-04-10 13:31:04",
|
||||
"created_at": "2020-04-10T13:31:04.000000Z",
|
||||
"updated_at": "2020-04-10T13:31:04.000000Z",
|
||||
"created_by": 1,
|
||||
"updated_by": 1,
|
||||
"path": "/uploads/images/cover_book/2020-04/anafrancisconi_Sp04AfFCPNM.jpg",
|
||||
|
@ -7,6 +7,6 @@
|
||||
"updated_by": 1,
|
||||
"owned_by": 1,
|
||||
"image_id": 501,
|
||||
"created_at": "2020-04-10 13:24:09",
|
||||
"updated_at": "2020-04-10 13:48:22"
|
||||
"created_at": "2020-04-10T13:24:09.000000Z",
|
||||
"updated_at": "2020-04-10T13:48:22.000000Z"
|
||||
}
|
@ -1,15 +1,8 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd"
|
||||
backupGlobals="false"
|
||||
backupStaticAttributes="false"
|
||||
bootstrap="vendor/autoload.php"
|
||||
colors="true"
|
||||
convertErrorsToExceptions="true"
|
||||
convertNoticesToExceptions="true"
|
||||
convertWarningsToExceptions="true"
|
||||
processIsolation="false"
|
||||
stopOnFailure="false">
|
||||
colors="true">
|
||||
<coverage>
|
||||
<include>
|
||||
<directory suffix=".php">app/</directory>
|
||||
|
@ -1,21 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Laravel - A PHP Framework For Web Artisans.
|
||||
*
|
||||
* @author Taylor Otwell <taylor@laravel.com>
|
||||
*/
|
||||
use Illuminate\Contracts\Http\Kernel;
|
||||
use BookStack\Http\Request;
|
||||
|
||||
define('LARAVEL_START', microtime(true));
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Check If The Application Is Under Maintenance
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| If the application is in maintenance / demo mode via the "down" command
|
||||
| we will load this file so that any pre-rendered content can be shown
|
||||
| instead of starting the framework, which could cause an exception.
|
||||
|
|
||||
*/
|
||||
|
||||
if (file_exists(__DIR__ . '/../storage/framework/maintenance.php')) {
|
||||
require __DIR__ . '/../storage/framework/maintenance.php';
|
||||
}
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Register The Auto Loader
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Composer provides a convenient, automatically generated class loader for
|
||||
| our application. We just need to utilize it! We'll simply require it
|
||||
| into the script here so that we don't have to worry about manual
|
||||
| loading any of our classes later on. It feels great to relax.
|
||||
| this application. We just need to utilize it! We'll simply require it
|
||||
| into the script here so we don't need to manually load our classes.
|
||||
|
|
||||
*/
|
||||
|
||||
@ -23,37 +35,22 @@ require __DIR__ . '/../vendor/autoload.php';
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Turn On The Lights
|
||||
| Run The Application
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| We need to illuminate PHP development, so let us turn on the lights.
|
||||
| This bootstraps the framework and gets it ready for use, then it
|
||||
| will load up this application so that we can run it and send
|
||||
| the responses back to the browser and delight our users.
|
||||
| Once we have the application, we can handle the incoming request using
|
||||
| the application's HTTP kernel. Then, we will send the response back
|
||||
| to this client's browser, allowing them to enjoy our application.
|
||||
|
|
||||
*/
|
||||
|
||||
$app = require_once __DIR__ . '/../bootstrap/app.php';
|
||||
$app->alias('request', \BookStack\Http\Request::class);
|
||||
$app->alias('request', Request::class);
|
||||
|
||||
/*
|
||||
|--------------------------------------------------------------------------
|
||||
| Run The Application
|
||||
|--------------------------------------------------------------------------
|
||||
|
|
||||
| Once we have the application, we can handle the incoming request
|
||||
| through the kernel, and send the associated response back to
|
||||
| the client's browser allowing them to enjoy the creative
|
||||
| and wonderful application we have prepared for them.
|
||||
|
|
||||
*/
|
||||
$kernel = $app->make(Kernel::class);
|
||||
|
||||
$kernel = $app->make(Illuminate\Contracts\Http\Kernel::class);
|
||||
$response = tap($kernel->handle(
|
||||
$request = Request::capture()
|
||||
))->send();
|
||||
|
||||
$response = $kernel->handle(
|
||||
$request = \BookStack\Http\Request::capture()
|
||||
);
|
||||
|
||||
$response->send();
|
||||
|
||||
$kernel->terminate($request, $response);
|
||||
$kernel->terminate($request, $response);
|
10
readme.md
10
readme.md
@ -206,11 +206,8 @@ These are the great open-source projects used to help build BookStack:
|
||||
* [Dropzone.js](http://www.dropzonejs.com/)
|
||||
* [clipboard.js](https://clipboardjs.com/)
|
||||
* [markdown-it](https://github.com/markdown-it/markdown-it) and [markdown-it-task-lists](https://github.com/revin/markdown-it-task-lists)
|
||||
* [BarryVD](https://github.com/barryvdh)
|
||||
* [Debugbar](https://github.com/barryvdh/laravel-debugbar)
|
||||
* [Dompdf](https://github.com/barryvdh/laravel-dompdf)
|
||||
* [Snappy (WKHTML2PDF)](https://github.com/barryvdh/laravel-snappy)
|
||||
* [Laravel IDE helper](https://github.com/barryvdh/laravel-ide-helper)
|
||||
* [BarryVD/Dompdf](https://github.com/barryvdh/laravel-dompdf)
|
||||
* [BarryVD/Snappy (WKHTML2PDF)](https://github.com/barryvdh/laravel-snappy)
|
||||
* [WKHTMLtoPDF](http://wkhtmltopdf.org/index.html)
|
||||
* [diagrams.net](https://github.com/jgraph/drawio)
|
||||
* [OneLogin's SAML PHP Toolkit](https://github.com/onelogin/php-saml)
|
||||
@ -219,4 +216,5 @@ These are the great open-source projects used to help build BookStack:
|
||||
* [StyleCI](https://styleci.io/)
|
||||
* [pragmarx/google2fa](https://github.com/antonioribeiro/google2fa)
|
||||
* [Bacon/BaconQrCode](https://github.com/Bacon/BaconQrCode)
|
||||
* [phpseclib](https://github.com/phpseclib/phpseclib)
|
||||
* [phpseclib](https://github.com/phpseclib/phpseclib)
|
||||
* [Clockwork](https://github.com/itsgoingd/clockwork)
|
@ -38,7 +38,6 @@ return [
|
||||
'registration_email_domain_invalid' => 'المجال الخاص بالبريد الإلكتروني لا يملك حق الوصول لهذا التطبيق',
|
||||
'register_success' => 'شكراً لإنشاء حسابكم! تم تسجيلكم ودخولكم للحساب الخاص بكم.',
|
||||
|
||||
|
||||
// Password Reset
|
||||
'reset_password' => 'استعادة كلمة المرور',
|
||||
'reset_password_send_instructions' => 'أدخل بريدك الإلكتروني بالأسفل وسيتم إرسال رسالة برابط لاستعادة كلمة المرور.',
|
||||
@ -49,7 +48,6 @@ return [
|
||||
'email_reset_text' => 'تم إرسال هذه الرسالة بسبب تلقينا لطلب استعادة كلمة المرور الخاصة بحسابكم.',
|
||||
'email_reset_not_requested' => 'إذا لم يتم طلب استعادة كلمة المرور من قبلكم، فلا حاجة لاتخاذ أية خطوات.',
|
||||
|
||||
|
||||
// Email Confirmation
|
||||
'email_confirm_subject' => 'تأكيد بريدكم الإلكتروني لتطبيق :appName',
|
||||
'email_confirm_greeting' => 'شكرا لانضمامكم إلى :appName!',
|
||||
@ -109,4 +107,4 @@ return [
|
||||
'mfa_verify_backup_code_enter_here' => 'Enter backup code here',
|
||||
'mfa_verify_totp_desc' => 'Enter the code, generated using your mobile app, below:',
|
||||
'mfa_setup_login_notification' => 'Multi-factor method configured, Please now login again using the configured method.',
|
||||
];
|
||||
];
|
||||
|
@ -20,7 +20,7 @@ return [
|
||||
'role' => 'الدور',
|
||||
'cover_image' => 'صورة الغلاف',
|
||||
'cover_image_description' => 'الصورة يجب أن تكون مقاربة لحجم 440×250 بكسل.',
|
||||
|
||||
|
||||
// Actions
|
||||
'actions' => 'إجراءات',
|
||||
'view' => 'عرض',
|
||||
|
@ -321,5 +321,5 @@ return [
|
||||
'revision_delete_confirm' => 'هل أنت متأكد من أنك تريد حذف هذه المراجعة؟',
|
||||
'revision_restore_confirm' => 'هل أنت متأكد من أنك تريد استعادة هذه المراجعة؟ سيتم استبدال محتوى الصفحة الحالية.',
|
||||
'revision_delete_success' => 'تم حذف المراجعة',
|
||||
'revision_cannot_delete_latest' => 'لايمكن حذف آخر مراجعة.'
|
||||
'revision_cannot_delete_latest' => 'لايمكن حذف آخر مراجعة.',
|
||||
];
|
||||
|
@ -7,7 +7,7 @@
|
||||
return [
|
||||
|
||||
'password' => 'يجب أن تتكون كلمة المرور من ستة أحرف على الأقل وأن تطابق التأكيد.',
|
||||
'user' => "لم يتم العثور على مستخدم بعنوان البريد الإلكتروني المعطى.",
|
||||
'user' => 'لم يتم العثور على مستخدم بعنوان البريد الإلكتروني المعطى.',
|
||||
'token' => 'رمز إعادة تعيين كلمة المرور غير صالح لعنوان هذا البريد الإلكتروني.',
|
||||
'sent' => 'تم إرسال رابط تجديد كلمة المرور إلى بريدكم الإلكتروني!',
|
||||
'reset' => 'تم تجديد كلمة المرور الخاصة بكم!',
|
||||
|
@ -72,7 +72,7 @@ return [
|
||||
// Maintenance settings
|
||||
'maint' => 'الصيانة',
|
||||
'maint_image_cleanup' => 'تنظيف الصور',
|
||||
'maint_image_cleanup_desc' => "مسح الصفحة ومراجعة المحتوى للتحقق من أي الصور والرسوم المستخدمة حاليًا وأي الصور زائدة عن الحاجة. تأكد من إنشاء قاعدة بيانات كاملة و نسخة احتياطية للصور قبل تشغيل هذا.",
|
||||
'maint_image_cleanup_desc' => 'مسح الصفحة ومراجعة المحتوى للتحقق من أي الصور والرسوم المستخدمة حاليًا وأي الصور زائدة عن الحاجة. تأكد من إنشاء قاعدة بيانات كاملة و نسخة احتياطية للصور قبل تشغيل هذا.',
|
||||
'maint_delete_images_only_in_revisions' => 'Also delete images that only exist in old page revisions',
|
||||
'maint_image_cleanup_run' => 'بدء التنظيف',
|
||||
'maint_image_cleanup_warning' => 'يوجد عدد :count من الصور المحتمل عدم استخدامها. تأكيد حذف الصور؟',
|
||||
@ -132,7 +132,7 @@ return [
|
||||
'role_delete' => 'حذف الدور',
|
||||
'role_delete_confirm' => 'سيتم حذف الدور المسمى \':roleName\'.',
|
||||
'role_delete_users_assigned' => 'هذا الدور له: عدد المستخدمين المعينين له. إذا كنت ترغب في ترحيل المستخدمين من هذا الدور ، فحدد دورًا جديدًا أدناه.',
|
||||
'role_delete_no_migration' => "لا تقم بترجيل المستخدمين",
|
||||
'role_delete_no_migration' => 'لا تقم بترجيل المستخدمين',
|
||||
'role_delete_sure' => 'تأكيد حذف الدور؟',
|
||||
'role_delete_success' => 'تم حذف الدور بنجاح',
|
||||
'role_edit' => 'تعديل الدور',
|
||||
@ -273,6 +273,6 @@ return [
|
||||
'vi' => 'Tiếng Việt',
|
||||
'zh_CN' => '简体中文',
|
||||
'zh_TW' => '繁體中文',
|
||||
]
|
||||
],
|
||||
//!////////////////////////////////
|
||||
];
|
||||
|
@ -38,7 +38,6 @@ return [
|
||||
'registration_email_domain_invalid' => 'Този емейл домейн към момента няма достъп до приложението',
|
||||
'register_success' => 'Благодарим Ви за регистрацията! В момента сте регистриран и сте вписани в приложението.',
|
||||
|
||||
|
||||
// Password Reset
|
||||
'reset_password' => 'Нулиране на паролата',
|
||||
'reset_password_send_instructions' => 'Въведете емейла си и ще ви бъде изпратен емейл с линк за нулиране на паролата.',
|
||||
@ -49,7 +48,6 @@ return [
|
||||
'email_reset_text' => 'Вие получихте този емейл, защото поискахте вашата парола да бъде занулена.',
|
||||
'email_reset_not_requested' => 'Ако Вие не сте поискали зануляването на паролата, няма нужда от други действия.',
|
||||
|
||||
|
||||
// Email Confirmation
|
||||
'email_confirm_subject' => 'Потвърди емейла си за :appName',
|
||||
'email_confirm_greeting' => 'Благодарим Ви, че се присъединихте към :appName!',
|
||||
@ -109,4 +107,4 @@ return [
|
||||
'mfa_verify_backup_code_enter_here' => 'Enter backup code here',
|
||||
'mfa_verify_totp_desc' => 'Enter the code, generated using your mobile app, below:',
|
||||
'mfa_setup_login_notification' => 'Multi-factor method configured, Please now login again using the configured method.',
|
||||
];
|
||||
];
|
||||
|
@ -20,7 +20,7 @@ return [
|
||||
'role' => 'Роля',
|
||||
'cover_image' => 'Основно изображение',
|
||||
'cover_image_description' => 'Картината трябва да е приблизително 440х250 пиксела.',
|
||||
|
||||
|
||||
// Actions
|
||||
'actions' => 'Действия',
|
||||
'view' => 'Преглед',
|
||||
|
@ -321,5 +321,5 @@ return [
|
||||
'revision_delete_confirm' => 'Наистина ли искате да изтриете тази версия?',
|
||||
'revision_restore_confirm' => 'Сигурни ли сте, че искате да изтриете тази версия? Настоящата страница ще бъде заместена.',
|
||||
'revision_delete_success' => 'Версията беше изтрита',
|
||||
'revision_cannot_delete_latest' => 'Не може да изтриете последната версия.'
|
||||
'revision_cannot_delete_latest' => 'Не може да изтриете последната версия.',
|
||||
];
|
||||
|
@ -7,7 +7,7 @@
|
||||
return [
|
||||
|
||||
'password' => 'Паролите трябва да имат поне 8 символа и да съвпадат с потвърждението.',
|
||||
'user' => "Не можем да намерим потребител с този имейл адрес.",
|
||||
'user' => 'Не можем да намерим потребител с този имейл адрес.',
|
||||
'token' => 'Кодът за зануляване на паролата е невалиден за този емейл адрес.',
|
||||
'sent' => 'Пратихме връзка за нулиране на паролата до имейла ви!',
|
||||
'reset' => 'Вашата парола е нулирана!',
|
||||
|
@ -72,7 +72,7 @@ return [
|
||||
// Maintenance settings
|
||||
'maint' => 'Maintenance',
|
||||
'maint_image_cleanup' => 'Cleanup Images',
|
||||
'maint_image_cleanup_desc' => "Scans page & revision content to check which images and drawings are currently in use and which images are redundant. Ensure you create a full database and image backup before running this.",
|
||||
'maint_image_cleanup_desc' => 'Scans page & revision content to check which images and drawings are currently in use and which images are redundant. Ensure you create a full database and image backup before running this.',
|
||||
'maint_delete_images_only_in_revisions' => 'Also delete images that only exist in old page revisions',
|
||||
'maint_image_cleanup_run' => 'Run Cleanup',
|
||||
'maint_image_cleanup_warning' => ':count potentially unused images were found. Are you sure you want to delete these images?',
|
||||
@ -132,7 +132,7 @@ return [
|
||||
'role_delete' => 'Изтрий роля',
|
||||
'role_delete_confirm' => 'Това ще изтрие ролята \':roleName\'.',
|
||||
'role_delete_users_assigned' => 'В тази роля се намират :userCount потребители. Ако искате да преместите тези потребители в друга роля, моля изберете нова роля отдолу.',
|
||||
'role_delete_no_migration' => "Не премествай потребителите в нова роля",
|
||||
'role_delete_no_migration' => 'Не премествай потребителите в нова роля',
|
||||
'role_delete_sure' => 'Сигурни ли сте, че искате да изтриете тази роля?',
|
||||
'role_delete_success' => 'Ролята беше успешно изтрита',
|
||||
'role_edit' => 'Редактиране на роля',
|
||||
@ -273,6 +273,6 @@ return [
|
||||
'vi' => 'Tiếng Việt',
|
||||
'zh_CN' => '简体中文',
|
||||
'zh_TW' => '繁體中文',
|
||||
]
|
||||
],
|
||||
//!////////////////////////////////
|
||||
];
|
||||
|
@ -38,7 +38,6 @@ return [
|
||||
'registration_email_domain_invalid' => 'Ta e-mail domena nema pristup ovoj aplikaciji',
|
||||
'register_success' => 'Hvala na registraciji! Sada ste registrovani i prijavljeni.',
|
||||
|
||||
|
||||
// Password Reset
|
||||
'reset_password' => 'Resetuj Lozinku',
|
||||
'reset_password_send_instructions' => 'Unesite vašu e-mail adresu ispod i na nju ćemo vam poslati e-mail sa linkom za promjenu lozinke.',
|
||||
@ -49,7 +48,6 @@ return [
|
||||
'email_reset_text' => 'Primate ovaj e-mail jer smo dobili zahtjev za promjenu lozinke za vaš račun.',
|
||||
'email_reset_not_requested' => 'Ako niste zahtijevali promjenu lozinke ne trebate ništa više uraditi.',
|
||||
|
||||
|
||||
// Email Confirmation
|
||||
'email_confirm_subject' => 'Potvrdite vaš e-mail na :appName',
|
||||
'email_confirm_greeting' => 'Hvala na pristupanju :appName!',
|
||||
@ -109,4 +107,4 @@ return [
|
||||
'mfa_verify_backup_code_enter_here' => 'Enter backup code here',
|
||||
'mfa_verify_totp_desc' => 'Enter the code, generated using your mobile app, below:',
|
||||
'mfa_setup_login_notification' => 'Multi-factor method configured, Please now login again using the configured method.',
|
||||
];
|
||||
];
|
||||
|
@ -20,7 +20,7 @@ return [
|
||||
'role' => 'Uloga',
|
||||
'cover_image' => 'Naslovna slika',
|
||||
'cover_image_description' => 'Ova slika treba biti približno 440x250px.',
|
||||
|
||||
|
||||
// Actions
|
||||
'actions' => 'Akcije',
|
||||
'view' => 'Prikaz',
|
||||
|
@ -321,5 +321,5 @@ return [
|
||||
'revision_delete_confirm' => 'Are you sure you want to delete this revision?',
|
||||
'revision_restore_confirm' => 'Are you sure you want to restore this revision? The current page contents will be replaced.',
|
||||
'revision_delete_success' => 'Revision deleted',
|
||||
'revision_cannot_delete_latest' => 'Cannot delete the latest revision.'
|
||||
'revision_cannot_delete_latest' => 'Cannot delete the latest revision.',
|
||||
];
|
||||
|
@ -7,7 +7,7 @@
|
||||
return [
|
||||
|
||||
'password' => 'Lozinke moraju sadržavati najmanje osam karaktera i podudarati se sa potvrdom lozinke.',
|
||||
'user' => "Ne možemo naći korisnika sa tom e-mail adresom.",
|
||||
'user' => 'Ne možemo naći korisnika sa tom e-mail adresom.',
|
||||
'token' => 'Token za poništavanje lozinke nije validan za ovu e-mail adresu.',
|
||||
'sent' => 'Poslali smo link za poništavanje vaše lozinke na e-mail!',
|
||||
'reset' => 'Vaša lozinka je resetovana!',
|
||||
|
@ -72,7 +72,7 @@ return [
|
||||
// Maintenance settings
|
||||
'maint' => 'Maintenance',
|
||||
'maint_image_cleanup' => 'Cleanup Images',
|
||||
'maint_image_cleanup_desc' => "Scans page & revision content to check which images and drawings are currently in use and which images are redundant. Ensure you create a full database and image backup before running this.",
|
||||
'maint_image_cleanup_desc' => 'Scans page & revision content to check which images and drawings are currently in use and which images are redundant. Ensure you create a full database and image backup before running this.',
|
||||
'maint_delete_images_only_in_revisions' => 'Also delete images that only exist in old page revisions',
|
||||
'maint_image_cleanup_run' => 'Run Cleanup',
|
||||
'maint_image_cleanup_warning' => ':count potentially unused images were found. Are you sure you want to delete these images?',
|
||||
@ -273,6 +273,6 @@ return [
|
||||
'vi' => 'Tiếng Việt',
|
||||
'zh_CN' => '简体中文',
|
||||
'zh_TW' => '繁體中文',
|
||||
]
|
||||
],
|
||||
//!////////////////////////////////
|
||||
];
|
||||
|
@ -38,7 +38,6 @@ return [
|
||||
'registration_email_domain_invalid' => 'Aquest domini de correu electrònic no té accés a aquesta aplicació',
|
||||
'register_success' => 'Gràcies per registrar-vos! Ja us hi heu registrat i heu iniciat la sessió.',
|
||||
|
||||
|
||||
// Password Reset
|
||||
'reset_password' => 'Restableix la contrasenya',
|
||||
'reset_password_send_instructions' => 'Introduïu la vostra adreça electrònica a continuació i us enviarem un correu electrònic amb un enllaç per a restablir la contrasenya.',
|
||||
@ -49,7 +48,6 @@ return [
|
||||
'email_reset_text' => 'Rebeu aquest correu electrònic perquè heu rebut una petició de restabliment de contrasenya per al vostre compte.',
|
||||
'email_reset_not_requested' => 'Si no heu demanat restablir la contrasenya, no cal que prengueu cap acció.',
|
||||
|
||||
|
||||
// Email Confirmation
|
||||
'email_confirm_subject' => 'Confirmeu la vostra adreça electrònica a :appName',
|
||||
'email_confirm_greeting' => 'Gràcies per unir-vos a :appName!',
|
||||
@ -109,4 +107,4 @@ return [
|
||||
'mfa_verify_backup_code_enter_here' => 'Enter backup code here',
|
||||
'mfa_verify_totp_desc' => 'Enter the code, generated using your mobile app, below:',
|
||||
'mfa_setup_login_notification' => 'Multi-factor method configured, Please now login again using the configured method.',
|
||||
];
|
||||
];
|
||||
|
@ -20,7 +20,7 @@ return [
|
||||
'role' => 'Rol',
|
||||
'cover_image' => 'Imatge de portada',
|
||||
'cover_image_description' => 'Aquesta imatge hauria de fer aproximadament 440x250 px.',
|
||||
|
||||
|
||||
// Actions
|
||||
'actions' => 'Accions',
|
||||
'view' => 'Visualitza',
|
||||
|
@ -321,5 +321,5 @@ return [
|
||||
'revision_delete_confirm' => 'Segur que voleu suprimir aquesta revisió?',
|
||||
'revision_restore_confirm' => 'Segur que voleu restaurar aquesta revisió? Se substituirà el contingut de la pàgina actual.',
|
||||
'revision_delete_success' => 'S\'ha suprimit la revisió',
|
||||
'revision_cannot_delete_latest' => 'No es pot suprimir la darrera revisió.'
|
||||
'revision_cannot_delete_latest' => 'No es pot suprimir la darrera revisió.',
|
||||
];
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user