Merge branch 'master' into 2019-design

This commit is contained in:
Dan Brown 2019-01-13 14:10:27 +00:00
commit 163a57cf70
No known key found for this signature in database
GPG Key ID: 46D9F943C24A2EF9
148 changed files with 3314 additions and 1693 deletions

View File

@ -1,11 +1,14 @@
# Environment # Application key
APP_ENV=production # Used for encryption where needed.
APP_DEBUG=false # Run `php artisan key:generate` to generate a valid key.
APP_KEY=SomeRandomString APP_KEY=SomeRandomString
# The below url has to be set if using social auth options # Application URL
# or if you are not using BookStack at the root path of your domain. # Remove the hash below and set a URL if using BookStack behind
# APP_URL=http://bookstack.dev # a proxy, if using a third-party authentication option.
# This must be the root URL that you want to host BookStack on.
# All URL's in BookStack will be generated using this value.
#APP_URL=https://example.com
# Database details # Database details
DB_HOST=localhost DB_HOST=localhost
@ -13,77 +16,16 @@ DB_DATABASE=database_database
DB_USERNAME=database_username DB_USERNAME=database_username
DB_PASSWORD=database_user_password DB_PASSWORD=database_user_password
# Cache and session # Mail system to use
CACHE_DRIVER=file # Can be 'smtp', 'mail' or 'sendmail'
SESSION_DRIVER=file
# If using Memcached, comment the above and uncomment these
#CACHE_DRIVER=memcached
#SESSION_DRIVER=memcached
QUEUE_DRIVER=sync
# A different prefix is useful when multiple BookStack instances use the same caching server
CACHE_PREFIX=bookstack
# Memcached settings
# If using a UNIX socket path for the host, set the port to 0
# This follows the following format: HOST:PORT:WEIGHT
# For multiple servers separate with a comma
MEMCACHED_SERVERS=127.0.0.1:11211:100
# Storage
STORAGE_TYPE=local
# Amazon S3 Config
STORAGE_S3_KEY=false
STORAGE_S3_SECRET=false
STORAGE_S3_REGION=false
STORAGE_S3_BUCKET=false
# Storage URL
# Used to prefix image urls for when using custom domains/cdns
STORAGE_URL=false
# General auth
AUTH_METHOD=standard
# Social Authentication information. Defaults as off.
GITHUB_APP_ID=false
GITHUB_APP_SECRET=false
GOOGLE_APP_ID=false
GOOGLE_APP_SECRET=false
GOOGLE_SELECT_ACCOUNT=false
OKTA_BASE_URL=false
OKTA_APP_ID=false
OKTA_APP_SECRET=false
TWITCH_APP_ID=false
TWITCH_APP_SECRET=false
GITLAB_APP_ID=false
GITLAB_APP_SECRET=false
GITLAB_BASE_URI=false
DISCORD_APP_ID=false
DISCORD_APP_SECRET=false
# External services such as Gravatar and Draw.IO
DISABLE_EXTERNAL_SERVICES=false
# LDAP Settings
LDAP_SERVER=false
LDAP_BASE_DN=false
LDAP_DN=false
LDAP_PASS=false
LDAP_USER_FILTER=false
LDAP_VERSION=false
# Do you want to sync LDAP groups to BookStack roles for a user
LDAP_USER_TO_GROUPS=false
# What is the LDAP attribute for group memberships
LDAP_GROUP_ATTRIBUTE="memberOf"
# Would you like to remove users from roles on BookStack if they do not match on LDAP
# If false, the ldap groups-roles sync will only add users to roles
LDAP_REMOVE_FROM_GROUPS=false
# Mail settings
MAIL_DRIVER=smtp MAIL_DRIVER=smtp
# SMTP mail options
MAIL_HOST=localhost MAIL_HOST=localhost
MAIL_PORT=1025 MAIL_PORT=1025
MAIL_USERNAME=null MAIL_USERNAME=null
MAIL_PASSWORD=null MAIL_PASSWORD=null
MAIL_ENCRYPTION=null MAIL_ENCRYPTION=null
MAIL_FROM=null
MAIL_FROM_NAME=null
# A full list of options can be found in the '.env.example.complete' file.

211
.env.example.complete Normal file
View File

@ -0,0 +1,211 @@
# Full list of environment variables that can be used with BookStack.
# Selectively copy these to your '.env' file as required.
# Each option is shown with it's default value.
# Do not copy this whole file to use as your '.env' file.
# Application environment
# Can be 'production', 'development', 'testing' or 'demo'
APP_ENV=production
# Enable debug mode
# Shows advanced debug information and errors.
# CAN EXPOSE OTHER VARIABLES, LEAVE DISABLED
APP_DEBUG=false
# Application key
# Used for encryption where needed.
# Run `php artisan key:generate` to generate a valid key.
APP_KEY=SomeRandomString
# Application URL
# This must be the root URL that you want to host BookStack on.
# All URL's in BookStack will be generated using this value.
APP_URL=https://example.com
# Application default language
# The default language choice to show.
# May be overridden by user-preference or visitor browser settings.
APP_LANG=en
# Auto-detect language for public visitors.
# Uses browser-sent headers to infer a language.
# APP_LANG will be used if such a header is not provided.
APP_AUTO_LANG_PUBLIC=true
# Database details
# Host can contain a port (localhost:3306) or a separate DB_PORT option can be used.
DB_HOST=localhost
DB_PORT=3306
DB_DATABASE=database_database
DB_USERNAME=database_username
DB_PASSWORD=database_user_password
# Mail system to use
# Can be 'smtp', 'mail' or 'sendmail'
MAIL_DRIVER=smtp
# Mail sending options
MAIL_FROM=mail@bookstackapp.com
MAIL_FROM_NAME=BookStack
# SMTP mail options
MAIL_HOST=localhost
MAIL_PORT=1025
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
# Cache & Session driver to use
# Can be 'file', 'database', 'memcached' or 'redis'
CACHE_DRIVER=file
SESSION_DRIVER=file
# Session configuration
SESSION_LIFETIME=120
SESSION_COOKIE_NAME=bookstack_session
SESSION_SECURE_COOKIE=false
# Cache key prefix
# Can be used to prevent conflicts multiple BookStack instances use the same store.
CACHE_PREFIX=bookstack
# Memcached server configuration
# If using a UNIX socket path for the host, set the port to 0
# This follows the following format: HOST:PORT:WEIGHT
# For multiple servers separate with a comma
MEMCACHED_SERVERS=127.0.0.1:11211:100
# Queue driver to use
# Queue not really currently used but may be configurable in the future.
# Would advise not to change this for now.
QUEUE_DRIVER=sync
# Storage system to use
# Can be 'local', 'local_secure' or 's3'
STORAGE_TYPE=local
# Amazon S3 storage configuration
STORAGE_S3_KEY=your-s3-key
STORAGE_S3_SECRET=your-s3-secret
STORAGE_S3_BUCKET=s3-bucket-name
STORAGE_S3_REGION=s3-bucket-region
# Storage URL prefix
# Used as a base for any generated image urls.
# An s3-format URL will be generated if not set.
STORAGE_URL=false
# Authentication method to use
# Can be 'standard' or 'ldap'
AUTH_METHOD=standard
# Social authentication configuration
# All disabled by default.
# Refer to https://www.bookstackapp.com/docs/admin/third-party-auth/
AZURE_APP_ID=false
AZURE_APP_SECRET=false
AZURE_TENANT=false
AZURE_AUTO_REGISTER=false
AZURE_AUTO_CONFIRM_EMAIL=false
DISCORD_APP_ID=false
DISCORD_APP_SECRET=false
DISCORD_AUTO_REGISTER=false
DISCORD_AUTO_CONFIRM_EMAIL=false
FACEBOOK_APP_ID=false
FACEBOOK_APP_SECRET=false
FACEBOOK_AUTO_REGISTER=false
FACEBOOK_AUTO_CONFIRM_EMAIL=false
GITHUB_APP_ID=false
GITHUB_APP_SECRET=false
GITHUB_AUTO_REGISTER=false
GITHUB_AUTO_CONFIRM_EMAIL=false
GITLAB_APP_ID=false
GITLAB_APP_SECRET=false
GITLAB_BASE_URI=false
GITLAB_AUTO_REGISTER=false
GITLAB_AUTO_CONFIRM_EMAIL=false
GOOGLE_APP_ID=false
GOOGLE_APP_SECRET=false
GOOGLE_SELECT_ACCOUNT=false
GOOGLE_AUTO_REGISTER=false
GOOGLE_AUTO_CONFIRM_EMAIL=false
OKTA_BASE_URL=false
OKTA_APP_ID=false
OKTA_APP_SECRET=false
OKTA_AUTO_REGISTER=false
OKTA_AUTO_CONFIRM_EMAIL=false
SLACK_APP_ID=false
SLACK_APP_SECRET=false
SLACK_AUTO_REGISTER=false
SLACK_AUTO_CONFIRM_EMAIL=false
TWITCH_APP_ID=false
TWITCH_APP_SECRET=false
TWITCH_AUTO_REGISTER=false
TWITCH_AUTO_CONFIRM_EMAIL=false
TWITTER_APP_ID=false
TWITTER_APP_SECRET=false
TWITTER_AUTO_REGISTER=false
TWITTER_AUTO_CONFIRM_EMAIL=false
# LDAP authentication configuration
# Refer to https://www.bookstackapp.com/docs/admin/ldap-auth/
LDAP_SERVER=false
LDAP_BASE_DN=false
LDAP_DN=false
LDAP_PASS=false
LDAP_USER_FILTER=false
LDAP_VERSION=false
LDAP_TLS_INSECURE=false
LDAP_EMAIL_ATTRIBUTE=mail
LDAP_FOLLOW_REFERRALS=true
# LDAP group sync configuration
# Refer to https://www.bookstackapp.com/docs/admin/ldap-auth/
LDAP_USER_TO_GROUPS=false
LDAP_GROUP_ATTRIBUTE="memberOf"
LDAP_REMOVE_FROM_GROUPS=false
# Disable default third-party services such as Gravatar and Draw.IO
# Service-specific options will override this option
DISABLE_EXTERNAL_SERVICES=false
# Use custom avatar service, Sets fetch URL
# Possible placeholders: ${hash} ${size} ${email}
# If set, Avatars will be fetched regardless of DISABLE_EXTERNAL_SERVICES option.
# Example: AVATAR_URL=https://seccdn.libravatar.org/avatar/${hash}?s=${size}&d=identicon
AVATAR_URL=
# Enable Draw.io integration
DRAWIO=true
# Default item listing view
# Used for public visitors and user's without a preference
# Can be 'list' or 'grid'
APP_VIEWS_BOOKS=list
APP_VIEWS_BOOKSHELVES=grid
# Page revision limit
# Number of page revisions to keep in the system before deleting old revisions.
# If set to 'false' a limit will not be enforced.
REVISION_LIMIT=50
# Allow <script> tags in page content
# Note, if set to 'true' the page editor may still escape scripts.
ALLOW_CONTENT_SCRIPTS=false
# Indicate if robots/crawlers should crawl your instance.
# Can be 'true', 'false' or 'null'.
# The behaviour of the default 'null' option will depend on the 'app-public' admin setting.
# Contents of the robots.txt file can be overridden, making this option obsolete.
ALLOW_ROBOTS=null

View File

@ -92,4 +92,27 @@ class Ldap
{ {
return ldap_bind($ldapConnection, $bindRdn, $bindPassword); return ldap_bind($ldapConnection, $bindRdn, $bindPassword);
} }
/**
* Explode a LDAP dn string into an array of components.
* @param string $dn
* @param int $withAttrib
* @return array
*/
public function explodeDn(string $dn, int $withAttrib)
{
return ldap_explode_dn($dn, $withAttrib);
}
/**
* Escape a string for use in an LDAP filter.
* @param string $value
* @param string $ignore
* @param int $flags
* @return string
*/
public function escape(string $value, string $ignore = "", int $flags = 0)
{
return ldap_escape($value, $ignore, $flags);
}
} }

View File

@ -107,6 +107,7 @@ class LdapService
if ($ldapUser === null) { if ($ldapUser === null) {
return false; return false;
} }
if ($ldapUser['uid'] !== $user->external_auth_id) { if ($ldapUser['uid'] !== $user->external_auth_id) {
return false; return false;
} }
@ -169,6 +170,16 @@ class LdapService
} }
$hostName = $ldapServer[0] . ($hasProtocol?':':'') . $ldapServer[1]; $hostName = $ldapServer[0] . ($hasProtocol?':':'') . $ldapServer[1];
$defaultPort = $ldapServer[0] === 'ldaps' ? 636 : 389; $defaultPort = $ldapServer[0] === 'ldaps' ? 636 : 389;
/*
* Check if TLS_INSECURE is set. The handle is set to NULL due to the nature of
* the LDAP_OPT_X_TLS_REQUIRE_CERT option. It can only be set globally and not
* per handle.
*/
if($this->config['tls_insecure']) {
$this->ldap->setOption(NULL, LDAP_OPT_X_TLS_REQUIRE_CERT, LDAP_OPT_X_TLS_NEVER);
}
$ldapConnection = $this->ldap->connect($hostName, count($ldapServer) > 2 ? intval($ldapServer[2]) : $defaultPort); $ldapConnection = $this->ldap->connect($hostName, count($ldapServer) > 2 ? intval($ldapServer[2]) : $defaultPort);
if ($ldapConnection === false) { if ($ldapConnection === false) {
@ -195,7 +206,7 @@ class LdapService
$newAttrs = []; $newAttrs = [];
foreach ($attrs as $key => $attrText) { foreach ($attrs as $key => $attrText) {
$newKey = '${' . $key . '}'; $newKey = '${' . $key . '}';
$newAttrs[$newKey] = $attrText; $newAttrs[$newKey] = $this->ldap->escape($attrText);
} }
return strtr($filterString, $newAttrs); return strtr($filterString, $newAttrs);
} }
@ -265,7 +276,8 @@ class LdapService
$baseDn = $this->config['base_dn']; $baseDn = $this->config['base_dn'];
$groupsAttr = strtolower($this->config['group_attribute']); $groupsAttr = strtolower($this->config['group_attribute']);
$groups = $this->ldap->searchAndGetEntries($ldapConnection, $baseDn, 'CN='.$groupName, [$groupsAttr]); $groupFilter = 'CN=' . $this->ldap->escape($groupName);
$groups = $this->ldap->searchAndGetEntries($ldapConnection, $baseDn, $groupFilter, [$groupsAttr]);
if ($groups['count'] === 0) { if ($groups['count'] === 0) {
return []; return [];
} }
@ -277,23 +289,26 @@ class LdapService
/** /**
* Filter out LDAP CN and DN language in a ldap search return * Filter out LDAP CN and DN language in a ldap search return
* Gets the base CN (common name) of the string * Gets the base CN (common name) of the string
* @param string $ldapSearchReturn * @param array $userGroupSearchResponse
* @return array * @return array
*/ */
protected function groupFilter($ldapSearchReturn) protected function groupFilter(array $userGroupSearchResponse)
{ {
$groupsAttr = strtolower($this->config['group_attribute']); $groupsAttr = strtolower($this->config['group_attribute']);
$ldapGroups = []; $ldapGroups = [];
$count = 0; $count = 0;
if (isset($ldapSearchReturn[$groupsAttr]['count'])) {
$count = (int) $ldapSearchReturn[$groupsAttr]['count']; if (isset($userGroupSearchResponse[$groupsAttr]['count'])) {
$count = (int) $userGroupSearchResponse[$groupsAttr]['count'];
} }
for ($i=0; $i<$count; $i++) { for ($i=0; $i<$count; $i++) {
$dnComponents = ldap_explode_dn($ldapSearchReturn[$groupsAttr][$i], 1); $dnComponents = $this->ldap->explodeDn($userGroupSearchResponse[$groupsAttr][$i], 1);
if (!in_array($dnComponents[0], $ldapGroups)) { if (!in_array($dnComponents[0], $ldapGroups)) {
$ldapGroups[] = $dnComponents[0]; $ldapGroups[] = $dnComponents[0];
} }
} }
return $ldapGroups; return $ldapGroups;
} }

View File

@ -3,6 +3,7 @@
use Activity; use Activity;
use BookStack\Entities\Repos\EntityRepo; use BookStack\Entities\Repos\EntityRepo;
use BookStack\Exceptions\NotFoundException; use BookStack\Exceptions\NotFoundException;
use BookStack\Exceptions\UserUpdateException;
use BookStack\Uploads\Image; use BookStack\Uploads\Image;
use Exception; use Exception;
use Images; use Images;
@ -42,7 +43,7 @@ class UserRepo
*/ */
public function getById($id) public function getById($id)
{ {
return $this->user->findOrFail($id); return $this->user->newQuery()->findOrFail($id);
} }
/** /**
@ -85,9 +86,7 @@ class UserRepo
{ {
$user = $this->create($data, $verifyEmail); $user = $this->create($data, $verifyEmail);
$this->attachDefaultRole($user); $this->attachDefaultRole($user);
$this->downloadAndAssignUserAvatar($user);
// Get avatar from gravatar and save
$this->downloadGravatarToUserAvatar($user);
return $user; return $user;
} }
@ -137,6 +136,40 @@ class UserRepo
return true; return true;
} }
/**
* Set the assigned user roles via an array of role IDs.
* @param User $user
* @param array $roles
* @throws UserUpdateException
*/
public function setUserRoles(User $user, array $roles)
{
if ($this->demotingLastAdmin($user, $roles)) {
throw new UserUpdateException(trans('errors.role_cannot_remove_only_admin'), $user->getEditUrl());
}
$user->roles()->sync($roles);
}
/**
* Check if the given user is the last admin and their new roles no longer
* contains the admin role.
* @param User $user
* @param array $newRoles
* @return bool
*/
protected function demotingLastAdmin(User $user, array $newRoles) : bool
{
if ($this->isOnlyAdmin($user)) {
$adminRole = $this->role->getSystemRole('admin');
if (!in_array(strval($adminRole->id), $newRoles)) {
return true;
}
}
return false;
}
/** /**
* Create a new basic instance of user. * Create a new basic instance of user.
* @param array $data * @param array $data
@ -145,7 +178,6 @@ class UserRepo
*/ */
public function create(array $data, $verifyEmail = false) public function create(array $data, $verifyEmail = false)
{ {
return $this->user->forceCreate([ return $this->user->forceCreate([
'name' => $data['name'], 'name' => $data['name'],
'email' => $data['email'], 'email' => $data['email'],
@ -238,25 +270,24 @@ class UserRepo
} }
/** /**
* Get a gravatar image for a user and set it as their avatar. * Get an avatar image for a user and set it as their avatar.
* Does not run if gravatar disabled in config. * Returns early if avatars disabled or not set in config.
* @param User $user * @param User $user
* @return bool * @return bool
*/ */
public function downloadGravatarToUserAvatar(User $user) public function downloadAndAssignUserAvatar(User $user)
{ {
// Get avatar from gravatar and save if (!Images::avatarFetchEnabled()) {
if (!config('services.gravatar')) {
return false; return false;
} }
try { try {
$avatar = Images::saveUserGravatar($user); $avatar = Images::saveUserAvatar($user);
$user->avatar()->associate($avatar); $user->avatar()->associate($avatar);
$user->save(); $user->save();
return true; return true;
} catch (Exception $e) { } catch (Exception $e) {
\Log::error('Failed to save user gravatar image'); \Log::error('Failed to save user avatar image');
return false; return false;
} }
} }

View File

@ -76,7 +76,7 @@ class CreateAdmin extends Command
$user = $this->userRepo->create(['email' => $email, 'name' => $name, 'password' => $password]); $user = $this->userRepo->create(['email' => $email, 'name' => $name, 'password' => $password]);
$this->userRepo->attachSystemRole($user, 'admin'); $this->userRepo->attachSystemRole($user, 'admin');
$this->userRepo->downloadGravatarToUserAvatar($user); $this->userRepo->downloadAndAssignUserAvatar($user);
$user->email_confirmed = true; $user->email_confirmed = true;
$user->save(); $user->save();

View File

@ -616,24 +616,48 @@ class EntityRepo
} }
/** /**
* Render the page for viewing, Parsing and performing features such as page transclusion. * Render the page for viewing
* @param Page $page * @param Page $page
* @param bool $ignorePermissions * @param bool $blankIncludes
* @return mixed|string * @return string
*/ */
public function renderPage(Page $page, $ignorePermissions = false) public function renderPage(Page $page, bool $blankIncludes = false) : string
{ {
$content = $page->html; $content = $page->html;
if (!config('app.allow_content_scripts')) { if (!config('app.allow_content_scripts')) {
$content = $this->escapeScripts($content); $content = $this->escapeScripts($content);
} }
$matches = []; if ($blankIncludes) {
preg_match_all("/{{@\s?([0-9].*?)}}/", $content, $matches); $content = $this->blankPageIncludes($content);
if (count($matches[0]) === 0) { } else {
$content = $this->parsePageIncludes($content);
}
return $content; return $content;
} }
/**
* Remove any page include tags within the given HTML.
* @param string $html
* @return string
*/
protected function blankPageIncludes(string $html) : string
{
return preg_replace("/{{@\s?([0-9].*?)}}/", '', $html);
}
/**
* Parse any include tags "{{@<page_id>#section}}" to be part of the page.
* @param string $html
* @return mixed|string
*/
protected function parsePageIncludes(string $html) : string
{
$matches = [];
preg_match_all("/{{@\s?([0-9].*?)}}/", $html, $matches);
$topLevelTags = ['table', 'ul', 'ol']; $topLevelTags = ['table', 'ul', 'ol'];
foreach ($matches[1] as $index => $includeId) { foreach ($matches[1] as $index => $includeId) {
$splitInclude = explode('#', $includeId, 2); $splitInclude = explode('#', $includeId, 2);
@ -642,14 +666,14 @@ class EntityRepo
continue; continue;
} }
$matchedPage = $this->getById('page', $pageId, false, $ignorePermissions); $matchedPage = $this->getById('page', $pageId);
if ($matchedPage === null) { if ($matchedPage === null) {
$content = str_replace($matches[0][$index], '', $content); $html = str_replace($matches[0][$index], '', $html);
continue; continue;
} }
if (count($splitInclude) === 1) { if (count($splitInclude) === 1) {
$content = str_replace($matches[0][$index], $matchedPage->html, $content); $html = str_replace($matches[0][$index], $matchedPage->html, $html);
continue; continue;
} }
@ -657,7 +681,7 @@ class EntityRepo
$doc->loadHTML(mb_convert_encoding('<body>'.$matchedPage->html.'</body>', 'HTML-ENTITIES', 'UTF-8')); $doc->loadHTML(mb_convert_encoding('<body>'.$matchedPage->html.'</body>', 'HTML-ENTITIES', 'UTF-8'));
$matchingElem = $doc->getElementById($splitInclude[1]); $matchingElem = $doc->getElementById($splitInclude[1]);
if ($matchingElem === null) { if ($matchingElem === null) {
$content = str_replace($matches[0][$index], '', $content); $html = str_replace($matches[0][$index], '', $html);
continue; continue;
} }
$innerContent = ''; $innerContent = '';
@ -669,25 +693,22 @@ class EntityRepo
$innerContent .= $doc->saveHTML($childNode); $innerContent .= $doc->saveHTML($childNode);
} }
} }
$content = str_replace($matches[0][$index], trim($innerContent), $content); $html = str_replace($matches[0][$index], trim($innerContent), $html);
} }
return $content; return $html;
} }
/** /**
* Escape script tags within HTML content. * Escape script tags within HTML content.
* @param string $html * @param string $html
* @return mixed * @return string
*/ */
protected function escapeScripts(string $html) protected function escapeScripts(string $html) : string
{ {
$scriptSearchRegex = '/<script.*?>.*?<\/script>/ms'; $scriptSearchRegex = '/<script.*?>.*?<\/script>/ms';
$matches = []; $matches = [];
preg_match_all($scriptSearchRegex, $html, $matches); preg_match_all($scriptSearchRegex, $html, $matches);
if (count($matches) === 0) {
return $html;
}
foreach ($matches[0] as $match) { foreach ($matches[0] as $match) {
$html = str_replace($match, htmlentities($match), $html); $html = str_replace($match, htmlentities($match), $html);

View File

@ -194,9 +194,9 @@ class PageRepo extends EntityRepo
* @param \BookStack\Entities\Page $page * @param \BookStack\Entities\Page $page
* @return string * @return string
*/ */
public function pageToPlainText(Page $page) protected function pageToPlainText(Page $page) : string
{ {
$html = $this->renderPage($page); $html = $this->renderPage($page, true);
return strip_tags($html); return strip_tags($html);
} }

View File

@ -0,0 +1,5 @@
<?php namespace BookStack\Exceptions;
use Exception;
class HttpFetchException extends Exception {}

View File

@ -11,7 +11,7 @@ class NotifyException extends \Exception
* @param string $message * @param string $message
* @param string $redirectLocation * @param string $redirectLocation
*/ */
public function __construct($message, $redirectLocation) public function __construct(string $message, string $redirectLocation = "/")
{ {
$this->message = $message; $this->message = $message;
$this->redirectLocation = $redirectLocation; $this->redirectLocation = $redirectLocation;

View File

@ -0,0 +1,3 @@
<?php namespace BookStack\Exceptions;
class UserUpdateException extends NotifyException {}

View File

@ -161,6 +161,7 @@ class ChapterController extends Controller
$chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug); $chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug);
$this->setPageTitle(trans('entities.chapters_move_named', ['chapterName' => $chapter->getShortName()])); $this->setPageTitle(trans('entities.chapters_move_named', ['chapterName' => $chapter->getShortName()]));
$this->checkOwnablePermission('chapter-update', $chapter); $this->checkOwnablePermission('chapter-update', $chapter);
$this->checkOwnablePermission('chapter-delete', $chapter);
return view('chapters/move', [ return view('chapters/move', [
'chapter' => $chapter, 'chapter' => $chapter,
'book' => $chapter->book 'book' => $chapter->book
@ -179,6 +180,7 @@ class ChapterController extends Controller
{ {
$chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug); $chapter = $this->entityRepo->getBySlug('chapter', $chapterSlug, $bookSlug);
$this->checkOwnablePermission('chapter-update', $chapter); $this->checkOwnablePermission('chapter-update', $chapter);
$this->checkOwnablePermission('chapter-delete', $chapter);
$entitySelection = $request->get('entity_selection', null); $entitySelection = $request->get('entity_selection', null);
if ($entitySelection === null || $entitySelection === '') { if ($entitySelection === null || $entitySelection === '') {

View File

@ -79,6 +79,7 @@ class HomeController extends Controller
{ {
$locale = app()->getLocale(); $locale = app()->getLocale();
$cacheKey = 'GLOBAL_TRANSLATIONS_' . $locale; $cacheKey = 'GLOBAL_TRANSLATIONS_' . $locale;
if (cache()->has($cacheKey) && config('app.env') !== 'development') { if (cache()->has($cacheKey) && config('app.env') !== 'development') {
$resp = cache($cacheKey); $resp = cache($cacheKey);
} else { } else {
@ -89,15 +90,6 @@ class HomeController extends Controller
'entities' => trans('entities'), 'entities' => trans('entities'),
'errors' => trans('errors') 'errors' => trans('errors')
]; ];
if ($locale !== 'en') {
$enTrans = [
'common' => trans('common', [], 'en'),
'components' => trans('components', [], 'en'),
'entities' => trans('entities', [], 'en'),
'errors' => trans('errors', [], 'en')
];
$translations = array_replace_recursive($enTrans, $translations);
}
$resp = 'window.translations = ' . json_encode($translations); $resp = 'window.translations = ' . json_encode($translations);
cache()->put($cacheKey, $resp, 120); cache()->put($cacheKey, $resp, 120);
} }

View File

@ -586,6 +586,7 @@ class PageController extends Controller
{ {
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug); $page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
$this->checkOwnablePermission('page-update', $page); $this->checkOwnablePermission('page-update', $page);
$this->checkOwnablePermission('page-delete', $page);
return view('pages/move', [ return view('pages/move', [
'book' => $page->book, 'book' => $page->book,
'page' => $page 'page' => $page
@ -604,6 +605,7 @@ class PageController extends Controller
{ {
$page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug); $page = $this->pageRepo->getPageBySlug($pageSlug, $bookSlug);
$this->checkOwnablePermission('page-update', $page); $this->checkOwnablePermission('page-update', $page);
$this->checkOwnablePermission('page-delete', $page);
$entitySelection = $request->get('entity_selection', null); $entitySelection = $request->get('entity_selection', null);
if ($entitySelection === null || $entitySelection === '') { if ($entitySelection === null || $entitySelection === '') {

View File

@ -3,6 +3,7 @@
use BookStack\Auth\Access\SocialAuthService; use BookStack\Auth\Access\SocialAuthService;
use BookStack\Auth\User; use BookStack\Auth\User;
use BookStack\Auth\UserRepo; use BookStack\Auth\UserRepo;
use BookStack\Exceptions\UserUpdateException;
use Illuminate\Http\Request; use Illuminate\Http\Request;
use Illuminate\Http\Response; use Illuminate\Http\Response;
@ -15,7 +16,7 @@ class UserController extends Controller
/** /**
* UserController constructor. * UserController constructor.
* @param User $user * @param User $user
* @param \BookStack\Auth\UserRepo $userRepo * @param UserRepo $userRepo
*/ */
public function __construct(User $user, UserRepo $userRepo) public function __construct(User $user, UserRepo $userRepo)
{ {
@ -59,6 +60,7 @@ class UserController extends Controller
* Store a newly created user in storage. * Store a newly created user in storage.
* @param Request $request * @param Request $request
* @return Response * @return Response
* @throws UserUpdateException
*/ */
public function store(Request $request) public function store(Request $request)
{ {
@ -89,10 +91,10 @@ class UserController extends Controller
if ($request->filled('roles')) { if ($request->filled('roles')) {
$roles = $request->get('roles'); $roles = $request->get('roles');
$user->roles()->sync($roles); $this->userRepo->setUserRoles($user, $roles);
} }
$this->userRepo->downloadGravatarToUserAvatar($user); $this->userRepo->downloadAndAssignUserAvatar($user);
return redirect('/settings/users'); return redirect('/settings/users');
} }
@ -124,6 +126,7 @@ class UserController extends Controller
* @param Request $request * @param Request $request
* @param int $id * @param int $id
* @return Response * @return Response
* @throws UserUpdateException
*/ */
public function update(Request $request, $id) public function update(Request $request, $id)
{ {
@ -140,13 +143,13 @@ class UserController extends Controller
'setting' => 'array' 'setting' => 'array'
]); ]);
$user = $this->user->findOrFail($id); $user = $this->userRepo->getById($id);
$user->fill($request->all()); $user->fill($request->all());
// Role updates // Role updates
if (userCan('users-manage') && $request->filled('roles')) { if (userCan('users-manage') && $request->filled('roles')) {
$roles = $request->get('roles'); $roles = $request->get('roles');
$user->roles()->sync($roles); $this->userRepo->setUserRoles($user, $roles);
} }
// Password updates // Password updates
@ -185,7 +188,7 @@ class UserController extends Controller
return $this->currentUser->id == $id; return $this->currentUser->id == $id;
}); });
$user = $this->user->findOrFail($id); $user = $this->userRepo->getById($id);
$this->setPageTitle(trans('settings.users_delete_named', ['userName' => $user->name])); $this->setPageTitle(trans('settings.users_delete_named', ['userName' => $user->name]));
return view('users/delete', ['user' => $user]); return view('users/delete', ['user' => $user]);
} }
@ -194,6 +197,7 @@ class UserController extends Controller
* Remove the specified user from storage. * Remove the specified user from storage.
* @param int $id * @param int $id
* @return Response * @return Response
* @throws \Exception
*/ */
public function destroy($id) public function destroy($id)
{ {
@ -277,7 +281,7 @@ class UserController extends Controller
$viewType = 'list'; $viewType = 'list';
} }
$user = $this->user->findOrFail($userId); $user = $this->userRepo->getById($id);
$key = $listName . '_view_type'; $key = $listName . '_view_type';
setting()->putUser($user, $key, $viewType); setting()->putUser($user, $key, $viewType);

View File

@ -1,17 +1,7 @@
<?php <?php namespace BookStack\Notifications;
namespace BookStack\Notifications; class ConfirmEmail extends MailNotification
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class ConfirmEmail extends Notification implements ShouldQueue
{ {
use Queueable;
public $token; public $token;
/** /**
@ -23,17 +13,6 @@ class ConfirmEmail extends Notification implements ShouldQueue
$this->token = $token; $this->token = $token;
} }
/**
* Get the notification's delivery channels.
*
* @param mixed $notifiable
* @return array
*/
public function via($notifiable)
{
return ['mail'];
}
/** /**
* Get the mail representation of the notification. * Get the mail representation of the notification.
* *
@ -43,7 +22,7 @@ class ConfirmEmail extends Notification implements ShouldQueue
public function toMail($notifiable) public function toMail($notifiable)
{ {
$appName = ['appName' => setting('app-name')]; $appName = ['appName' => setting('app-name')];
return (new MailMessage) return $this->newMailMessage()
->subject(trans('auth.email_confirm_subject', $appName)) ->subject(trans('auth.email_confirm_subject', $appName))
->greeting(trans('auth.email_confirm_greeting', $appName)) ->greeting(trans('auth.email_confirm_greeting', $appName))
->line(trans('auth.email_confirm_text')) ->line(trans('auth.email_confirm_text'))

View File

@ -0,0 +1,35 @@
<?php namespace BookStack\Notifications;
use Illuminate\Bus\Queueable;
use Illuminate\Contracts\Queue\ShouldQueue;
use Illuminate\Notifications\Messages\MailMessage;
use Illuminate\Notifications\Notification;
class MailNotification extends Notification implements ShouldQueue
{
use Queueable;
/**
* Get the notification's channels.
*
* @param mixed $notifiable
* @return array|string
*/
public function via($notifiable)
{
return ['mail'];
}
/**
* Create a new mail message.
* @return MailMessage
*/
protected function newMailMessage()
{
return (new MailMessage)->view([
'html' => 'vendor.notifications.email',
'text' => 'vendor.notifications.email-plain'
]);
}
}

View File

@ -1,11 +1,7 @@
<?php <?php namespace BookStack\Notifications;
namespace BookStack\Notifications;
use Illuminate\Notifications\Messages\MailMessage; class ResetPassword extends MailNotification
use Illuminate\Notifications\Notification;
class ResetPassword extends Notification
{ {
/** /**
* The password reset token. * The password reset token.
@ -24,17 +20,6 @@ class ResetPassword extends Notification
$this->token = $token; $this->token = $token;
} }
/**
* Get the notification's channels.
*
* @param mixed $notifiable
* @return array|string
*/
public function via($notifiable)
{
return ['mail'];
}
/** /**
* Build the mail representation of the notification. * Build the mail representation of the notification.
* *
@ -42,7 +27,7 @@ class ResetPassword extends Notification
*/ */
public function toMail() public function toMail()
{ {
return (new MailMessage) return $this->newMailMessage()
->subject(trans('auth.email_reset_subject', ['appName' => setting('app-name')])) ->subject(trans('auth.email_reset_subject', ['appName' => setting('app-name')]))
->line(trans('auth.email_reset_text')) ->line(trans('auth.email_reset_text'))
->action(trans('auth.reset_password'), baseUrl('password/reset/' . $this->token)) ->action(trans('auth.reset_password'), baseUrl('password/reset/' . $this->token))

View File

@ -9,6 +9,7 @@ use BookStack\Actions\ViewService;
use BookStack\Auth\Permissions\PermissionService; use BookStack\Auth\Permissions\PermissionService;
use BookStack\Settings\Setting; use BookStack\Settings\Setting;
use BookStack\Settings\SettingService; use BookStack\Settings\SettingService;
use BookStack\Uploads\HttpFetcher;
use BookStack\Uploads\Image; use BookStack\Uploads\Image;
use BookStack\Uploads\ImageService; use BookStack\Uploads\ImageService;
use Illuminate\Contracts\Cache\Repository; use Illuminate\Contracts\Cache\Repository;
@ -61,7 +62,8 @@ class CustomFacadeProvider extends ServiceProvider
$this->app->make(Image::class), $this->app->make(Image::class),
$this->app->make(ImageManager::class), $this->app->make(ImageManager::class),
$this->app->make(Factory::class), $this->app->make(Factory::class),
$this->app->make(Repository::class) $this->app->make(Repository::class),
$this->app->make(HttpFetcher::class)
); );
}); });
} }

View File

@ -0,0 +1,32 @@
<?php namespace BookStack\Providers;
use BookStack\Translation\Translator;
class TranslationServiceProvider extends \Illuminate\Translation\TranslationServiceProvider
{
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->registerLoader();
$this->app->singleton('translator', function ($app) {
$loader = $app['translation.loader'];
// When registering the translator component, we'll need to set the default
// locale as well as the fallback locale. So, we'll grab the application
// configuration so we can easily get both of these values from there.
$locale = $app['config']['app.locale'];
$trans = new Translator($loader, $locale);
$trans->setFallback($app['config']['app.fallback_locale']);
return $trans;
});
}
}

View File

@ -0,0 +1,74 @@
<?php namespace BookStack\Translation;
class Translator extends \Illuminate\Translation\Translator
{
/**
* Mapping of locales to their base locales
* @var array
*/
protected $baseLocaleMap = [
'de_informal' => 'de',
];
/**
* Get the translation for a given key.
*
* @param string $key
* @param array $replace
* @param string $locale
* @return string|array|null
*/
public function trans($key, array $replace = [], $locale = null)
{
$translation = $this->get($key, $replace, $locale);
if (is_array($translation)) {
$translation = $this->mergeBackupTranslations($translation, $key, $locale);
}
return $translation;
}
/**
* Merge the fallback translations, and base translations if existing,
* into the provided core key => value array of translations content.
* @param array $translationArray
* @param string $key
* @param null $locale
* @return array
*/
protected function mergeBackupTranslations(array $translationArray, string $key, $locale = null)
{
$fallback = $this->get($key, [], $this->fallback);
$baseLocale = $this->getBaseLocale($locale ?? $this->locale);
$baseTranslations = $baseLocale ? $this->get($key, [], $baseLocale) : [];
return array_replace_recursive($fallback, $baseTranslations, $translationArray);
}
/**
* Get the array of locales to be checked.
*
* @param string|null $locale
* @return array
*/
protected function localeArray($locale)
{
$primaryLocale = $locale ?: $this->locale;
return array_filter([$primaryLocale, $this->getBaseLocale($primaryLocale), $this->fallback]);
}
/**
* Get the locale to extend for the given locale.
*
* @param string $locale
* @return string|null
*/
protected function getBaseLocale($locale)
{
return $this->baseLocaleMap[$locale] ?? null;
}
}

View File

@ -0,0 +1,34 @@
<?php namespace BookStack\Uploads;
use BookStack\Exceptions\HttpFetchException;
class HttpFetcher
{
/**
* Fetch content from an external URI.
* @param string $uri
* @return bool|string
* @throws HttpFetchException
*/
public function fetch(string $uri)
{
$ch = curl_init();
curl_setopt_array($ch, [
CURLOPT_URL => $uri,
CURLOPT_RETURNTRANSFER => 1,
CURLOPT_CONNECTTIMEOUT => 5
]);
$data = curl_exec($ch);
$err = curl_error($ch);
curl_close($ch);
if ($err) {
throw new HttpFetchException($err);
}
return $data;
}
}

View File

@ -1,6 +1,7 @@
<?php namespace BookStack\Uploads; <?php namespace BookStack\Uploads;
use BookStack\Auth\User; use BookStack\Auth\User;
use BookStack\Exceptions\HttpFetchException;
use BookStack\Exceptions\ImageUploadException; use BookStack\Exceptions\ImageUploadException;
use DB; use DB;
use Exception; use Exception;
@ -17,6 +18,7 @@ class ImageService extends UploadService
protected $cache; protected $cache;
protected $storageUrl; protected $storageUrl;
protected $image; protected $image;
protected $http;
/** /**
* ImageService constructor. * ImageService constructor.
@ -24,12 +26,14 @@ class ImageService extends UploadService
* @param ImageManager $imageTool * @param ImageManager $imageTool
* @param FileSystem $fileSystem * @param FileSystem $fileSystem
* @param Cache $cache * @param Cache $cache
* @param HttpFetcher $http
*/ */
public function __construct(Image $image, ImageManager $imageTool, FileSystem $fileSystem, Cache $cache) public function __construct(Image $image, ImageManager $imageTool, FileSystem $fileSystem, Cache $cache, HttpFetcher $http)
{ {
$this->image = $image; $this->image = $image;
$this->imageTool = $imageTool; $this->imageTool = $imageTool;
$this->cache = $cache; $this->cache = $cache;
$this->http = $http;
parent::__construct($fileSystem); parent::__construct($fileSystem);
} }
@ -95,8 +99,9 @@ class ImageService extends UploadService
private function saveNewFromUrl($url, $type, $imageName = false) private function saveNewFromUrl($url, $type, $imageName = false)
{ {
$imageName = $imageName ? $imageName : basename($url); $imageName = $imageName ? $imageName : basename($url);
$imageData = file_get_contents($url); try {
if ($imageData === false) { $imageData = $this->http->fetch($url);
} catch (HttpFetchException $exception) {
throw new \Exception(trans('errors.cannot_get_image_from_url', ['url' => $url])); throw new \Exception(trans('errors.cannot_get_image_from_url', ['url' => $url]));
} }
return $this->saveNew($imageName, $imageData, $type); return $this->saveNew($imageName, $imageData, $type);
@ -279,24 +284,57 @@ class ImageService extends UploadService
} }
/** /**
* Save a gravatar image and set a the profile image for a user. * Save an avatar image from an external service.
* @param \BookStack\Auth\User $user * @param \BookStack\Auth\User $user
* @param int $size * @param int $size
* @return mixed * @return Image
* @throws Exception * @throws Exception
*/ */
public function saveUserGravatar(User $user, $size = 500) public function saveUserAvatar(User $user, $size = 500)
{ {
$emailHash = md5(strtolower(trim($user->email))); $avatarUrl = $this->getAvatarUrl();
$url = 'https://www.gravatar.com/avatar/' . $emailHash . '?s=' . $size . '&d=identicon'; $email = strtolower(trim($user->email));
$imageName = str_replace(' ', '-', $user->name . '-gravatar.png');
$image = $this->saveNewFromUrl($url, 'user', $imageName); $replacements = [
'${hash}' => md5($email),
'${size}' => $size,
'${email}' => urlencode($email),
];
$userAvatarUrl = strtr($avatarUrl, $replacements);
$imageName = str_replace(' ', '-', $user->name . '-avatar.png');
$image = $this->saveNewFromUrl($userAvatarUrl, 'user', $imageName);
$image->created_by = $user->id; $image->created_by = $user->id;
$image->updated_by = $user->id; $image->updated_by = $user->id;
$image->save(); $image->save();
return $image; return $image;
} }
/**
* Check if fetching external avatars is enabled.
* @return bool
*/
public function avatarFetchEnabled()
{
$fetchUrl = $this->getAvatarUrl();
return is_string($fetchUrl) && strpos($fetchUrl, 'http') === 0;
}
/**
* Get the URL to fetch avatars from.
* @return string|mixed
*/
protected function getAvatarUrl()
{
$url = trim(config('services.avatar_url'));
if (empty($url) && !config('services.disable_services')) {
$url = 'https://www.gravatar.com/avatar/${hash}?s=${size}&d=identicon';
}
return $url;
}
/** /**
* Delete gallery and drawings that are not within HTML content of pages or page revisions. * Delete gallery and drawings that are not within HTML content of pages or page revisions.
@ -365,14 +403,7 @@ class ImageService extends UploadService
} }
} else { } else {
try { try {
$ch = curl_init(); $imageData = $this->http->fetch($uri);
curl_setopt_array($ch, [CURLOPT_URL => $uri, CURLOPT_RETURNTRANSFER => 1, CURLOPT_CONNECTTIMEOUT => 5]);
$imageData = curl_exec($ch);
$err = curl_error($ch);
curl_close($ch);
if ($err) {
throw new \Exception("Image fetch failed, Received error: " . $err);
}
} catch (\Exception $e) { } catch (\Exception $e) {
} }
} }

View File

@ -5,9 +5,14 @@
"license": "MIT", "license": "MIT",
"type": "project", "type": "project",
"require": { "require": {
"php": ">=7.0.0", "php": ">=7.0.5",
"ext-json": "*",
"ext-tidy": "*", "ext-tidy": "*",
"ext-dom": "*", "ext-dom": "*",
"ext-xml": "*",
"ext-mbstring": "*",
"ext-gd": "*",
"ext-curl": "*",
"laravel/framework": "~5.5.44", "laravel/framework": "~5.5.44",
"fideloper/proxy": "~3.3", "fideloper/proxy": "~3.3",
"intervention/image": "^2.4", "intervention/image": "^2.4",
@ -82,7 +87,7 @@
"optimize-autoloader": true, "optimize-autoloader": true,
"preferred-install": "dist", "preferred-install": "dist",
"platform": { "platform": {
"php": "7.0" "php": "7.0.5"
} }
} }
} }

217
composer.lock generated
View File

@ -4,20 +4,20 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file", "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#composer-lock-the-lock-file",
"This file is @generated automatically" "This file is @generated automatically"
], ],
"content-hash": "4a15ede09baa575d7accd7a4f66067fd", "content-hash": "06219a5c2419ca23ec2924eb31f4ed16",
"packages": [ "packages": [
{ {
"name": "aws/aws-sdk-php", "name": "aws/aws-sdk-php",
"version": "3.70.3", "version": "3.82.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/aws/aws-sdk-php.git", "url": "https://github.com/aws/aws-sdk-php.git",
"reference": "8278052a097a4ebe2b798fab7e2e3c907bc01a47" "reference": "a0353c24b18d2ba0f5bb7ca8a478b4ce0b8153f7"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/8278052a097a4ebe2b798fab7e2e3c907bc01a47", "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/a0353c24b18d2ba0f5bb7ca8a478b4ce0b8153f7",
"reference": "8278052a097a4ebe2b798fab7e2e3c907bc01a47", "reference": "a0353c24b18d2ba0f5bb7ca8a478b4ce0b8153f7",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -87,7 +87,7 @@
"s3", "s3",
"sdk" "sdk"
], ],
"time": "2018-11-02T20:04:36+00:00" "time": "2018-12-21T22:21:50+00:00"
}, },
{ {
"name": "barryvdh/laravel-dompdf", "name": "barryvdh/laravel-dompdf",
@ -729,30 +729,34 @@
}, },
{ {
"name": "dompdf/dompdf", "name": "dompdf/dompdf",
"version": "v0.8.2", "version": "v0.8.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/dompdf/dompdf.git", "url": "https://github.com/dompdf/dompdf.git",
"reference": "5113accd9ae5d466077cce5208dcf3fb871bf8f6" "reference": "75f13c700009be21a1965dc2c5b68a8708c22ba2"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/dompdf/dompdf/zipball/5113accd9ae5d466077cce5208dcf3fb871bf8f6", "url": "https://api.github.com/repos/dompdf/dompdf/zipball/75f13c700009be21a1965dc2c5b68a8708c22ba2",
"reference": "5113accd9ae5d466077cce5208dcf3fb871bf8f6", "reference": "75f13c700009be21a1965dc2c5b68a8708c22ba2",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"ext-dom": "*", "ext-dom": "*",
"ext-gd": "*",
"ext-mbstring": "*", "ext-mbstring": "*",
"phenx/php-font-lib": "0.5.*", "phenx/php-font-lib": "0.5.*",
"phenx/php-svg-lib": "0.3.*", "phenx/php-svg-lib": "0.3.*",
"php": ">=5.4.0" "php": ">=5.4.0"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "4.8.*", "phpunit/phpunit": "^4.8|^5.5|^6.5",
"squizlabs/php_codesniffer": "2.*" "squizlabs/php_codesniffer": "2.*"
}, },
"suggest": {
"ext-gd": "Needed to process images",
"ext-gmagick": "Improves image processing performance",
"ext-imagick": "Improves image processing performance"
},
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
@ -787,20 +791,20 @@
], ],
"description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter", "description": "DOMPDF is a CSS 2.1 compliant HTML to PDF converter",
"homepage": "https://github.com/dompdf/dompdf", "homepage": "https://github.com/dompdf/dompdf",
"time": "2017-11-26T14:49:08+00:00" "time": "2018-12-14T02:40:31+00:00"
}, },
{ {
"name": "egulias/email-validator", "name": "egulias/email-validator",
"version": "2.1.6", "version": "2.1.7",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/egulias/EmailValidator.git", "url": "https://github.com/egulias/EmailValidator.git",
"reference": "0578b32b30b22de3e8664f797cf846fc9246f786" "reference": "709f21f92707308cdf8f9bcfa1af4cb26586521e"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/egulias/EmailValidator/zipball/0578b32b30b22de3e8664f797cf846fc9246f786", "url": "https://api.github.com/repos/egulias/EmailValidator/zipball/709f21f92707308cdf8f9bcfa1af4cb26586521e",
"reference": "0578b32b30b22de3e8664f797cf846fc9246f786", "reference": "709f21f92707308cdf8f9bcfa1af4cb26586521e",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -844,7 +848,7 @@
"validation", "validation",
"validator" "validator"
], ],
"time": "2018-09-25T20:47:26+00:00" "time": "2018-12-04T22:38:24+00:00"
}, },
{ {
"name": "erusev/parsedown", "name": "erusev/parsedown",
@ -1116,32 +1120,33 @@
}, },
{ {
"name": "guzzlehttp/psr7", "name": "guzzlehttp/psr7",
"version": "1.4.2", "version": "1.5.2",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/guzzle/psr7.git", "url": "https://github.com/guzzle/psr7.git",
"reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c" "reference": "9f83dded91781a01c63574e387eaa769be769115"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/guzzle/psr7/zipball/f5b8a8512e2b58b0071a7280e39f14f72e05d87c", "url": "https://api.github.com/repos/guzzle/psr7/zipball/9f83dded91781a01c63574e387eaa769be769115",
"reference": "f5b8a8512e2b58b0071a7280e39f14f72e05d87c", "reference": "9f83dded91781a01c63574e387eaa769be769115",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"php": ">=5.4.0", "php": ">=5.4.0",
"psr/http-message": "~1.0" "psr/http-message": "~1.0",
"ralouphie/getallheaders": "^2.0.5"
}, },
"provide": { "provide": {
"psr/http-message-implementation": "1.0" "psr/http-message-implementation": "1.0"
}, },
"require-dev": { "require-dev": {
"phpunit/phpunit": "~4.0" "phpunit/phpunit": "~4.8.36 || ^5.7.27 || ^6.5.8"
}, },
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.4-dev" "dev-master": "1.5-dev"
} }
}, },
"autoload": { "autoload": {
@ -1171,13 +1176,14 @@
"keywords": [ "keywords": [
"http", "http",
"message", "message",
"psr-7",
"request", "request",
"response", "response",
"stream", "stream",
"uri", "uri",
"url" "url"
], ],
"time": "2017-03-20T17:10:46+00:00" "time": "2018-12-04T20:46:45+00:00"
}, },
{ {
"name": "intervention/image", "name": "intervention/image",
@ -1514,16 +1520,16 @@
}, },
{ {
"name": "league/flysystem", "name": "league/flysystem",
"version": "1.0.48", "version": "1.0.49",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/thephpleague/flysystem.git", "url": "https://github.com/thephpleague/flysystem.git",
"reference": "a6ded5b2f6055e2db97b4b859fdfca2b952b78aa" "reference": "a63cc83d8a931b271be45148fa39ba7156782ffd"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/thephpleague/flysystem/zipball/a6ded5b2f6055e2db97b4b859fdfca2b952b78aa", "url": "https://api.github.com/repos/thephpleague/flysystem/zipball/a63cc83d8a931b271be45148fa39ba7156782ffd",
"reference": "a6ded5b2f6055e2db97b4b859fdfca2b952b78aa", "reference": "a63cc83d8a931b271be45148fa39ba7156782ffd",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1594,7 +1600,7 @@
"sftp", "sftp",
"storage" "storage"
], ],
"time": "2018-10-15T13:53:10+00:00" "time": "2018-11-23T23:41:29+00:00"
}, },
{ {
"name": "league/flysystem-aws-s3-v3", "name": "league/flysystem-aws-s3-v3",
@ -1708,16 +1714,16 @@
}, },
{ {
"name": "monolog/monolog", "name": "monolog/monolog",
"version": "1.23.0", "version": "1.24.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/Seldaek/monolog.git", "url": "https://github.com/Seldaek/monolog.git",
"reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4" "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/Seldaek/monolog/zipball/fd8c787753b3a2ad11bc60c063cff1358a32a3b4", "url": "https://api.github.com/repos/Seldaek/monolog/zipball/bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266",
"reference": "fd8c787753b3a2ad11bc60c063cff1358a32a3b4", "reference": "bfc9ebb28f97e7a24c45bdc3f0ff482e47bb0266",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1782,7 +1788,7 @@
"logging", "logging",
"psr-3" "psr-3"
], ],
"time": "2017-06-19T01:22:40+00:00" "time": "2018-11-05T09:00:11+00:00"
}, },
{ {
"name": "mtdowling/cron-expression", "name": "mtdowling/cron-expression",
@ -1885,16 +1891,16 @@
}, },
{ {
"name": "nesbot/carbon", "name": "nesbot/carbon",
"version": "1.34.0", "version": "1.36.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/briannesbitt/Carbon.git", "url": "https://github.com/briannesbitt/Carbon.git",
"reference": "1dbd3cb01c5645f3e7deda7aa46ef780d95fcc33" "reference": "63da8cdf89d7a5efe43aabc794365f6e7b7b8983"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/1dbd3cb01c5645f3e7deda7aa46ef780d95fcc33", "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/63da8cdf89d7a5efe43aabc794365f6e7b7b8983",
"reference": "1dbd3cb01c5645f3e7deda7aa46ef780d95fcc33", "reference": "63da8cdf89d7a5efe43aabc794365f6e7b7b8983",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -1902,9 +1908,12 @@
"symfony/translation": "~2.6 || ~3.0 || ~4.0" "symfony/translation": "~2.6 || ~3.0 || ~4.0"
}, },
"require-dev": { "require-dev": {
"friendsofphp/php-cs-fixer": "~2",
"phpunit/phpunit": "^4.8.35 || ^5.7" "phpunit/phpunit": "^4.8.35 || ^5.7"
}, },
"suggest": {
"friendsofphp/php-cs-fixer": "Needed for the `composer phpcs` command. Allow to automatically fix code style.",
"phpstan/phpstan": "Needed for the `composer phpstan` command. Allow to detect potential errors."
},
"type": "library", "type": "library",
"extra": { "extra": {
"laravel": { "laravel": {
@ -1936,7 +1945,7 @@
"datetime", "datetime",
"time" "time"
], ],
"time": "2018-09-20T19:36:25+00:00" "time": "2018-11-22T18:23:02+00:00"
}, },
{ {
"name": "paragonie/random_compat", "name": "paragonie/random_compat",
@ -2211,16 +2220,16 @@
}, },
{ {
"name": "psr/log", "name": "psr/log",
"version": "1.0.2", "version": "1.1.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/php-fig/log.git", "url": "https://github.com/php-fig/log.git",
"reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d" "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/php-fig/log/zipball/4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", "url": "https://api.github.com/repos/php-fig/log/zipball/6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
"reference": "4ebe3a8bf773a19edfe0a84b6585ba3d401b724d", "reference": "6c001f1daafa3a3ac1d8ff69ee4db8e799a654dd",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -2254,7 +2263,7 @@
"psr", "psr",
"psr-3" "psr-3"
], ],
"time": "2016-10-10T12:19:37+00:00" "time": "2018-11-20T15:27:04+00:00"
}, },
{ {
"name": "psr/simple-cache", "name": "psr/simple-cache",
@ -2304,6 +2313,46 @@
], ],
"time": "2017-10-23T01:57:42+00:00" "time": "2017-10-23T01:57:42+00:00"
}, },
{
"name": "ralouphie/getallheaders",
"version": "2.0.5",
"source": {
"type": "git",
"url": "https://github.com/ralouphie/getallheaders.git",
"reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/ralouphie/getallheaders/zipball/5601c8a83fbba7ef674a7369456d12f1e0d0eafa",
"reference": "5601c8a83fbba7ef674a7369456d12f1e0d0eafa",
"shasum": ""
},
"require": {
"php": ">=5.3"
},
"require-dev": {
"phpunit/phpunit": "~3.7.0",
"satooshi/php-coveralls": ">=1.0"
},
"type": "library",
"autoload": {
"files": [
"src/getallheaders.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Ralph Khattar",
"email": "ralph.khattar@gmail.com"
}
],
"description": "A polyfill for getallheaders.",
"time": "2016-02-11T07:05:27+00:00"
},
{ {
"name": "ramsey/uuid", "name": "ramsey/uuid",
"version": "3.8.0", "version": "3.8.0",
@ -3667,16 +3716,16 @@
"packages-dev": [ "packages-dev": [
{ {
"name": "barryvdh/laravel-debugbar", "name": "barryvdh/laravel-debugbar",
"version": "v3.2.0", "version": "v3.2.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/barryvdh/laravel-debugbar.git", "url": "https://github.com/barryvdh/laravel-debugbar.git",
"reference": "5b68f3972083a7eeec0d6f161962fcda71a127c0" "reference": "9d5caf43c5f3a3aea2178942f281054805872e7c"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/5b68f3972083a7eeec0d6f161962fcda71a127c0", "url": "https://api.github.com/repos/barryvdh/laravel-debugbar/zipball/9d5caf43c5f3a3aea2178942f281054805872e7c",
"reference": "5b68f3972083a7eeec0d6f161962fcda71a127c0", "reference": "9d5caf43c5f3a3aea2178942f281054805872e7c",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3731,24 +3780,24 @@
"profiler", "profiler",
"webprofiler" "webprofiler"
], ],
"time": "2018-08-22T11:06:19+00:00" "time": "2018-11-09T08:37:55+00:00"
}, },
{ {
"name": "barryvdh/laravel-ide-helper", "name": "barryvdh/laravel-ide-helper",
"version": "v2.5.1", "version": "v2.5.3",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/barryvdh/laravel-ide-helper.git", "url": "https://github.com/barryvdh/laravel-ide-helper.git",
"reference": "7db1843473e1562d8e0490b51db847d3a1415140" "reference": "3d7f1240896a075aa23b13f82dfcbe165dadeef2"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/7db1843473e1562d8e0490b51db847d3a1415140", "url": "https://api.github.com/repos/barryvdh/laravel-ide-helper/zipball/3d7f1240896a075aa23b13f82dfcbe165dadeef2",
"reference": "7db1843473e1562d8e0490b51db847d3a1415140", "reference": "3d7f1240896a075aa23b13f82dfcbe165dadeef2",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
"barryvdh/reflection-docblock": "^2.0.4", "barryvdh/reflection-docblock": "^2.0.6",
"composer/composer": "^1.6", "composer/composer": "^1.6",
"illuminate/console": "^5.5,<5.8", "illuminate/console": "^5.5,<5.8",
"illuminate/filesystem": "^5.5,<5.8", "illuminate/filesystem": "^5.5,<5.8",
@ -3805,20 +3854,20 @@
"phpstorm", "phpstorm",
"sublime" "sublime"
], ],
"time": "2018-09-06T18:41:09+00:00" "time": "2018-12-19T12:12:05+00:00"
}, },
{ {
"name": "barryvdh/reflection-docblock", "name": "barryvdh/reflection-docblock",
"version": "v2.0.4", "version": "v2.0.6",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/barryvdh/ReflectionDocBlock.git", "url": "https://github.com/barryvdh/ReflectionDocBlock.git",
"reference": "3dcbd98b5d9384a5357266efba8fd29884458e5c" "reference": "6b69015d83d3daf9004a71a89f26e27d27ef6a16"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/barryvdh/ReflectionDocBlock/zipball/3dcbd98b5d9384a5357266efba8fd29884458e5c", "url": "https://api.github.com/repos/barryvdh/ReflectionDocBlock/zipball/6b69015d83d3daf9004a71a89f26e27d27ef6a16",
"reference": "3dcbd98b5d9384a5357266efba8fd29884458e5c", "reference": "6b69015d83d3daf9004a71a89f26e27d27ef6a16",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3854,7 +3903,7 @@
"email": "mike.vanriel@naenius.com" "email": "mike.vanriel@naenius.com"
} }
], ],
"time": "2016-06-13T19:28:20+00:00" "time": "2018-12-13T10:34:14+00:00"
}, },
{ {
"name": "composer/ca-bundle", "name": "composer/ca-bundle",
@ -3914,16 +3963,16 @@
}, },
{ {
"name": "composer/composer", "name": "composer/composer",
"version": "1.7.3", "version": "1.8.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/composer/composer.git", "url": "https://github.com/composer/composer.git",
"reference": "e965b9aaa8854c3067f1ed2ae45f436572d73eb7" "reference": "d8aef3af866b28786ce9b8647e52c42496436669"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/composer/composer/zipball/e965b9aaa8854c3067f1ed2ae45f436572d73eb7", "url": "https://api.github.com/repos/composer/composer/zipball/d8aef3af866b28786ce9b8647e52c42496436669",
"reference": "e965b9aaa8854c3067f1ed2ae45f436572d73eb7", "reference": "d8aef3af866b28786ce9b8647e52c42496436669",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -3959,7 +4008,7 @@
"type": "library", "type": "library",
"extra": { "extra": {
"branch-alias": { "branch-alias": {
"dev-master": "1.7-dev" "dev-master": "1.8-dev"
} }
}, },
"autoload": { "autoload": {
@ -3990,7 +4039,7 @@
"dependency", "dependency",
"package" "package"
], ],
"time": "2018-11-01T09:05:06+00:00" "time": "2018-12-03T09:31:16+00:00"
}, },
{ {
"name": "composer/semver", "name": "composer/semver",
@ -4117,16 +4166,16 @@
}, },
{ {
"name": "composer/xdebug-handler", "name": "composer/xdebug-handler",
"version": "1.3.0", "version": "1.3.1",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/composer/xdebug-handler.git", "url": "https://github.com/composer/xdebug-handler.git",
"reference": "b8e9745fb9b06ea6664d8872c4505fb16df4611c" "reference": "dc523135366eb68f22268d069ea7749486458562"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/composer/xdebug-handler/zipball/b8e9745fb9b06ea6664d8872c4505fb16df4611c", "url": "https://api.github.com/repos/composer/xdebug-handler/zipball/dc523135366eb68f22268d069ea7749486458562",
"reference": "b8e9745fb9b06ea6664d8872c4505fb16df4611c", "reference": "dc523135366eb68f22268d069ea7749486458562",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -4157,7 +4206,7 @@
"Xdebug", "Xdebug",
"performance" "performance"
], ],
"time": "2018-08-31T19:07:57+00:00" "time": "2018-11-29T10:59:02+00:00"
}, },
{ {
"name": "doctrine/instantiator", "name": "doctrine/instantiator",
@ -6020,16 +6069,16 @@
}, },
{ {
"name": "squizlabs/php_codesniffer", "name": "squizlabs/php_codesniffer",
"version": "3.3.2", "version": "3.4.0",
"source": { "source": {
"type": "git", "type": "git",
"url": "https://github.com/squizlabs/PHP_CodeSniffer.git", "url": "https://github.com/squizlabs/PHP_CodeSniffer.git",
"reference": "6ad28354c04b364c3c71a34e4a18b629cc3b231e" "reference": "379deb987e26c7cd103a7b387aea178baec96e48"
}, },
"dist": { "dist": {
"type": "zip", "type": "zip",
"url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/6ad28354c04b364c3c71a34e4a18b629cc3b231e", "url": "https://api.github.com/repos/squizlabs/PHP_CodeSniffer/zipball/379deb987e26c7cd103a7b387aea178baec96e48",
"reference": "6ad28354c04b364c3c71a34e4a18b629cc3b231e", "reference": "379deb987e26c7cd103a7b387aea178baec96e48",
"shasum": "" "shasum": ""
}, },
"require": { "require": {
@ -6067,7 +6116,7 @@
"phpcs", "phpcs",
"standards" "standards"
], ],
"time": "2018-09-23T23:08:17+00:00" "time": "2018-12-19T23:57:18+00:00"
}, },
{ {
"name": "symfony/dom-crawler", "name": "symfony/dom-crawler",
@ -6271,12 +6320,16 @@
"prefer-stable": false, "prefer-stable": false,
"prefer-lowest": false, "prefer-lowest": false,
"platform": { "platform": {
"php": ">=7.0.0", "php": ">=7.0.5",
"ext-json": "*",
"ext-tidy": "*", "ext-tidy": "*",
"ext-dom": "*" "ext-dom": "*",
"ext-xml": "*",
"ext-mbstring": "*",
"ext-gd": "*"
}, },
"platform-dev": [], "platform-dev": [],
"platform-overrides": { "platform-overrides": {
"php": "7.0" "php": "7.0.5"
} }
} }

View File

@ -1,175 +1,85 @@
<?php <?php
/**
* Global app 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.
*/
return [ return [
// The environment to run BookStack in.
// Options: production, development, demo, testing
'env' => env('APP_ENV', 'production'), 'env' => env('APP_ENV', 'production'),
/** // Enter the application in debug mode.
* Set the default view type for various lists. Can be overridden by user preferences. // Shows much more verbose error messages. Has potential to show
* This will be used for public viewers and users that have not set a preference. // private configuration variables so should remain disabled in public.
*/
'views' => [
'books' => env('APP_VIEWS_BOOKS', 'list')
],
/**
* The number of revisions to keep in the database.
* Once this limit is reached older revisions will be deleted.
* If set to false then a limit will not be enforced.
*/
'revision_limit' => env('REVISION_LIMIT', 50),
/**
* Allow <script> tags to entered within page content.
* <script> tags are escaped by default.
* Even when overridden the WYSIWYG editor may still escape script content.
*/
'allow_content_scripts' => env('ALLOW_CONTENT_SCRIPTS', false),
/**
* Override the default behaviour for allowing crawlers to crawl the instance.
* May be ignored if view has be overridden or modified.
* Defaults to null since, if not set, 'app-public' status used instead.
*/
'allow_robots' => env('ALLOW_ROBOTS', null),
/*
|--------------------------------------------------------------------------
| Application Debug Mode
|--------------------------------------------------------------------------
|
| When your application is in debug mode, detailed error messages with
| stack traces will be shown on every error that occurs within your
| application. If disabled, a simple generic error page is shown.
|
*/
'debug' => env('APP_DEBUG', false), 'debug' => env('APP_DEBUG', false),
/* // Set the default view type for various lists. Can be overridden by user preferences.
|-------------------------------------------------------------------------- // These will be used for public viewers and users that have not set a preference.
| Application URL 'views' => [
|-------------------------------------------------------------------------- 'books' => env('APP_VIEWS_BOOKS', 'list'),
| 'bookshelves' => env('APP_VIEWS_BOOKSHELVES', 'grid'),
| This URL is used by the console to properly generate URLs when using ],
| the Artisan command line tool. You should set this to the root of
| your application so that it is used when running Artisan tasks.
|
*/
// The number of revisions to keep in the database.
// Once this limit is reached older revisions will be deleted.
// If set to false then a limit will not be enforced.
'revision_limit' => env('REVISION_LIMIT', 50),
// Allow <script> tags to entered within page content.
// <script> tags are escaped by default.
// Even when overridden the WYSIWYG editor may still escape script content.
'allow_content_scripts' => env('ALLOW_CONTENT_SCRIPTS', false),
// Override the default behaviour for allowing crawlers to crawl the instance.
// May be ignored if view has be overridden or modified.
// Defaults to null since, if not set, 'app-public' status used instead.
'allow_robots' => env('ALLOW_ROBOTS', null),
// Application Base URL, Used by laravel in development commands
// and used by BookStack in URL generation.
'url' => env('APP_URL', '') === 'http://bookstack.dev' ? '' : env('APP_URL', ''), 'url' => env('APP_URL', '') === 'http://bookstack.dev' ? '' : env('APP_URL', ''),
/* // Application timezone for back-end date functions.
|--------------------------------------------------------------------------
| Application Timezone
|--------------------------------------------------------------------------
|
| Here you may specify the default timezone for your application, which
| will be used by the PHP date and date-time functions. We have gone
| ahead and set this to a sensible default for you out of the box.
|
*/
'timezone' => 'UTC', 'timezone' => 'UTC',
/* // Default locale to use
|--------------------------------------------------------------------------
| Application Locale Configuration
|--------------------------------------------------------------------------
|
| The application locale determines the default locale that will be used
| by the translation service provider. You are free to set this value
| to any of the locales which will be supported by the application.
|
*/
'locale' => env('APP_LANG', 'en'), 'locale' => env('APP_LANG', 'en'),
'locales' => ['en', 'ar', 'de', 'es', 'es_AR', 'fr', 'nl', 'pt_BR', 'sk', 'sv', 'kr', 'ja', 'pl', 'it', 'ru', 'zh_CN', 'zh_TW'],
/* // Locales available
|-------------------------------------------------------------------------- 'locales' => ['en', 'ar', 'de', 'de_informal', 'es', 'es_AR', 'fr', 'nl', 'pt_BR', 'sk', 'sv', 'kr', 'ja', 'pl', 'it', 'ru', 'uk', 'zh_CN', 'zh_TW'],
| Right-to-left text control
|--------------------------------------------------------------------------
|
| Right-to-left text control is set to false by default since English
| is the primary supported application but this may be dynamically
| altered by the applications localization system.
|
*/
'rtl' => false,
/*
|--------------------------------------------------------------------------
| Auto-detect the locale for public users
|--------------------------------------------------------------------------
|
| For public users their locale can be guessed by headers sent by their
| browser. This is usually set by users in their browser settings.
| If not found the default app locale will be used.
|
*/
'auto_detect_locale' => env('APP_AUTO_LANG_PUBLIC', true),
/*
|--------------------------------------------------------------------------
| Application Fallback Locale
|--------------------------------------------------------------------------
|
| The fallback locale determines the locale to use when the current one
| is not available. You may change the value to correspond to any of
| the language folders that are provided through your application.
|
*/
// Application Fallback Locale
'fallback_locale' => 'en', 'fallback_locale' => 'en',
/* // Enable right-to-left text control.
|-------------------------------------------------------------------------- 'rtl' => false,
| Encryption Key
|--------------------------------------------------------------------------
|
| This key is used by the Illuminate encrypter service and should be set
| to a random, 32 character string, otherwise these encrypted strings
| will not be safe. Please do this before deploying an application!
|
*/
// Auto-detect the locale for public users
// For public users their locale can be guessed by headers sent by their
// browser. This is usually set by users in their browser settings.
// If not found the default app locale will be used.
'auto_detect_locale' => env('APP_AUTO_LANG_PUBLIC', true),
// Encryption key
'key' => env('APP_KEY', 'AbAZchsay4uBTU33RubBzLKw203yqSqr'), 'key' => env('APP_KEY', 'AbAZchsay4uBTU33RubBzLKw203yqSqr'),
// Encryption cipher
'cipher' => 'AES-256-CBC', 'cipher' => 'AES-256-CBC',
/* // Logging configuration
|-------------------------------------------------------------------------- // Options: single, daily, syslog, errorlog
| Logging Configuration
|--------------------------------------------------------------------------
|
| Here you may configure the log settings for your application. Out of
| the box, Laravel uses the Monolog PHP logging library. This gives
| you a variety of powerful log handlers / formatters to utilize.
|
| Available Settings: "single", "daily", "syslog", "errorlog"
|
*/
'log' => env('APP_LOGGING', 'single'), 'log' => env('APP_LOGGING', 'single'),
/* // Application Services Provides
|--------------------------------------------------------------------------
| Autoloaded Service Providers
|--------------------------------------------------------------------------
|
| The service providers listed here will be automatically loaded on the
| request to your application. Feel free to add your own services to
| this array to grant expanded functionality to your applications.
|
*/
'providers' => [ 'providers' => [
/* // Laravel Framework Service Providers...
* Laravel Framework Service Providers...
*/
Illuminate\Auth\AuthServiceProvider::class, Illuminate\Auth\AuthServiceProvider::class,
Illuminate\Broadcasting\BroadcastServiceProvider::class, Illuminate\Broadcasting\BroadcastServiceProvider::class,
Illuminate\Bus\BusServiceProvider::class, Illuminate\Bus\BusServiceProvider::class,
@ -187,25 +97,22 @@ return [
Illuminate\Redis\RedisServiceProvider::class, Illuminate\Redis\RedisServiceProvider::class,
Illuminate\Auth\Passwords\PasswordResetServiceProvider::class, Illuminate\Auth\Passwords\PasswordResetServiceProvider::class,
Illuminate\Session\SessionServiceProvider::class, Illuminate\Session\SessionServiceProvider::class,
Illuminate\Translation\TranslationServiceProvider::class,
Illuminate\Validation\ValidationServiceProvider::class, Illuminate\Validation\ValidationServiceProvider::class,
Illuminate\View\ViewServiceProvider::class, Illuminate\View\ViewServiceProvider::class,
Illuminate\Notifications\NotificationServiceProvider::class, Illuminate\Notifications\NotificationServiceProvider::class,
SocialiteProviders\Manager\ServiceProvider::class, SocialiteProviders\Manager\ServiceProvider::class,
/** // Third party service providers
* Third Party
*/
Intervention\Image\ImageServiceProvider::class, Intervention\Image\ImageServiceProvider::class,
Barryvdh\DomPDF\ServiceProvider::class, Barryvdh\DomPDF\ServiceProvider::class,
Barryvdh\Snappy\ServiceProvider::class, Barryvdh\Snappy\ServiceProvider::class,
/* // BookStack replacement service providers (Extends Laravel)
* Application Service Providers...
*/
BookStack\Providers\PaginationServiceProvider::class, BookStack\Providers\PaginationServiceProvider::class,
BookStack\Providers\TranslationServiceProvider::class,
// BookStack custom service providers
BookStack\Providers\AuthServiceProvider::class, BookStack\Providers\AuthServiceProvider::class,
BookStack\Providers\AppServiceProvider::class, BookStack\Providers\AppServiceProvider::class,
BookStack\Providers\BroadcastServiceProvider::class, BookStack\Providers\BroadcastServiceProvider::class,
@ -225,8 +132,10 @@ return [
| |
*/ */
// Class aliases, Registered on application start
'aliases' => [ 'aliases' => [
// Laravel
'App' => Illuminate\Support\Facades\App::class, 'App' => Illuminate\Support\Facades\App::class,
'Artisan' => Illuminate\Support\Facades\Artisan::class, 'Artisan' => Illuminate\Support\Facades\Artisan::class,
'Auth' => Illuminate\Support\Facades\Auth::class, 'Auth' => Illuminate\Support\Facades\Auth::class,
@ -262,18 +171,12 @@ return [
'View' => Illuminate\Support\Facades\View::class, 'View' => Illuminate\Support\Facades\View::class,
'Socialite' => Laravel\Socialite\Facades\Socialite::class, 'Socialite' => Laravel\Socialite\Facades\Socialite::class,
/** // Third Party
* Third Party
*/
'ImageTool' => Intervention\Image\Facades\Image::class, 'ImageTool' => Intervention\Image\Facades\Image::class,
'DomPDF' => Barryvdh\DomPDF\Facade::class, 'DomPDF' => Barryvdh\DomPDF\Facade::class,
'SnappyPDF' => Barryvdh\Snappy\Facades\SnappyPdf::class, 'SnappyPDF' => Barryvdh\Snappy\Facades\SnappyPdf::class,
/** // Custom BookStack
* Custom
*/
'Activity' => BookStack\Facades\Activity::class, 'Activity' => BookStack\Facades\Activity::class,
'Setting' => BookStack\Facades\Setting::class, 'Setting' => BookStack\Facades\Setting::class,
'Views' => BookStack\Facades\Views::class, 'Views' => BookStack\Facades\Views::class,
@ -281,6 +184,7 @@ return [
], ],
// Proxy configuration
'proxies' => env('APP_PROXIES', ''), 'proxies' => env('APP_PROXIES', ''),
]; ];

View File

@ -1,43 +1,32 @@
<?php <?php
/**
* Authentication 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.
*/
return [ return [
// Method of authentication to use
// Options: standard, ldap
'method' => env('AUTH_METHOD', 'standard'), 'method' => env('AUTH_METHOD', 'standard'),
/* // Authentication Defaults
|-------------------------------------------------------------------------- // This option controls the default authentication "guard" and password
| Authentication Defaults // reset options for your application.
|--------------------------------------------------------------------------
|
| This option controls the default authentication "guard" and password
| reset options for your application. You may change these defaults
| as required, but they're a perfect start for most applications.
|
*/
'defaults' => [ 'defaults' => [
'guard' => 'web', 'guard' => 'web',
'passwords' => 'users', 'passwords' => 'users',
], ],
/* // Authentication Guards
|-------------------------------------------------------------------------- // All authentication drivers have a user provider. This defines how the
| Authentication Guards // users are actually retrieved out of your database or other storage
|-------------------------------------------------------------------------- // mechanisms used by this application to persist your user's data.
| // Supported: "session", "token"
| Next, you may define every authentication guard for your application.
| Of course, a great default configuration has been defined for you
| here which uses session storage and the Eloquent user provider.
|
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| Supported: "session", "token"
|
*/
'guards' => [ 'guards' => [
'web' => [ 'web' => [
'driver' => 'session', 'driver' => 'session',
@ -50,23 +39,11 @@ return [
], ],
], ],
/* // User Providers
|-------------------------------------------------------------------------- // All authentication drivers have a user provider. This defines how the
| User Providers // users are actually retrieved out of your database or other storage
|-------------------------------------------------------------------------- // mechanisms used by this application to persist your user's data.
| // Supported: database, eloquent, ldap
| All authentication drivers have a user provider. This defines how the
| users are actually retrieved out of your database or other storage
| mechanisms used by this application to persist your user's data.
|
| If you have multiple user tables or models you may configure multiple
| sources which represent each model / table. These sources may then
| be assigned to any extra authentication guards you have defined.
|
| Supported: "database", "eloquent"
|
*/
'providers' => [ 'providers' => [
'users' => [ 'users' => [
'driver' => env('AUTH_METHOD', 'standard') === 'standard' ? 'eloquent' : env('AUTH_METHOD'), 'driver' => env('AUTH_METHOD', 'standard') === 'standard' ? 'eloquent' : env('AUTH_METHOD'),
@ -79,25 +56,10 @@ return [
// ], // ],
], ],
/* // Resetting Passwords
|-------------------------------------------------------------------------- // The expire time is the number of minutes that the reset token should be
| Resetting Passwords // considered valid. This security feature keeps tokens short-lived so
|-------------------------------------------------------------------------- // they have less time to be guessed. You may change this as needed.
|
| Here you may set the options for resetting passwords including the view
| that is your password reset e-mail. You may also set the name of the
| table that maintains all of the reset tokens for your application.
|
| You may specify multiple password reset configurations if you have more
| than one user table or model in the application and you want to have
| separate password reset settings based on the specific user types.
|
| The expire time is the number of minutes that the reset token should be
| considered valid. This security feature keeps tokens short-lived so
| they have less time to be guessed. You may change this as needed.
|
*/
'passwords' => [ 'passwords' => [
'users' => [ 'users' => [
'provider' => 'users', 'provider' => 'users',

View File

@ -1,31 +1,25 @@
<?php <?php
/**
* Broadcasting 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.
*/
return [ return [
/* // Default Broadcaster
|-------------------------------------------------------------------------- // This option controls the default broadcaster that will be used by the
| Default Broadcaster // framework when an event needs to be broadcast. This can be set to
|-------------------------------------------------------------------------- // any of the connections defined in the "connections" array below.
|
| This option controls the default broadcaster that will be used by the
| framework when an event needs to be broadcast. You may set this to
| any of the connections defined in the "connections" array below.
|
*/
'default' => env('BROADCAST_DRIVER', 'pusher'), 'default' => env('BROADCAST_DRIVER', 'pusher'),
/* // Broadcast Connections
|-------------------------------------------------------------------------- // Here you may define all of the broadcast connections that will be used
| Broadcast Connections // to broadcast events to other systems or over websockets. Samples of
|-------------------------------------------------------------------------- // each available type of connection are provided inside this array.
|
| 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' => [ 'connections' => [
'pusher' => [ 'pusher' => [

View File

@ -1,5 +1,13 @@
<?php <?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 // MEMCACHED - Split out configuration into an array
if (env('CACHE_DRIVER') === 'memcached') { if (env('CACHE_DRIVER') === 'memcached') {
$memcachedServerKeys = ['host', 'port', 'weight']; $memcachedServerKeys = ['host', 'port', 'weight'];
@ -14,30 +22,11 @@ if (env('CACHE_DRIVER') === 'memcached') {
return [ 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'), '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.
|
*/
'stores' => [ 'stores' => [
'apc' => [ 'apc' => [
@ -71,17 +60,8 @@ return [
], ],
/* // Cache key prefix
|-------------------------------------------------------------------------- // Used to prevent collisions in shared cache systems.
| 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', 'bookstack'), 'prefix' => env('CACHE_PREFIX', 'bookstack'),
]; ];

View File

@ -1,35 +0,0 @@
<?php
return [
/*
|--------------------------------------------------------------------------
| Additional Compiled Classes
|--------------------------------------------------------------------------
|
| Here you may specify additional classes to include in the compiled file
| generated by the `artisan optimize` command. These should be classes
| that are included on basically every request into the application.
|
*/
'files' => [
//
],
/*
|--------------------------------------------------------------------------
| Compiled File Providers
|--------------------------------------------------------------------------
|
| Here you may list service providers which define a "compiles" function
| that returns additional files that should be compiled, providing an
| easy way to get common files from any packages you are utilizing.
|
*/
'providers' => [
//
],
];

View File

@ -1,5 +1,13 @@
<?php <?php
/**
* Database 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.
*/
// REDIS - Split out configuration into an array // REDIS - Split out configuration into an array
if (env('REDIS_SERVERS', false)) { if (env('REDIS_SERVERS', false)) {
$redisServerKeys = ['host', 'port', 'database']; $redisServerKeys = ['host', 'port', 'database'];
@ -16,6 +24,7 @@ if (env('REDIS_SERVERS', false)) {
} }
} }
// MYSQL - Split out port from host if set
$mysql_host = env('DB_HOST', 'localhost'); $mysql_host = env('DB_HOST', 'localhost');
$mysql_host_exploded = explode(':', $mysql_host); $mysql_host_exploded = explode(':', $mysql_host);
$mysql_port = env('DB_PORT', 3306); $mysql_port = env('DB_PORT', 3306);
@ -26,48 +35,12 @@ if (count($mysql_host_exploded) > 1) {
return [ return [
/* // Default database connection name.
|-------------------------------------------------------------------------- // Options: mysql, mysql_testing
| PDO Fetch Style
|--------------------------------------------------------------------------
|
| By default, database results will be returned as instances of the PHP
| stdClass object; however, you may desire to retrieve records in an
| array format for simplicity. Here you can tweak the fetch style.
|
*/
'fetch' => PDO::FETCH_CLASS,
/*
|--------------------------------------------------------------------------
| Default Database Connection Name
|--------------------------------------------------------------------------
|
| Here you may specify which of the database connections below you wish
| to use as your default connection for all database work. Of course
| you may use many connections at once using the Database library.
|
*/
'default' => env('DB_CONNECTION', 'mysql'), 'default' => env('DB_CONNECTION', 'mysql'),
/* // Available database connections
|-------------------------------------------------------------------------- // Many of those shown here are unsupported by BookStack.
| Database Connections
|--------------------------------------------------------------------------
|
| Here are each of the database connections setup for your application.
| Of course, examples of configuring each database platform that is
| supported by Laravel is shown below to make development simple.
|
|
| All database work in Laravel is done through the PHP PDO facilities
| so make sure you have the driver for your particular database of
| choice installed on your machine before you begin development.
|
*/
'connections' => [ 'connections' => [
'sqlite' => [ 'sqlite' => [
@ -82,11 +55,13 @@ return [
'database' => env('DB_DATABASE', 'forge'), 'database' => env('DB_DATABASE', 'forge'),
'username' => env('DB_USERNAME', 'forge'), 'username' => env('DB_USERNAME', 'forge'),
'password' => env('DB_PASSWORD', ''), 'password' => env('DB_PASSWORD', ''),
'unix_socket' => env('DB_SOCKET', ''),
'port' => $mysql_port, 'port' => $mysql_port,
'charset' => 'utf8mb4', 'charset' => 'utf8mb4',
'collation' => 'utf8mb4_unicode_ci', 'collation' => 'utf8mb4_unicode_ci',
'prefix' => '', 'prefix' => '',
'strict' => false, 'strict' => false,
'engine' => null,
], ],
'mysql_testing' => [ 'mysql_testing' => [
@ -124,30 +99,13 @@ return [
], ],
/* // Migration Repository Table
|-------------------------------------------------------------------------- // This table keeps track of all the migrations that have already run for
| Migration Repository Table // your application. Using this information, we can determine which of
|-------------------------------------------------------------------------- // the migrations on disk haven't actually been run in the database.
|
| This table keeps track of all the migrations that have already run for
| your application. Using this information, we can determine which of
| the migrations on disk haven't actually been run in the database.
|
*/
'migrations' => 'migrations', 'migrations' => 'migrations',
/* // Redis configuration to use if set
|--------------------------------------------------------------------------
| Redis Databases
|--------------------------------------------------------------------------
|
| Redis is an open source, fast, and advanced key-value store that also
| provides a richer set of commands than a typical key-value systems
| such as APC or Memcached. Laravel makes it easy to dig right in.
|
*/
'redis' => env('REDIS_SERVERS', false) ? $redisConfig : [], 'redis' => env('REDIS_SERVERS', false) ? $redisConfig : [],
]; ];

View File

@ -1,16 +1,16 @@
<?php <?php
/**
* DOMPDF 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.
*/
return [ return [
/*
|--------------------------------------------------------------------------
| Settings
|--------------------------------------------------------------------------
|
| Set some default values. It is possible to add all defines that can be set
| in dompdf_config.inc.php. You can also override the entire config file.
|
*/
'show_warnings' => false, // Throw an Exception on warnings from dompdf 'show_warnings' => false, // Throw an Exception on warnings from dompdf
'orientation' => 'portrait', 'orientation' => 'portrait',
'defines' => [ 'defines' => [

View File

@ -1,57 +1,29 @@
<?php <?php
/**
* Filesystem 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.
*/
return [ return [
/* // Default Filesystem Disk
|-------------------------------------------------------------------------- // Options: local, local_secure, s3
| Default Filesystem Disk
|--------------------------------------------------------------------------
|
| Here you may specify the default filesystem disk that should be used
| by the framework. A "local" driver, as well as a variety of cloud
| based drivers are available for your choosing. Just store away!
|
| Supported: "local", "ftp", "s3", "rackspace"
|
*/
'default' => env('STORAGE_TYPE', 'local'), 'default' => env('STORAGE_TYPE', 'local'),
/* // Storage URL
|-------------------------------------------------------------------------- // This is the url to where the storage is located for when using an external
| Storage URL // file storage service, such as s3, to store publicly accessible assets.
|--------------------------------------------------------------------------
|
| This is the url to where the storage is located for when using an external
| file storage service, such as s3, to store publicly accessible assets.
|
*/
'url' => env('STORAGE_URL', false), 'url' => env('STORAGE_URL', false),
/* // Default Cloud Filesystem Disk
|--------------------------------------------------------------------------
| Default Cloud Filesystem Disk
|--------------------------------------------------------------------------
|
| Many applications store files both locally and in the cloud. For this
| reason, you may specify a default "cloud" driver here. This driver
| will be bound as the Cloud disk implementation in the container.
|
*/
'cloud' => 's3', 'cloud' => 's3',
/* // Available filesystem disks
|-------------------------------------------------------------------------- // Only local, local_secure & s3 are supported by BookStack
| Filesystem Disks
|--------------------------------------------------------------------------
|
| Here you may configure as many filesystem "disks" as you wish, and you
| may even configure multiple disks of the same driver. Defaults have
| been setup for each driver as an example of the required options.
|
*/
'disks' => [ 'disks' => [
'local' => [ 'local' => [
@ -69,13 +41,6 @@ return [
'host' => 'ftp.example.com', 'host' => 'ftp.example.com',
'username' => 'your-username', 'username' => 'your-username',
'password' => 'your-password', 'password' => 'your-password',
// Optional FTP Settings...
// 'port' => 21,
// 'root' => '',
// 'passive' => true,
// 'ssl' => true,
// 'timeout' => 30,
], ],
's3' => [ 's3' => [

View File

@ -1,124 +1,49 @@
<?php <?php
/**
* Mail 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.
*/
return [ return [
/* // Mail driver to use.
|-------------------------------------------------------------------------- // Options: smtp, mail, sendmail, log
| Mail Driver
|--------------------------------------------------------------------------
|
| Laravel supports both SMTP and PHP's "mail" function as drivers for the
| sending of e-mail. You may specify which one you're using throughout
| your application here. By default, Laravel is setup for SMTP mail.
|
| Supported: "smtp", "mail", "sendmail", "mailgun", "mandrill", "ses", "log"
|
*/
'driver' => env('MAIL_DRIVER', 'smtp'), 'driver' => env('MAIL_DRIVER', 'smtp'),
/* // SMTP host address
|--------------------------------------------------------------------------
| SMTP Host Address
|--------------------------------------------------------------------------
|
| Here you may provide the host address of the SMTP server used by your
| applications. A default option is provided that is compatible with
| the Mailgun mail service which will provide reliable deliveries.
|
*/
'host' => env('MAIL_HOST', 'smtp.mailgun.org'), 'host' => env('MAIL_HOST', 'smtp.mailgun.org'),
/* // SMTP host port
|--------------------------------------------------------------------------
| SMTP Host Port
|--------------------------------------------------------------------------
|
| This is the SMTP port used by your application to deliver e-mails to
| users of the application. Like the host we have set this value to
| stay compatible with the Mailgun e-mail application by default.
|
*/
'port' => env('MAIL_PORT', 587), 'port' => env('MAIL_PORT', 587),
/* // Global "From" address & name
|-------------------------------------------------------------------------- 'from' => [
| Global "From" Address 'address' => env('MAIL_FROM', 'mail@bookstackapp.com'),
|-------------------------------------------------------------------------- 'name' => env('MAIL_FROM_NAME','BookStack')
| ],
| You may wish for all e-mails sent by your application to be sent from
| the same address. Here, you may specify a name and address that is
| used globally for all e-mails that are sent by your application.
|
*/
'from' => ['address' => env('MAIL_FROM', 'mail@bookstackapp.com'), 'name' => env('MAIL_FROM_NAME','BookStack')],
/*
|--------------------------------------------------------------------------
| E-Mail Encryption Protocol
|--------------------------------------------------------------------------
|
| Here you may specify the encryption protocol that should be used when
| the application send e-mail messages. A sensible default using the
| transport layer security protocol should provide great security.
|
*/
// Email encryption protocol
'encryption' => env('MAIL_ENCRYPTION', 'tls'), 'encryption' => env('MAIL_ENCRYPTION', 'tls'),
/* // SMTP server username
|--------------------------------------------------------------------------
| SMTP Server Username
|--------------------------------------------------------------------------
|
| If your SMTP server requires a username for authentication, you should
| set it here. This will get used to authenticate with your server on
| connection. You may also set the "password" value below this one.
|
*/
'username' => env('MAIL_USERNAME'), 'username' => env('MAIL_USERNAME'),
/* // SMTP server password
|--------------------------------------------------------------------------
| SMTP Server Password
|--------------------------------------------------------------------------
|
| Here you may set the password required by your SMTP server to send out
| messages from your application. This will be given to the server on
| connection so that the application will be able to send messages.
|
*/
'password' => env('MAIL_PASSWORD'), 'password' => env('MAIL_PASSWORD'),
/* // Sendmail application path
|--------------------------------------------------------------------------
| Sendmail System Path
|--------------------------------------------------------------------------
|
| When using the "sendmail" driver to send e-mails, we will need to know
| the path to where Sendmail lives on this server. A default path has
| been provided here, which will work well on most of your systems.
|
*/
'sendmail' => '/usr/sbin/sendmail -bs', 'sendmail' => '/usr/sbin/sendmail -bs',
/* // Email markdown configuration
|-------------------------------------------------------------------------- 'markdown' => [
| Mail "Pretend" 'theme' => 'default',
|-------------------------------------------------------------------------- 'paths' => [
| resource_path('views/vendor/mail'),
| When this option is enabled, e-mail will not actually be sent over the ],
| web and will instead be written to your application's logs files so ],
| you may inspect the message. This is great for local development.
|
*/
'pretend' => env('MAIL_PRETEND', false),
]; ];

View File

@ -1,34 +1,20 @@
<?php <?php
/**
* Queue 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.
*/
return [ return [
/* // Default driver to use for the queue
|-------------------------------------------------------------------------- // Options: null, sync, redis
| Default Queue Driver
|--------------------------------------------------------------------------
|
| The Laravel queue API supports a variety of back-ends via an unified
| API, giving you convenient access to each back-end using the same
| syntax for each one. Here you may set the default queue driver.
|
| Supported: "null", "sync", "database", "beanstalkd",
| "sqs", "iron", "redis"
|
*/
'default' => env('QUEUE_DRIVER', 'sync'), 'default' => env('QUEUE_DRIVER', 'sync'),
/* // Queue connection configuration
|--------------------------------------------------------------------------
| Queue Connections
|--------------------------------------------------------------------------
|
| Here you may configure the connection information for each server that
| is used by your application. A default configuration has been added
| for each back-end shipped with Laravel. You are free to add more.
|
*/
'connections' => [ 'connections' => [
'sync' => [ 'sync' => [
@ -75,17 +61,7 @@ return [
], ],
/* // Failed queue job logging
|--------------------------------------------------------------------------
| Failed Queue Jobs
|--------------------------------------------------------------------------
|
| These options configure the behavior of failed queue job logging so you
| can control which database and table are used to store the jobs that
| have failed. You may change them to any database / table you wish.
|
*/
'failed' => [ 'failed' => [
'database' => 'mysql', 'table' => 'failed_jobs', 'database' => 'mysql', 'table' => 'failed_jobs',
], ],

View File

@ -1,25 +1,25 @@
<?php <?php
/**
* Third party service 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.
*/
return [ return [
/*
|--------------------------------------------------------------------------
| Third Party Services
|--------------------------------------------------------------------------
|
| This file is for storing the credentials for third party services such
| as Stripe, Mailgun, Mandrill, and others. This file provides a sane
| default location for this type of information, allowing packages
| to have a conventional place to find your various credentials.
|
*/
// Single option to disable non-auth external services such as Gravatar and Draw.io // Single option to disable non-auth external services such as Gravatar and Draw.io
'disable_services' => env('DISABLE_EXTERNAL_SERVICES', false), 'disable_services' => env('DISABLE_EXTERNAL_SERVICES', false),
'gravatar' => env('GRAVATAR', !env('DISABLE_EXTERNAL_SERVICES', false)),
// Draw.io integration active
'drawio' => env('DRAWIO', !env('DISABLE_EXTERNAL_SERVICES', false)), 'drawio' => env('DRAWIO', !env('DISABLE_EXTERNAL_SERVICES', false)),
// URL for fetching avatars
'avatar_url' => env('AVATAR_URL', ''),
// Callback URL for social authentication methods
'callback_url' => env('APP_URL', false), 'callback_url' => env('APP_URL', false),
'mailgun' => [ 'mailgun' => [
@ -27,10 +27,6 @@ return [
'secret' => '', 'secret' => '',
], ],
'mandrill' => [
'secret' => '',
],
'ses' => [ 'ses' => [
'key' => '', 'key' => '',
'secret' => '', 'secret' => '',
@ -149,6 +145,7 @@ return [
'user_to_groups' => env('LDAP_USER_TO_GROUPS',false), 'user_to_groups' => env('LDAP_USER_TO_GROUPS',false),
'group_attribute' => env('LDAP_GROUP_ATTRIBUTE', 'memberOf'), 'group_attribute' => env('LDAP_GROUP_ATTRIBUTE', 'memberOf'),
'remove_from_groups' => env('LDAP_REMOVE_FROM_GROUPS',false), 'remove_from_groups' => env('LDAP_REMOVE_FROM_GROUPS',false),
'tls_insecure' => env('LDAP_TLS_INSECURE', false),
] ]
]; ];

View File

@ -1,181 +1,80 @@
<?php <?php
/**
* Session 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.
*/
return [ return [
/* // Default session driver
|-------------------------------------------------------------------------- // Options: file, cookie, database, redis, memcached, array
| Default Session Driver
|--------------------------------------------------------------------------
|
| This option controls the default session "driver" that will be used on
| requests. By default, we will use the lightweight native driver but
| you may specify any of the other wonderful drivers provided here.
|
| Supported: "file", "cookie", "database", "apc",
| "memcached", "redis", "array"
|
*/
'driver' => env('SESSION_DRIVER', 'file'), 'driver' => env('SESSION_DRIVER', 'file'),
/* // Session lifetime, in minutes
|--------------------------------------------------------------------------
| Session Lifetime
|--------------------------------------------------------------------------
|
| Here you may specify the number of minutes that you wish the session
| to be allowed to remain idle before it expires. If you want them
| to immediately expire on the browser closing, set that option.
|
*/
'lifetime' => env('SESSION_LIFETIME', 120), 'lifetime' => env('SESSION_LIFETIME', 120),
// Expire session on browser close
'expire_on_close' => false, 'expire_on_close' => false,
/* // Encrypt session data
|--------------------------------------------------------------------------
| Session Encryption
|--------------------------------------------------------------------------
|
| This option allows you to easily specify that all of your session data
| should be encrypted before it is stored. All encryption will be run
| automatically by Laravel and you can use the Session like normal.
|
*/
'encrypt' => false, 'encrypt' => false,
/* // Location to store session files
|--------------------------------------------------------------------------
| Session File Location
|--------------------------------------------------------------------------
|
| When using the native session driver, we need a location where session
| files may be stored. A default has been set for you but a different
| location may be specified. This is only needed for file sessions.
|
*/
'files' => storage_path('framework/sessions'), 'files' => storage_path('framework/sessions'),
/* // Session Database Connection
|-------------------------------------------------------------------------- // When using the "database" or "redis" session drivers, you can specify a
| Session Database Connection // connection that should be used to manage these sessions. This should
|-------------------------------------------------------------------------- // correspond to a connection in your database configuration options.
|
| When using the "database" or "redis" session drivers, you may specify a
| connection that should be used to manage these sessions. This should
| correspond to a connection in your database configuration options.
|
*/
'connection' => null, 'connection' => null,
/* // Session database table, if database driver is in use
|--------------------------------------------------------------------------
| Session Database Table
|--------------------------------------------------------------------------
|
| When using the "database" session driver, you may specify the table we
| should use to manage the sessions. Of course, a sensible default is
| provided for you; however, you are free to change this as needed.
|
*/
'table' => 'sessions', 'table' => 'sessions',
/* // Session Sweeping Lottery
|-------------------------------------------------------------------------- // Some session drivers must manually sweep their storage location to get
| Session Sweeping Lottery // rid of old sessions from storage. Here are the chances that it will
|-------------------------------------------------------------------------- // happen on a given request. By default, the odds are 2 out of 100.
|
| Some session drivers must manually sweep their storage location to get
| rid of old sessions from storage. Here are the chances that it will
| happen on a given request. By default, the odds are 2 out of 100.
|
*/
'lottery' => [2, 100], 'lottery' => [2, 100],
/*
|--------------------------------------------------------------------------
| Session Cookie Name
|--------------------------------------------------------------------------
|
| Here you may change the name of the cookie used to identify a session
| instance by ID. The name specified here will get used every time a
| new session cookie is created by the framework for every driver.
|
*/
// Session Cookie Name
// Here you may change the name of the cookie used to identify a session
// instance by ID. The name specified here will get used every time a
// new session cookie is created by the framework for every driver.
'cookie' => env('SESSION_COOKIE_NAME', 'bookstack_session'), 'cookie' => env('SESSION_COOKIE_NAME', 'bookstack_session'),
/* // Session Cookie Path
|-------------------------------------------------------------------------- // The session cookie path determines the path for which the cookie will
| Session Cookie Path // be regarded as available. Typically, this will be the root path of
|-------------------------------------------------------------------------- // your application but you are free to change this when necessary.
|
| The session cookie path determines the path for which the cookie will
| be regarded as available. Typically, this will be the root path of
| your application but you are free to change this when necessary.
|
*/
'path' => '/', 'path' => '/',
/* // Session Cookie Domain
|-------------------------------------------------------------------------- // Here you may change the domain of the cookie used to identify a session
| Session Cookie Domain // in your application. This will determine which domains the cookie is
|-------------------------------------------------------------------------- // available to in your application. A sensible default has been set.
|
| Here you may change the domain of the cookie used to identify a session
| in your application. This will determine which domains the cookie is
| available to in your application. A sensible default has been set.
|
*/
'domain' => env('SESSION_DOMAIN', null), 'domain' => env('SESSION_DOMAIN', null),
/* // HTTPS Only Cookies
|-------------------------------------------------------------------------- // By setting this option to true, session cookies will only be sent back
| HTTPS Only Cookies // to the server if the browser has a HTTPS connection. This will keep
|-------------------------------------------------------------------------- // the cookie from being sent to you if it can not be done securely.
|
| By setting this option to true, session cookies will only be sent back
| to the server if the browser has a HTTPS connection. This will keep
| the cookie from being sent to you if it can not be done securely.
|
*/
'secure' => env('SESSION_SECURE_COOKIE', false), 'secure' => env('SESSION_SECURE_COOKIE', false),
/* // HTTP Access Only
|-------------------------------------------------------------------------- // Setting this value to true will prevent JavaScript from accessing the
| HTTP Access Only // value of the cookie and the cookie will only be accessible through the HTTP protocol.
|--------------------------------------------------------------------------
|
| Setting this value to true will prevent JavaScript from accessing the
| value of the cookie and the cookie will only be accessible through
| the HTTP protocol. You are free to modify this option if needed.
|
*/
'http_only' => true, 'http_only' => true,
/* // Same-Site Cookies
|-------------------------------------------------------------------------- // This option determines how your cookies behave when cross-site requests
| Same-Site Cookies // take place, and can be used to mitigate CSRF attacks. By default, we
|-------------------------------------------------------------------------- // do not enable this as other CSRF protection services are in place.
| // Options: lax, strict
| This option determines how your cookies behave when cross-site requests
| take place, and can be used to mitigate CSRF attacks. By default, we
| do not enable this as other CSRF protection services are in place.
|
| Supported: "lax", "strict"
|
*/
'same_site' => null, 'same_site' => null,
]; ];

View File

@ -1,8 +1,13 @@
<?php <?php
/** /**
* The defaults for the system settings that are saved in the database. * Default system settings.
*
* 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.
*/ */
return [ return [
'app-name' => 'BookStack', 'app-name' => 'BookStack',

View File

@ -1,5 +1,13 @@
<?php <?php
/**
* SnappyPDF 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.
*/
return [ return [
'pdf' => [ 'pdf' => [
'enabled' => true, 'enabled' => true,

View File

@ -1,5 +1,14 @@
<?php <?php
/**
* View 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.
*/
// Join up possible view locations
$viewPaths = [realpath(base_path('resources/views'))]; $viewPaths = [realpath(base_path('resources/views'))];
if ($theme = env('APP_THEME', false)) { if ($theme = env('APP_THEME', false)) {
array_unshift($viewPaths, base_path('themes/' . $theme)); array_unshift($viewPaths, base_path('themes/' . $theme));
@ -7,43 +16,22 @@ if ($theme = env('APP_THEME', false)) {
return [ return [
/* // App theme
|-------------------------------------------------------------------------- // This option defines the theme to use for the application. When a theme
| App theme // is set there must be a `themes/<theme_name>` folder to hold the
|-------------------------------------------------------------------------- // custom theme overrides.
|
| This option defines the theme to use for the application. When a theme
| is set there mush be a `themes/<theme_name>` folder to hold the
| custom theme overrides.
|
*/
'theme' => env('APP_THEME', false), 'theme' => env('APP_THEME', false),
/* // View Storage Paths
|-------------------------------------------------------------------------- // Most templating systems load templates from disk. Here you may specify
| View Storage Paths // an array of paths that should be checked for your views. Of course
|-------------------------------------------------------------------------- // the usual Laravel view path has already been registered for you.
|
| Most templating systems load templates from disk. Here you may specify
| an array of paths that should be checked for your views. Of course
| the usual Laravel view path has already been registered for you.
|
*/
'paths' => $viewPaths, 'paths' => $viewPaths,
/* // Compiled View Path
|-------------------------------------------------------------------------- // This option determines where all the compiled Blade templates will be
| Compiled View Path // stored for your application. Typically, this is within the storage
|-------------------------------------------------------------------------- // directory. However, as usual, you are free to change this value.
|
| This option determines where all the compiled Blade templates will be
| stored for your application. Typically, this is within the storage
| directory. However, as usual, you are free to change this value.
|
*/
'compiled' => realpath(storage_path('framework/views')), 'compiled' => realpath(storage_path('framework/views')),
]; ];

View File

@ -31,6 +31,7 @@
<env name="MAIL_DRIVER" value="log"/> <env name="MAIL_DRIVER" value="log"/>
<env name="AUTH_METHOD" value="standard"/> <env name="AUTH_METHOD" value="standard"/>
<env name="DISABLE_EXTERNAL_SERVICES" value="true"/> <env name="DISABLE_EXTERNAL_SERVICES" value="true"/>
<env name="AVATAR_URL" value=""/>
<env name="LDAP_VERSION" value="3"/> <env name="LDAP_VERSION" value="3"/>
<env name="STORAGE_TYPE" value="local"/> <env name="STORAGE_TYPE" value="local"/>
<env name="GITHUB_APP_ID" value="aaaaaaaaaaaaaa"/> <env name="GITHUB_APP_ID" value="aaaaaaaaaaaaaa"/>

View File

@ -1 +1 @@
!function(){"use strict";var n=function(t){var e=t,r=function(){return e};return{get:r,set:function(t){e=t},clone:function(){return n(r())}}},t=tinymce.util.Tools.resolve("tinymce.PluginManager"),a=tinymce.util.Tools.resolve("tinymce.util.LocalStorage"),o=tinymce.util.Tools.resolve("tinymce.util.Tools"),r=function(t){return t.fire("RestoreDraft")},i=function(t){return t.fire("StoreDraft")},s=function(t){return t.fire("RemoveDraft")},e=function(t,e){return((t=/^(\d+)([ms]?)$/.exec(""+(t||e)))[2]?{s:1e3,m:6e4}[t[2]]:1)*parseInt(t,10)},u=function(t){return t.getParam("autosave_ask_before_unload",!0)},f=function(t){var e=t.getParam("autosave_prefix","tinymce-autosave-{path}{query}{hash}-{id}-");return e=(e=(e=(e=e.replace(/\{path\}/g,document.location.pathname)).replace(/\{query\}/g,document.location.search)).replace(/\{hash\}/g,document.location.hash)).replace(/\{id\}/g,t.id)},c=function(t){return e(t.settings.autosave_interval,"30s")},l=function(t){return e(t.settings.autosave_retention,"20m")},m=function(t,e){var r=t.settings.forced_root_block;return""===(e=o.trim(void 0===e?t.getBody().innerHTML:e))||new RegExp("^<"+r+"[^>]*>((\xa0|&nbsp;|[ \t]|<br[^>]*>)+?|)</"+r+">|<br>$","i").test(e)},v=function(t){var e=parseInt(a.getItem(f(t)+"time"),10)||0;return!((new Date).getTime()-e>l(t)&&(d(t,!1),1))},d=function(t,e){var r=f(t);a.removeItem(r+"draft"),a.removeItem(r+"time"),!1!==e&&s(t)},D=function(t){var e=f(t);!m(t)&&t.isDirty()&&(a.setItem(e+"draft",t.getContent({format:"raw",no_events:!0})),a.setItem(e+"time",(new Date).getTime().toString()),i(t))},g=function(t){var e=f(t);v(t)&&(t.setContent(a.getItem(e+"draft"),{format:"raw"}),r(t))},y={isEmpty:m,hasDraft:v,removeDraft:d,storeDraft:D,restoreDraft:g,startStoreDraft:function(t,e){var r=c(t);e.get()||(setInterval(function(){t.removed||D(t)},r),e.set(!0))},restoreLastDraft:function(t){t.undoManager.transact(function(){g(t),d(t)}),t.focus()}},p=function(e,r){return function(){var t=Array.prototype.slice.call(arguments);return e.apply(null,[r].concat(t))}},h=function(t){return{hasDraft:p(y.hasDraft,t),storeDraft:p(y.storeDraft,t),restoreDraft:p(y.restoreDraft,t),removeDraft:p(y.removeDraft,t),isEmpty:p(y.isEmpty,t)}},_=tinymce.util.Tools.resolve("tinymce.EditorManager");_._beforeUnloadHandler=function(){var e;return o.each(_.get(),function(t){t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&u(t)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))}),e};var b=function(t){window.onbeforeunload=_._beforeUnloadHandler},I=function(r,n){return function(t){var e=t.control;e.disabled(!y.hasDraft(r)),r.on("StoreDraft RestoreDraft RemoveDraft",function(){e.disabled(!y.hasDraft(r))}),y.startStoreDraft(r,n)}},w=function(t,e){t.addButton("restoredraft",{title:"Restore last draft",onclick:function(){y.restoreLastDraft(t)},onPostRender:I(t,e)}),t.addMenuItem("restoredraft",{text:"Restore last draft",onclick:function(){y.restoreLastDraft(t)},onPostRender:I(t,e),context:"file"})};t.add("autosave",function(t){var e=n(!1);return b(t),w(t,e),h(t)})}(); !function(){"use strict";var a=function(t){var e=t,n=function(){return e};return{get:n,set:function(t){e=t},clone:function(){return a(n())}}},t=tinymce.util.Tools.resolve("tinymce.PluginManager"),r=tinymce.util.Tools.resolve("tinymce.util.LocalStorage"),o=tinymce.util.Tools.resolve("tinymce.util.Tools"),i=function(t,e){var n=t||e,r=/^(\d+)([ms]?)$/.exec(""+n);return(r[2]?{s:1e3,m:6e4}[r[2]]:1)*parseInt(n,10)},u=function(t){var e=t.getParam("autosave_prefix","tinymce-autosave-{path}{query}{hash}-{id}-");return e=(e=(e=(e=e.replace(/\{path\}/g,document.location.pathname)).replace(/\{query\}/g,document.location.search)).replace(/\{hash\}/g,document.location.hash)).replace(/\{id\}/g,t.id)},s=function(t,e){var n=t.settings.forced_root_block;return""===(e=o.trim(void 0===e?t.getBody().innerHTML:e))||new RegExp("^<"+n+"[^>]*>((\xa0|&nbsp;|[ \t]|<br[^>]*>)+?|)</"+n+">|<br>$","i").test(e)},c=function(t){var e=parseInt(r.getItem(u(t)+"time"),10)||0;return!((new Date).getTime()-e>i(t.settings.autosave_retention,"20m")&&(f(t,!1),1))},f=function(t,e){var n=u(t);r.removeItem(n+"draft"),r.removeItem(n+"time"),!1!==e&&t.fire("RemoveDraft")},l=function(t){var e=u(t);!s(t)&&t.isDirty()&&(r.setItem(e+"draft",t.getContent({format:"raw",no_events:!0})),r.setItem(e+"time",(new Date).getTime().toString()),t.fire("StoreDraft"))},m=function(t){var e=u(t);c(t)&&(t.setContent(r.getItem(e+"draft"),{format:"raw"}),t.fire("RestoreDraft"))},v=function(t,e){var n=i(t.settings.autosave_interval,"30s");e.get()||(setInterval(function(){t.removed||l(t)},n),e.set(!0))},d=function(t){t.undoManager.transact(function(){m(t),f(t)}),t.focus()};function g(r){for(var o=[],t=1;t<arguments.length;t++)o[t-1]=arguments[t];return function(){for(var t=[],e=0;e<arguments.length;e++)t[e]=arguments[e];var n=o.concat(t);return r.apply(null,n)}}var y=tinymce.util.Tools.resolve("tinymce.EditorManager");y._beforeUnloadHandler=function(){var e;return o.each(y.get(),function(t){t.plugins.autosave&&t.plugins.autosave.storeDraft(),!e&&t.isDirty()&&t.getParam("autosave_ask_before_unload",!0)&&(e=t.translate("You have unsaved changes are you sure you want to navigate away?"))}),e};var p=function(n,r){return function(t){var e=t.control;e.disabled(!c(n)),n.on("StoreDraft RestoreDraft RemoveDraft",function(){e.disabled(!c(n))}),v(n,r)}};t.add("autosave",function(t){var e,n,r,o=a(!1);return window.onbeforeunload=y._beforeUnloadHandler,n=o,(e=t).addButton("restoredraft",{title:"Restore last draft",onclick:function(){d(e)},onPostRender:p(e,n)}),e.addMenuItem("restoredraft",{text:"Restore last draft",onclick:function(){d(e)},onPostRender:p(e,n),context:"file"}),t.on("init",function(){t.getParam("autosave_restore_when_empty",!1)&&t.dom.isEmpty(t.getBody())&&m(t)}),{hasDraft:g(c,r=t),storeDraft:g(l,r),restoreDraft:g(m,r),removeDraft:g(f,r),isEmpty:g(s,r)}})}();

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -87,6 +87,7 @@
<glyph unicode="&#xe906;" glyph-name="reload" d="M889.68 793.68c-93.608 102.216-228.154 166.32-377.68 166.32-282.77 0-512-229.23-512-512h96c0 229.75 186.25 416 416 416 123.020 0 233.542-53.418 309.696-138.306l-149.696-149.694h352v352l-134.32-134.32zM928 448c0-229.75-186.25-416-416-416-123.020 0-233.542 53.418-309.694 138.306l149.694 149.694h-352v-352l134.32 134.32c93.608-102.216 228.154-166.32 377.68-166.32 282.77 0 512 229.23 512 512h-96z" /> <glyph unicode="&#xe906;" glyph-name="reload" d="M889.68 793.68c-93.608 102.216-228.154 166.32-377.68 166.32-282.77 0-512-229.23-512-512h96c0 229.75 186.25 416 416 416 123.020 0 233.542-53.418 309.696-138.306l-149.696-149.694h352v352l-134.32-134.32zM928 448c0-229.75-186.25-416-416-416-123.020 0-233.542 53.418-309.694 138.306l149.694 149.694h-352v-352l134.32 134.32c93.608-102.216 228.154-166.32 377.68-166.32 282.77 0 512 229.23 512 512h-96z" />
<glyph unicode="&#xe907;" glyph-name="translate" d="M553.6 304l-118.4 118.4c80 89.6 137.6 195.2 172.8 304h137.6v92.8h-326.4v92.8h-92.8v-92.8h-326.4v-92.8h518.4c-32-89.6-80-176-147.2-249.6-44.8 48-80 99.2-108.8 156.8h-92.8c35.2-76.8 80-147.2 137.6-211.2l-236.8-233.6 67.2-67.2 233.6 233.6 144-144c3.2 0 38.4 92.8 38.4 92.8zM816 540.8h-92.8l-208-560h92.8l51.2 140.8h220.8l51.2-140.8h92.8l-208 560zM691.2 214.4l76.8 201.6 76.8-201.6h-153.6z" /> <glyph unicode="&#xe907;" glyph-name="translate" d="M553.6 304l-118.4 118.4c80 89.6 137.6 195.2 172.8 304h137.6v92.8h-326.4v92.8h-92.8v-92.8h-326.4v-92.8h518.4c-32-89.6-80-176-147.2-249.6-44.8 48-80 99.2-108.8 156.8h-92.8c35.2-76.8 80-147.2 137.6-211.2l-236.8-233.6 67.2-67.2 233.6 233.6 144-144c3.2 0 38.4 92.8 38.4 92.8zM816 540.8h-92.8l-208-560h92.8l51.2 140.8h220.8l51.2-140.8h92.8l-208 560zM691.2 214.4l76.8 201.6 76.8-201.6h-153.6z" />
<glyph unicode="&#xe908;" glyph-name="drag" d="M576 896h128v-128h-128v128zM576 640h128v-128h-128v128zM320 640h128v-128h-128v128zM576 384h128v-128h-128v128zM320 384h128v-128h-128v128zM320 128h128v-128h-128v128zM576 128h128v-128h-128v128zM320 896h128v-128h-128v128z" /> <glyph unicode="&#xe908;" glyph-name="drag" d="M576 896h128v-128h-128v128zM576 640h128v-128h-128v128zM320 640h128v-128h-128v128zM576 384h128v-128h-128v128zM320 384h128v-128h-128v128zM320 128h128v-128h-128v128zM576 128h128v-128h-128v128zM320 896h128v-128h-128v128z" />
<glyph unicode="&#xe909;" glyph-name="format-painter" d="M768 746.667v42.667c0 23.467-19.2 42.667-42.667 42.667h-512c-23.467 0-42.667-19.2-42.667-42.667v-170.667c0-23.467 19.2-42.667 42.667-42.667h512c23.467 0 42.667 19.2 42.667 42.667v42.667h42.667v-170.667h-426.667v-384c0-23.467 19.2-42.667 42.667-42.667h85.333c23.467 0 42.667 19.2 42.667 42.667v298.667h341.333v341.333h-128z" />
<glyph unicode="&#xe90b;" glyph-name="home" d="M1024 369.556l-512 397.426-512-397.428v162.038l512 397.426 512-397.428zM896 384v-384h-256v256h-256v-256h-256v384l384 288z" /> <glyph unicode="&#xe90b;" glyph-name="home" d="M1024 369.556l-512 397.426-512-397.428v162.038l512 397.426 512-397.428zM896 384v-384h-256v256h-256v-256h-256v384l384 288z" />
<glyph unicode="&#xe911;" glyph-name="books" d="M576.234 670.73l242.712 81.432 203.584-606.784-242.712-81.432zM0 64h256v704h-256v-704zM64 640h128v-64h-128v64zM320 64h256v704h-256v-704zM384 640h128v-64h-128v64z" /> <glyph unicode="&#xe911;" glyph-name="books" d="M576.234 670.73l242.712 81.432 203.584-606.784-242.712-81.432zM0 64h256v704h-256v-704zM64 640h128v-64h-128v64zM320 64h256v704h-256v-704zM384 640h128v-64h-128v64z" />
<glyph unicode="&#xe914;" glyph-name="upload" d="M839.432 760.57c27.492-27.492 50.554-78.672 55.552-120.57h-318.984v318.984c41.898-4.998 93.076-28.060 120.568-55.552l142.864-142.862zM512 576v384h-368c-44 0-80-36-80-80v-864c0-44 36-80 80-80h672c44 0 80 36 80 80v560h-384zM576 192v-192h-192v192h-160l256 256 256-256h-160z" /> <glyph unicode="&#xe914;" glyph-name="upload" d="M839.432 760.57c27.492-27.492 50.554-78.672 55.552-120.57h-318.984v318.984c41.898-4.998 93.076-28.060 120.568-55.552l142.864-142.862zM512 576v384h-368c-44 0-80-36-80-80v-864c0-44 36-80 80-80h672c44 0 80 36 80 80v560h-384zM576 192v-192h-192v192h-160l256 256 256-256h-160z" />

Before

Width:  |  Height:  |  Size: 45 KiB

After

Width:  |  Height:  |  Size: 45 KiB

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -25,11 +25,14 @@ In regards to development philosophy, BookStack has a relaxed, open & positive a
All development on BookStack is currently done on the master branch. When it's time for a release the master branch is merged into release with built & minified CSS & JS then tagged at its version. Here are the current development requirements: All development on BookStack is currently done on the master branch. When it's time for a release the master branch is merged into release with built & minified CSS & JS then tagged at its version. Here are the current development requirements:
* [Node.js](https://nodejs.org/en/) v6.9+ * [Node.js](https://nodejs.org/en/) v10.0+
SASS is used to help the CSS development and the JavaScript is run through babel to allow for writing ES6 code. This is done using webpack. To run the build task you can use the following commands: SASS is used to help the CSS development and the JavaScript is run through babel to allow for writing ES6 code. This is done using webpack. To run the build task you can use the following commands:
``` bash ``` bash
# Install NPM Dependencies
npm install
# Build assets for development # Build assets for development
npm run build npm run build
@ -40,7 +43,7 @@ npm run production
npm run dev npm run dev
``` ```
BookStack has many integration tests that use Laravel's built-in testing capabilities which makes use of PHPUnit. To use you will need PHPUnit installed and accessible via command line. There is a `mysql_testing` database defined within the app config which is what is used by PHPUnit. This database is set with the following database name, user name and password defined as `bookstack-test`. You will have to create that database and credentials before testing. BookStack has many integration tests that use Laravel's built-in testing capabilities which makes use of PHPUnit. To use you will need PHPUnit 6 installed and accessible via command line, Directly running the composer-installed version will not work. There is a `mysql_testing` database defined within the app config which is what is used by PHPUnit. This database is set with the following database name, user name and password defined as `bookstack-test`. You will have to create that database and credentials before testing.
The testing database will also need migrating and seeding beforehand. This can be done with the following commands: The testing database will also need migrating and seeding beforehand. This can be done with the following commands:
@ -53,7 +56,7 @@ Once done you can run `phpunit` in the application root directory to run all tes
## Translations ## Translations
As part of BookStack v0.14 support for translations has been built in. All text strings can be found in the `resources/lang` folder where each language option has its own folder. To add a new language you should copy the `en` folder to an new folder (eg. `fr` for french) then go through and translate all text strings in those files, leaving the keys and file-names intact. If a language string is missing then the `en` translation will be used. To show the language option in the user preferences language drop-down you will need to add your language to the options found at the bottom of the `resources/lang/en/settings.php` file. A system-wide language can also be set in the `.env` file like so: `APP_LANG=en`. All text strings can be found in the `resources/lang` folder where each language option has its own folder. To add a new language you should copy the `en` folder to an new folder (eg. `fr` for french) then go through and translate all text strings in those files, leaving the keys and file-names intact. If a language string is missing then the `en` translation will be used. To show the language option in the user preferences language drop-down you will need to add your language to the options found at the bottom of the `resources/lang/en/settings.php` file. A system-wide language can also be set in the `.env` file like so: `APP_LANG=en`.
You will also need to add the language to the `locales` array in the `config/app.php` file. You will also need to add the language to the `locales` array in the `config/app.php` file.
@ -70,7 +73,7 @@ php resources/lang/check.php pt_BR
Some strings have colon-prefixed variables in such as `:userName`. Leave these values as they are as they will be replaced at run-time. Some strings have colon-prefixed variables in such as `:userName`. Leave these values as they are as they will be replaced at run-time.
## Contributing & Maintenence ## Contributing & Maintenance
Feel free to create issues to request new features or to report bugs and problems. Just please follow the template given when creating the issue. Feel free to create issues to request new features or to report bugs and problems. Just please follow the template given when creating the issue.

View File

@ -52,7 +52,7 @@ const modeMap = {
sh: 'shell', sh: 'shell',
bash: 'shell', bash: 'shell',
toml: 'toml', toml: 'toml',
sql: 'sql', sql: 'text/x-sql',
xml: 'xml', xml: 'xml',
yaml: 'yaml', yaml: 'yaml',
yml: 'yaml', yml: 'yaml',

View File

@ -10,22 +10,28 @@ const props = ['placeholder', 'uploadUrl', 'uploadedTo'];
// TODO - Remove jQuery usage // TODO - Remove jQuery usage
function mounted() { function mounted() {
let container = this.$el; const container = this.$el;
let _this = this; const _this = this;
this._dz = new DropZone(container, { this._dz = new DropZone(container, {
addRemoveLinks: true, addRemoveLinks: true,
dictRemoveFile: trans('components.image_upload_remove'), dictRemoveFile: trans('components.image_upload_remove'),
timeout: Number(window.uploadTimeout) || 60000,
url: function() { url: function() {
return _this.uploadUrl; return _this.uploadUrl;
}, },
init: function () { init: function () {
let dz = this; const dz = this;
dz.on('sending', function (file, xhr, data) { dz.on('sending', function (file, xhr, data) {
let token = window.document.querySelector('meta[name=token]').getAttribute('content'); const token = window.document.querySelector('meta[name=token]').getAttribute('content');
data.append('_token', token); data.append('_token', token);
let uploadedTo = typeof _this.uploadedTo === 'undefined' ? 0 : _this.uploadedTo; const uploadedTo = typeof _this.uploadedTo === 'undefined' ? 0 : _this.uploadedTo;
data.append('uploaded_to', uploadedTo); data.append('uploaded_to', uploadedTo);
xhr.ontimeout = function (e) {
dz.emit('complete', file);
dz.emit('error', file, trans('errors.file_upload_timeout'));
}
}); });
dz.on('success', function (file, data) { dz.on('success', function (file, data) {
@ -42,8 +48,11 @@ function mounted() {
$(file.previewElement).find('[data-dz-errormessage]').text(message); $(file.previewElement).find('[data-dz-errormessage]').text(message);
} }
if (xhr && xhr.status === 413) setMessage(trans('errors.server_upload_limit')); if (xhr && xhr.status === 413) {
else if (errorMessage.file) setMessage(errorMessage.file); setMessage(trans('errors.server_upload_limit'))
} else if (errorMessage.file) {
setMessage(errorMessage.file);
}
}); });
} }

View File

@ -54,3 +54,8 @@
.mce-colorbtn-trans { .mce-colorbtn-trans {
overflow: hidden; overflow: hidden;
} }
// Fix to prevent CodeMirror focus events throwing TinyMCE cursor position.
.mce-content-body .CodeMirrorContainer > .CodeMirror {
pointer-events: none;
}

View File

@ -38,6 +38,7 @@ return [
'uploaded' => 'الخادم لا يسمح برفع ملفات بهذا الحجم. الرجاء محاولة الرفع بحجم أصغر.', 'uploaded' => 'الخادم لا يسمح برفع ملفات بهذا الحجم. الرجاء محاولة الرفع بحجم أصغر.',
'image_upload_error' => 'حدث خطأ خلال رفع الصورة', 'image_upload_error' => 'حدث خطأ خلال رفع الصورة',
'image_upload_type_error' => 'صيغة الصورة المرفوعة غير صالحة', 'image_upload_type_error' => 'صيغة الصورة المرفوعة غير صالحة',
'file_upload_timeout' => 'انتهت عملية تحميل الملف.',
// Attachments // Attachments
'attachment_page_mismatch' => 'Page mismatch during attachment update', // جار البحث عن الترجمة الأنسب 'attachment_page_mismatch' => 'Page mismatch during attachment update', // جار البحث عن الترجمة الأنسب

View File

@ -32,6 +32,8 @@ return [
'server_upload_limit' => 'Der Server verbietet das Hochladen von Dateien mit dieser Dateigröße. Bitte versuchen Sie es mit einer kleineren Datei.', 'server_upload_limit' => 'Der Server verbietet das Hochladen von Dateien mit dieser Dateigröße. Bitte versuchen Sie es mit einer kleineren Datei.',
'image_upload_error' => 'Beim Hochladen des Bildes trat ein Fehler auf.', 'image_upload_error' => 'Beim Hochladen des Bildes trat ein Fehler auf.',
'image_upload_type_error' => 'Der Bildtyp der hochgeladenen Datei ist ungültig.', 'image_upload_type_error' => 'Der Bildtyp der hochgeladenen Datei ist ungültig.',
'file_upload_timeout' => 'Der Upload der Datei ist abgelaufen.',
// Attachments // Attachments
'attachment_page_mismatch' => 'Die Seite stimmte nach dem Hochladen des Anhangs nicht überein.', 'attachment_page_mismatch' => 'Die Seite stimmte nach dem Hochladen des Anhangs nicht überein.',
'attachment_not_found' => 'Anhang konnte nicht gefunden werden.', 'attachment_not_found' => 'Anhang konnte nicht gefunden werden.',

View File

@ -0,0 +1,6 @@
<?php
// Extends 'de'
return [
//
];

View File

@ -0,0 +1,47 @@
<?php
// Extends 'de'
return [
/*
|--------------------------------------------------------------------------
| Authentication Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used during authentication for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/
'throttle' => 'Zu viele Anmeldeversuche. Bitte versuche es in :seconds Sekunden erneut.',
/**
* Login & Register
*/
'ldap_email_hint' => 'Bitte gib eine E-Mail-Adresse ein, um diese mit dem Account zu nutzen.',
'register_confirm' => 'Bitte prüfe Deinen Posteingang und bestätig die Registrierung.',
'registration_email_domain_invalid' => 'Du kannst dich mit dieser E-Mail nicht registrieren.',
'register_success' => 'Vielen Dank für Deine Registrierung! Die Daten sind gespeichert und Du bist angemeldet.',
/**
* Password Reset
*/
'reset_password_send_instructions' => 'Bitte gib Deine E-Mail-Adresse ein. Danach erhältst Du eine E-Mail mit einem Link zum Zurücksetzen Deines Passwortes.',
'reset_password_sent_success' => 'Eine E-Mail mit dem Link zum Zurücksetzen Deines Passwortes wurde an :email gesendet.',
'reset_password_success' => 'Dein Passwort wurde erfolgreich zurückgesetzt.',
'email_reset_text' => 'Du erhältsts diese E-Mail, weil jemand versucht hat, Dein Passwort zurückzusetzen.',
'email_reset_not_requested' => 'Wenn Du das nicht warst, brauchst Du nichts weiter zu tun.',
/**
* Email Confirmation
*/
'email_confirm_subject' => 'Bestätige Deine E-Mail-Adresse für :appName',
'email_confirm_greeting' => 'Danke, dass Du dich für :appName registrierst hast!',
'email_confirm_text' => 'Bitte bestätige Deine E-Mail-Adresse, indem Du auf die Schaltfläche klickst:',
'email_confirm_send_error' => 'Leider konnte die für die Registrierung notwendige E-Mail zur Bestätigung Deine E-Mail-Adresse nicht versandt werden. Bitte kontaktiere den Systemadministrator!',
'email_confirm_success' => 'Deine E-Mail-Adresse wurde best&auml;tigt!',
'email_confirm_resent' => 'Bestätigungs-E-Mail wurde erneut versendet, bitte überprüfe Deinen Posteingang.',
'email_not_confirmed_text' => 'Deine E-Mail-Adresse ist bisher nicht bestätigt.',
'email_not_confirmed_click_link' => 'Bitte klicke auf den Link in der E-Mail, die Du nach der Registrierung erhalten hast.',
'email_not_confirmed_resend' => 'Wenn Du die E-Mail nicht erhalten hast, kannst Du die Nachricht erneut anfordern. Fülle hierzu bitte das folgende Formular aus:',
];

View File

@ -0,0 +1,9 @@
<?php
// Extends 'de'
return [
/**
* Email Content
*/
'email_action_help' => 'Sollte es beim Anklicken der Schaltfläche ":action_text" Probleme geben, öffne die folgende URL in Deinem Browser:',
];

View File

@ -0,0 +1,10 @@
<?php
// Extends 'de'
return [
/**
* Image Manager
*/
'image_delete_confirm' => 'Bitte klicke erneut auf löschen, wenn Du dieses Bild wirklich entfernen möchtest.',
'image_dropzone' => 'Ziehe Bilder hierher oder klicke hier, um ein Bild auszuwählen',
];

View File

@ -0,0 +1,57 @@
<?php
// Extends 'de'
return [
/**
* Shared
*/
'no_pages_viewed' => 'Du hast bisher keine Seiten angesehen.',
'no_pages_recently_created' => 'Du hast bisher keine Seiten angelegt.',
'no_pages_recently_updated' => 'Du hast bisher keine Seiten aktualisiert.',
/**
* Books
*/
'books_delete_confirmation' => 'Bist Du sicher, dass Du dieses Buch löschen möchtest?',
/**
* Chapters
*/
'chapters_delete_confirm' => 'Bist Du sicher, dass Du dieses Kapitel löschen möchtest?',
/**
* Pages
*/
'pages_delete_confirm' => 'Bist Du sicher, dass Du diese Seite löschen möchtest?',
'pages_delete_draft_confirm' => 'Bist Du sicher, dass Du diesen Seitenentwurf löschen möchtest?',
'pages_edit_enter_changelog_desc' => 'Bitte gib eine kurze Zusammenfassung Deiner Änderungen ein',
'pages_editing_draft_notification' => 'Du bearbeitest momenten einen Entwurf, der zuletzt :timeDiff gespeichert wurde.',
'pages_draft_edit_active' => [
'start_a' => ':count Benutzer bearbeiten derzeit diese Seite.',
'start_b' => ':userName bearbeitet jetzt diese Seite.',
'time_a' => 'seit die Seiten zuletzt aktualisiert wurden.',
'time_b' => 'in den letzten :minCount Minuten',
'message' => ':start :time. Achte darauf, keine Änderungen von anderen Benutzern zu überschreiben!',
],
/**
* Editor sidebar
*/
'tags_explain' => "Füge Schlagwörter hinzu, um ihren Inhalt zu kategorisieren.\nDu kannst einen erklärenden Inhalt hinzufügen, um eine genauere Unterteilung vorzunehmen.",
'attachments_explain' => 'Du kannst auf Deiner Seite Dateien hochladen oder Links hinzufügen. Diese werden in der Seitenleiste angezeigt.',
'attachments_delete_confirm' => 'Klicke erneut auf löschen, um diesen Anhang zu entfernen.',
'attachments_dropzone' => 'Ziehe Dateien hierher oder klicke hier, um eine Datei auszuwählen',
'attachments_explain_link' => 'Wenn Du keine Datei hochladen möchtest, kannst Du stattdessen einen Link hinzufügen. Dieser Link kann auf eine andere Seite oder eine Datei im Internet verweisen.',
'attachments_edit_drop_upload' => 'Ziehe Dateien hierher, um diese hochzuladen und zu überschreiben',
/**
* Comments
*/
'comment_placeholder' => 'Gib hier Deine Kommentare ein (Markdown unterstützt)',
'comment_delete_confirm' => 'Möchtst Du diesen Kommentar wirklich löschen?',
/**
* Revision
*/
'revision_delete_confirm' => 'Bist Du sicher, dass Du diese Revision löschen möchtest?',
];

View File

@ -0,0 +1,32 @@
<?php
// Extends 'de'
return [
// Pages
'permission' => 'Du hast keine Berechtigung, auf diese Seite zuzugreifen.',
'permissionJson' => 'Du hast keine Berechtigung, die angeforderte Aktion auszuführen.',
// Auth
'email_already_confirmed' => 'Die E-Mail-Adresse ist bereits bestätigt. Bitte melde dich an.',
'email_confirmation_invalid' => 'Der Bestätigungslink ist nicht gültig oder wurde bereits verwendet. Bitte registriere dich erneut.',
'social_account_in_use' => 'Dieses :socialAccount-Konto wird bereits verwendet. Bitte melde dich mit dem :socialAccount-Konto an.',
'social_account_email_in_use' => 'Die E-Mail-Adresse ":email" ist bereits registriert. Wenn Du bereits registriert bist, kannst Du Dein :socialAccount-Konto in Deinen Profil-Einstellungen verknüpfen.',
'social_account_not_used' => 'Dieses :socialAccount-Konto ist bisher keinem Benutzer zugeordnet. Du kannst das in Deinen Profil-Einstellungen tun.',
'social_account_register_instructions' => 'Wenn Du bisher kein Social-Media Konto besitzt, kannst Du ein solches Konto mit der :socialAccount Option anlegen.',
// System
'path_not_writable' => 'Die Datei kann nicht in den angegebenen Pfad :filePath hochgeladen werden. Stelle sicher, dass dieser Ordner auf dem Server beschreibbar ist.',
'cannot_create_thumbs' => 'Der Server kann keine Vorschau-Bilder erzeugen. Bitte prüfe, ob die GD PHP-Erweiterung installiert ist.',
'server_upload_limit' => 'Der Server verbietet das Hochladen von Dateien mit dieser Dateigröße. Bitte versuche es mit einer kleineren Datei.',
// Pages
'page_draft_autosave_fail' => 'Fehler beim Speichern des Entwurfs. Stelle sicher, dass Du mit dem Internet verbunden bist, bevor Du den Entwurf dieser Seite speicherst.',
'page_custom_home_deletion' => 'Eine als Startseite gesetzte Seite kann nicht gelöscht werden.',
// Users
'users_cannot_delete_only_admin' => 'Du kannst den einzigen Administrator nicht löschen.',
'users_cannot_delete_guest' => 'Du kannst den Gast-Benutzer nicht löschen',
// Error pages
'sorry_page_not_found' => 'Entschuldigung. Die Seite, die Du angefordert hast, wurde nicht gefunden.',
];

View File

@ -0,0 +1,6 @@
<?php
// Extends 'de'
return [
//
];

View File

@ -0,0 +1,6 @@
<?php
// Extends 'de'
return [
//
];

View File

@ -0,0 +1,38 @@
<?php
// Extends 'de'
return [
/**
* Settings text strings
* Contains all text strings used in the general settings sections of BookStack
* including users and roles.
*/
/**
* App settings
*/
'app_editor_desc' => 'Wähle den Editor aus, der von allen Benutzern genutzt werden soll, um Seiten zu editieren.',
'app_primary_color_desc' => "Dies sollte ein HEX Wert sein.\nWenn Du nichts eingibst, wird die Anwendung auf die Standardfarbe zurückgesetzt.",
'app_homepage_desc' => 'Wähle eine Seite als Startseite aus, die statt der Standardansicht angezeigt werden soll. Seitenberechtigungen werden für die ausgewählten Seiten ignoriert.',
'app_homepage_books' => 'Oder wähle die Buch-Übersicht als Startseite. Das wird die Seiten-Auswahl überschreiben.',
/**
* Maintenance settings
*/
'maint_image_cleanup_desc' => 'Überprüft Seiten- und Versionsinhalte auf ungenutzte und mehrfach vorhandene Bilder. Erstelle vor dem Start ein Backup Deiner Datenbank und Bilder.',
'maint_image_cleanup_warning' => ':count eventuell unbenutze Bilder wurden gefunden. Möchtest Du diese Bilder löschen?',
/**
* Role settings
*/
'role_delete_confirm' => 'Du möchtest die Rolle ":roleName" löschen.',
'role_delete_users_assigned' => 'Diese Rolle ist :userCount Benutzern zugeordnet. Du kannst unten eine neue Rolle auswählen, die Du diesen Benutzern zuordnen möchtest.',
'role_delete_sure' => 'Bist Du sicher, dass Du diese Rolle löschen möchtest?',
/**
* Users
*/
'users_password_warning' => 'Fülle die folgenden Felder nur aus, wenn Du Dein Passwort ändern möchtest:',
'users_delete_confirm' => 'Bist Du sicher, dass Du diesen Benutzer löschen möchtest?',
'users_social_accounts_info' => 'Hier kannst Du andere Social-Media-Konten für eine schnellere und einfachere Anmeldung verknüpfen. Wenn Du ein Social-Media Konto löschst, bleibt der Zugriff erhalten. Entferne in diesem Falle die Berechtigung in Deinen Profil-Einstellungen des verknüpften Social-Media-Kontos.',
];

View File

@ -0,0 +1,6 @@
<?php
// Extends 'de'
return [
//
];

View File

@ -1,11 +1,9 @@
<?php <?php
return [
/** /**
* Activity text strings. * Activity text strings.
* Is used for all the text within activity logs & notifications. * Is used for all the text within activity logs & notifications.
*/ */
return [
// Pages // Pages
'page_create' => 'created page', 'page_create' => 'created page',

View File

@ -1,21 +1,15 @@
<?php <?php
return [ /**
/* * Authentication Language Lines
|-------------------------------------------------------------------------- * The following language lines are used during authentication for various
| Authentication Language Lines * messages that we need to display to the user.
|--------------------------------------------------------------------------
|
| The following language lines are used during authentication for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/ */
return [
'failed' => 'These credentials do not match our records.', 'failed' => 'These credentials do not match our records.',
'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.',
/** // Login & Register
* Login & Register
*/
'sign_up' => 'Sign up', 'sign_up' => 'Sign up',
'log_in' => 'Log in', 'log_in' => 'Log in',
'log_in_with' => 'Login with :socialDriver', 'log_in_with' => 'Login with :socialDriver',
@ -43,23 +37,18 @@ return [
'register_success' => 'Thanks for signing up! You are now registered and signed in.', 'register_success' => 'Thanks for signing up! You are now registered and signed in.',
/** // Password Reset
* Password Reset
*/
'reset_password' => 'Reset Password', 'reset_password' => 'Reset Password',
'reset_password_send_instructions' => 'Enter your email below and you will be sent an email with a password reset link.', 'reset_password_send_instructions' => 'Enter your email below and you will be sent an email with a password reset link.',
'reset_password_send_button' => 'Send Reset Link', 'reset_password_send_button' => 'Send Reset Link',
'reset_password_sent_success' => 'A password reset link has been sent to :email.', 'reset_password_sent_success' => 'A password reset link has been sent to :email.',
'reset_password_success' => 'Your password has been successfully reset.', 'reset_password_success' => 'Your password has been successfully reset.',
'email_reset_subject' => 'Reset your :appName password', 'email_reset_subject' => 'Reset your :appName password',
'email_reset_text' => 'You are receiving this email because we received a password reset request for your account.', 'email_reset_text' => 'You are receiving this email because we received a password reset request for your account.',
'email_reset_not_requested' => 'If you did not request a password reset, no further action is required.', 'email_reset_not_requested' => 'If you did not request a password reset, no further action is required.',
/** // Email Confirmation
* Email Confirmation
*/
'email_confirm_subject' => 'Confirm your email on :appName', 'email_confirm_subject' => 'Confirm your email on :appName',
'email_confirm_greeting' => 'Thanks for joining :appName!', 'email_confirm_greeting' => 'Thanks for joining :appName!',
'email_confirm_text' => 'Please confirm your email address by clicking the button below:', 'email_confirm_text' => 'Please confirm your email address by clicking the button below:',

View File

@ -1,9 +1,10 @@
<?php <?php
/**
* Common elements found throughout many areas of BookStack.
*/
return [ return [
/** // Buttons
* Buttons
*/
'cancel' => 'Cancel', 'cancel' => 'Cancel',
'confirm' => 'Confirm', 'confirm' => 'Confirm',
'back' => 'Back', 'back' => 'Back',
@ -12,18 +13,14 @@ return [
'select' => 'Select', 'select' => 'Select',
'more' => 'More', 'more' => 'More',
/** // Form Labels
* Form Labels
*/
'name' => 'Name', 'name' => 'Name',
'description' => 'Description', 'description' => 'Description',
'role' => 'Role', 'role' => 'Role',
'cover_image' => 'Cover image', 'cover_image' => 'Cover image',
'cover_image_description' => 'This image should be approx 440x250px.', 'cover_image_description' => 'This image should be approx 440x250px.',
/** // Actions
* Actions
*/
'actions' => 'Actions', 'actions' => 'Actions',
'view' => 'View', 'view' => 'View',
'create' => 'Create', 'create' => 'Create',
@ -40,16 +37,12 @@ return [
'remove' => 'Remove', 'remove' => 'Remove',
'add' => 'Add', 'add' => 'Add',
/** // Sort Options
* Sort Options
*/
'sort_name' => 'Name', 'sort_name' => 'Name',
'sort_created_at' => 'Created Date', 'sort_created_at' => 'Created Date',
'sort_updated_at' => 'Updated Date', 'sort_updated_at' => 'Updated Date',
/** // Misc
* Misc
*/
'deleted_user' => 'Deleted User', 'deleted_user' => 'Deleted User',
'no_activity' => 'No activity to show', 'no_activity' => 'No activity to show',
'no_items' => 'No items available', 'no_items' => 'No items available',
@ -61,15 +54,11 @@ return [
'list_view' => 'List View', 'list_view' => 'List View',
'default' => 'Default', 'default' => 'Default',
/** // Header
* Header
*/
'view_profile' => 'View Profile', 'view_profile' => 'View Profile',
'edit_profile' => 'Edit Profile', 'edit_profile' => 'Edit Profile',
/** // Email Content
* Email Content
*/
'email_action_help' => 'If youre having trouble clicking the ":actionText" button, copy and paste the URL below into your web browser:', 'email_action_help' => 'If youre having trouble clicking the ":actionText" button, copy and paste the URL below into your web browser:',
'email_rights' => 'All rights reserved', 'email_rights' => 'All rights reserved',
]; ];

View File

@ -1,9 +1,10 @@
<?php <?php
/**
* Text used in custom JavaScript driven components.
*/
return [ return [
/** // Image Manager
* Image Manager
*/
'image_select' => 'Image Select', 'image_select' => 'Image Select',
'image_all' => 'All', 'image_all' => 'All',
'image_all_title' => 'View all images', 'image_all_title' => 'View all images',
@ -24,9 +25,7 @@ return [
'image_delete_success' => 'Image successfully deleted', 'image_delete_success' => 'Image successfully deleted',
'image_upload_remove' => 'Remove', 'image_upload_remove' => 'Remove',
/** // Code Editor
* Code editor
*/
'code_editor' => 'Edit Code', 'code_editor' => 'Edit Code',
'code_language' => 'Code Language', 'code_language' => 'Code Language',
'code_content' => 'Code Content', 'code_content' => 'Code Content',

View File

@ -1,9 +1,11 @@
<?php <?php
/**
* Text used for 'Entities' (Document Structure Elements) such as
* Books, Shelves, Chapters & Pages
*/
return [ return [
/** // Shared
* Shared
*/
'recently_created' => 'Recently Created', 'recently_created' => 'Recently Created',
'recently_created_pages' => 'Recently Created Pages', 'recently_created_pages' => 'Recently Created Pages',
'recently_updated_pages' => 'Recently Updated Pages', 'recently_updated_pages' => 'Recently Updated Pages',
@ -31,17 +33,13 @@ return [
'export_pdf' => 'PDF File', 'export_pdf' => 'PDF File',
'export_text' => 'Plain Text File', 'export_text' => 'Plain Text File',
/** // Permissions and restrictions
* Permissions and restrictions
*/
'permissions' => 'Permissions', 'permissions' => 'Permissions',
'permissions_intro' => 'Once enabled, These permissions will take priority over any set role permissions.', 'permissions_intro' => 'Once enabled, These permissions will take priority over any set role permissions.',
'permissions_enable' => 'Enable Custom Permissions', 'permissions_enable' => 'Enable Custom Permissions',
'permissions_save' => 'Save Permissions', 'permissions_save' => 'Save Permissions',
/** // Search
* Search
*/
'search_results' => 'Search Results', 'search_results' => 'Search Results',
'search_total_results_found' => ':count result found|:count total results found', 'search_total_results_found' => ':count result found|:count total results found',
'search_clear' => 'Clear Search', 'search_clear' => 'Clear Search',
@ -66,9 +64,7 @@ return [
'search_set_date' => 'Set Date', 'search_set_date' => 'Set Date',
'search_update' => 'Update Search', 'search_update' => 'Update Search',
/** // Shelves
* Shelves
*/
'shelf' => 'Shelf', 'shelf' => 'Shelf',
'shelves' => 'Shelves', 'shelves' => 'Shelves',
'shelves_long' => 'Bookshelves', 'shelves_long' => 'Bookshelves',
@ -98,9 +94,7 @@ return [
'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this bookshelf to all books contained within. Before activating, ensure any changes to the permissions of this bookshelf have been saved.', 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this bookshelf to all books contained within. Before activating, ensure any changes to the permissions of this bookshelf have been saved.',
'shelves_copy_permission_success' => 'Bookshelf permissions copied to :count books', 'shelves_copy_permission_success' => 'Bookshelf permissions copied to :count books',
/** // Books
* Books
*/
'book' => 'Book', 'book' => 'Book',
'books' => 'Books', 'books' => 'Books',
'x_books' => ':count Book|:count Books', 'x_books' => ':count Book|:count Books',
@ -134,9 +128,7 @@ return [
'books_sort_show_other' => 'Show Other Books', 'books_sort_show_other' => 'Show Other Books',
'books_sort_save' => 'Save New Order', 'books_sort_save' => 'Save New Order',
/** // Chapters
* Chapters
*/
'chapter' => 'Chapter', 'chapter' => 'Chapter',
'chapters' => 'Chapters', 'chapters' => 'Chapters',
'x_chapters' => ':count Chapter|:count Chapters', 'x_chapters' => ':count Chapter|:count Chapters',
@ -159,9 +151,7 @@ return [
'chapters_permissions_success' => 'Chapter Permissions Updated', 'chapters_permissions_success' => 'Chapter Permissions Updated',
'chapters_search_this' => 'Search this chapter', 'chapters_search_this' => 'Search this chapter',
/** // Pages
* Pages
*/
'page' => 'Page', 'page' => 'Page',
'pages' => 'Pages', 'pages' => 'Pages',
'x_pages' => ':count Page|:count Pages', 'x_pages' => ':count Page|:count Pages',
@ -235,9 +225,7 @@ return [
'pages_draft_discarded' => 'Draft discarded, The editor has been updated with the current page content', 'pages_draft_discarded' => 'Draft discarded, The editor has been updated with the current page content',
'pages_specific' => 'Specific Page', 'pages_specific' => 'Specific Page',
/** // Editor Sidebar
* Editor sidebar
*/
'page_tags' => 'Page Tags', 'page_tags' => 'Page Tags',
'chapter_tags' => 'Chapter Tags', 'chapter_tags' => 'Chapter Tags',
'book_tags' => 'Book Tags', 'book_tags' => 'Book Tags',
@ -273,18 +261,14 @@ return [
'attachments_file_updated' => 'File successfully updated', 'attachments_file_updated' => 'File successfully updated',
'attachments_link_attached' => 'Link successfully attached to page', 'attachments_link_attached' => 'Link successfully attached to page',
/** // Profile View
* Profile View
*/
'profile_user_for_x' => 'User for :time', 'profile_user_for_x' => 'User for :time',
'profile_created_content' => 'Created Content', 'profile_created_content' => 'Created Content',
'profile_not_created_pages' => ':userName has not created any pages', 'profile_not_created_pages' => ':userName has not created any pages',
'profile_not_created_chapters' => ':userName has not created any chapters', 'profile_not_created_chapters' => ':userName has not created any chapters',
'profile_not_created_books' => ':userName has not created any books', 'profile_not_created_books' => ':userName has not created any books',
/** // Comments
* Comments
*/
'comment' => 'Comment', 'comment' => 'Comment',
'comments' => 'Comments', 'comments' => 'Comments',
'comment_add' => 'Add Comment', 'comment_add' => 'Add Comment',
@ -302,9 +286,7 @@ return [
'comment_delete_confirm' => 'Are you sure you want to delete this comment?', 'comment_delete_confirm' => 'Are you sure you want to delete this comment?',
'comment_in_reply_to' => 'In reply to :commentId', 'comment_in_reply_to' => 'In reply to :commentId',
/** // Revision
* Revision
*/
'revision_delete_confirm' => 'Are you sure you want to delete this revision?', 'revision_delete_confirm' => 'Are you sure you want to delete this revision?',
'revision_delete_success' => 'Revision deleted', 'revision_delete_success' => 'Revision deleted',
'revision_cannot_delete_latest' => 'Cannot delete the latest revision.' 'revision_cannot_delete_latest' => 'Cannot delete the latest revision.'

View File

@ -1,10 +1,8 @@
<?php <?php
return [
/** /**
* Error text strings. * Text shown in error messaging.
*/ */
return [
// Permissions // Permissions
'permission' => 'You do not have permission to access the requested page.', 'permission' => 'You do not have permission to access the requested page.',
@ -38,6 +36,7 @@ return [
'uploaded' => 'The server does not allow uploads of this size. Please try a smaller file size.', 'uploaded' => 'The server does not allow uploads of this size. Please try a smaller file size.',
'image_upload_error' => 'An error occurred uploading the image', 'image_upload_error' => 'An error occurred uploading the image',
'image_upload_type_error' => 'The image type being uploaded is invalid', 'image_upload_type_error' => 'The image type being uploaded is invalid',
'file_upload_timeout' => 'The file upload has timed out.',
// Attachments // Attachments
'attachment_page_mismatch' => 'Page mismatch during attachment update', 'attachment_page_mismatch' => 'Page mismatch during attachment update',
@ -65,6 +64,7 @@ return [
'role_cannot_be_edited' => 'This role cannot be edited', 'role_cannot_be_edited' => 'This role cannot be edited',
'role_system_cannot_be_deleted' => 'This role is a system role and cannot be deleted', 'role_system_cannot_be_deleted' => 'This role is a system role and cannot be deleted',
'role_registration_default_cannot_delete' => 'This role cannot be deleted while set as the default registration role', 'role_registration_default_cannot_delete' => 'This role cannot be deleted while set as the default registration role',
'role_cannot_remove_only_admin' => 'This user is the only user assigned to the administrator role. Assign the administrator role to another user before attempting to remove it here.',
// Comments // Comments
'comment_list' => 'An error occurred while fetching the comments.', 'comment_list' => 'An error occurred while fetching the comments.',
@ -80,4 +80,5 @@ return [
'error_occurred' => 'An Error Occurred', 'error_occurred' => 'An Error Occurred',
'app_down' => ':appName is down right now', 'app_down' => ':appName is down right now',
'back_soon' => 'It will be back up soon.', 'back_soon' => 'It will be back up soon.',
]; ];

View File

@ -1,17 +1,10 @@
<?php <?php
/**
return [ * Pagination Language Lines
* The following language lines are used by the paginator library to build
/* * the simple pagination links.
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/ */
return [
'previous' => '&laquo; Previous', 'previous' => '&laquo; Previous',
'next' => 'Next &raquo;', 'next' => 'Next &raquo;',

View File

@ -1,17 +1,10 @@
<?php <?php
/**
return [ * Password Reminder Language Lines
* The following language lines are the default lines which match reasons
/* * that are given by the password broker for a password update attempt has failed.
|--------------------------------------------------------------------------
| Password Reminder Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| has failed, such as for an invalid token or invalid new password.
|
*/ */
return [
'password' => 'Passwords must be at least six characters and match the confirmation.', 'password' => 'Passwords must be at least six characters and match the confirmation.',
'user' => "We can't find a user with that e-mail address.", 'user' => "We can't find a user with that e-mail address.",

View File

@ -1,21 +1,17 @@
<?php <?php
return [
/** /**
* Settings text strings * Settings text strings
* Contains all text strings used in the general settings sections of BookStack * Contains all text strings used in the general settings sections of BookStack
* including users and roles. * including users and roles.
*/ */
return [
// Common Messages
'settings' => 'Settings', 'settings' => 'Settings',
'settings_save' => 'Save Settings', 'settings_save' => 'Save Settings',
'settings_save_success' => 'Settings saved', 'settings_save_success' => 'Settings saved',
/** // App Settings
* App settings
*/
'app_settings' => 'App Settings', 'app_settings' => 'App Settings',
'app_name' => 'Application name', 'app_name' => 'Application name',
'app_name_desc' => 'This name is shown in the header and any emails.', 'app_name_desc' => 'This name is shown in the header and any emails.',
@ -37,10 +33,7 @@ return [
'app_disable_comments' => 'Disable comments', 'app_disable_comments' => 'Disable comments',
'app_disable_comments_desc' => 'Disable comments across all pages in the application. Existing comments are not shown.', 'app_disable_comments_desc' => 'Disable comments across all pages in the application. Existing comments are not shown.',
/** // Registration Settings
* Registration settings
*/
'reg_settings' => 'Registration Settings', 'reg_settings' => 'Registration Settings',
'reg_allow' => 'Allow registration?', 'reg_allow' => 'Allow registration?',
'reg_default_role' => 'Default user role after registration', 'reg_default_role' => 'Default user role after registration',
@ -50,10 +43,7 @@ return [
'reg_confirm_restrict_domain_desc' => 'Enter a comma separated list of email domains you would like to restrict registration to. Users will be sent an email to confirm their address before being allowed to interact with the application. <br> Note that users will be able to change their email addresses after successful registration.', 'reg_confirm_restrict_domain_desc' => 'Enter a comma separated list of email domains you would like to restrict registration to. Users will be sent an email to confirm their address before being allowed to interact with the application. <br> Note that users will be able to change their email addresses after successful registration.',
'reg_confirm_restrict_domain_placeholder' => 'No restriction set', 'reg_confirm_restrict_domain_placeholder' => 'No restriction set',
/** // Maintenance settings
* Maintenance settings
*/
'maint' => 'Maintenance', 'maint' => 'Maintenance',
'maint_image_cleanup' => 'Cleanup Images', '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.",
@ -63,10 +53,7 @@ return [
'maint_image_cleanup_success' => ':count potentially unused images found and deleted!', 'maint_image_cleanup_success' => ':count potentially unused images found and deleted!',
'maint_image_cleanup_nothing_found' => 'No unused images found, Nothing deleted!', 'maint_image_cleanup_nothing_found' => 'No unused images found, Nothing deleted!',
/** // Role Settings
* Role settings
*/
'roles' => 'Roles', 'roles' => 'Roles',
'role_user_roles' => 'User Roles', 'role_user_roles' => 'User Roles',
'role_create' => 'Create New Role', 'role_create' => 'Create New Role',
@ -99,10 +86,7 @@ return [
'role_users' => 'Users in this role', 'role_users' => 'Users in this role',
'role_users_none' => 'No users are currently assigned to this role', 'role_users_none' => 'No users are currently assigned to this role',
/** // Users
* Users
*/
'users' => 'Users', 'users' => 'Users',
'user_profile' => 'User Profile', 'user_profile' => 'User Profile',
'users_add_new' => 'Add New User', 'users_add_new' => 'Add New User',
@ -129,14 +113,15 @@ return [
'users_social_connected' => ':socialAccount account was successfully attached to your profile.', 'users_social_connected' => ':socialAccount account was successfully attached to your profile.',
'users_social_disconnected' => ':socialAccount account was successfully disconnected from your profile.', 'users_social_disconnected' => ':socialAccount account was successfully disconnected from your profile.',
// Since these labels are already localized this array does not need to be //! Since these labels are already localized this array does not need to be
// translated in the language-specific files. //! translated in the language-specific files.
// DELETE BELOW IF COPIED FROM EN //! DELETE BELOW IF COPIED FROM EN
/////////////////////////////////// //!////////////////////////////////
'language_select' => [ 'language_select' => [
'en' => 'English', 'en' => 'English',
'ar' => 'العربية', 'ar' => 'العربية',
'de' => 'Deutsch', 'de' => 'Deutsch (Sie)',
'de_informal' => 'Deutsch (Du)',
'es' => 'Español', 'es' => 'Español',
'es_AR' => 'Español Argentina', 'es_AR' => 'Español Argentina',
'fr' => 'Français', 'fr' => 'Français',
@ -149,8 +134,9 @@ return [
'pl' => 'Polski', 'pl' => 'Polski',
'it' => 'Italian', 'it' => 'Italian',
'ru' => 'Русский', 'ru' => 'Русский',
'uk' => 'Українська',
'zh_CN' => '简体中文', 'zh_CN' => '简体中文',
'zh_TW' => '繁體中文' 'zh_TW' => '繁體中文'
] ]
/////////////////////////////////// //!////////////////////////////////
]; ];

View File

@ -1,18 +1,13 @@
<?php <?php
/**
* Validation Lines
* The following language lines contain the default error messages used by
* the validator class. Some of these rules have multiple versions such
* as the size rules. Feel free to tweak each of these messages here.
*/
return [ return [
/* // Standard laravel validation lines
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| as the size rules. Feel free to tweak each of these messages here.
|
*/
'accepted' => 'The :attribute must be accepted.', 'accepted' => 'The :attribute must be accepted.',
'active_url' => 'The :attribute is not a valid URL.', 'active_url' => 'The :attribute is not a valid URL.',
'after' => 'The :attribute must be a date after :date.', 'after' => 'The :attribute must be a date after :date.',
@ -75,34 +70,13 @@ return [
'unique' => 'The :attribute has already been taken.', 'unique' => 'The :attribute has already been taken.',
'url' => 'The :attribute format is invalid.', 'url' => 'The :attribute format is invalid.',
/* // Custom validation lines
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom' => [ 'custom' => [
'password-confirm' => [ 'password-confirm' => [
'required_with' => 'Password confirmation required', 'required_with' => 'Password confirmation required',
], ],
], ],
/* // Custom validation attributes
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap attribute place-holders
| with something more reader friendly such as E-Mail Address instead
| of "email". This simply helps us make messages a little cleaner.
|
*/
'attributes' => [], 'attributes' => [],
]; ];

View File

@ -1,11 +1,9 @@
<?php <?php
return [
/** /**
* Activity text strings. * Activity text strings.
* Is used for all the text within activity logs & notifications. * Is used for all the text within activity logs & notifications.
*/ */
return [
// Pages // Pages
'page_create' => 'página creada', 'page_create' => 'página creada',

View File

@ -1,21 +1,15 @@
<?php <?php
return [ /**
/* * Authentication Language Lines
|-------------------------------------------------------------------------- * The following language lines are used during authentication for various
| Authentication Language Lines * messages that we need to display to the user.
|--------------------------------------------------------------------------
|
| The following language lines are used during authentication for various
| messages that we need to display to the user. You are free to modify
| these language lines according to your application's requirements.
|
*/ */
return [
'failed' => 'Las credenciales no concuerdan con nuestros registros.', 'failed' => 'Las credenciales no concuerdan con nuestros registros.',
'throttle' => 'Demasiados intentos fallidos de conexión. Por favor intente nuevamente en :seconds segundos.', 'throttle' => 'Demasiados intentos fallidos de conexión. Por favor intente nuevamente en :seconds segundos.',
/** // Login & Register
* Login & Register
*/
'sign_up' => 'Registrarse', 'sign_up' => 'Registrarse',
'log_in' => 'Acceder', 'log_in' => 'Acceder',
'log_in_with' => 'Acceder con :socialDriver', 'log_in_with' => 'Acceder con :socialDriver',
@ -43,23 +37,18 @@ return [
'register_success' => '¡Gracias por registrarse! Ahora se encuentra registrado y logueado.', 'register_success' => '¡Gracias por registrarse! Ahora se encuentra registrado y logueado.',
/** // Password Reset
* Password Reset
*/
'reset_password' => 'Resetear Contraseña', 'reset_password' => 'Resetear Contraseña',
'reset_password_send_instructions' => 'Introduzca su correo electrónico a continuación y le será enviado un correo con un link para la restauración', 'reset_password_send_instructions' => 'Introduzca su correo electrónico a continuación y le será enviado un correo con un link para la restauración',
'reset_password_send_button' => 'Enviar Enlace de Reseteo', 'reset_password_send_button' => 'Enviar Enlace de Reseteo',
'reset_password_sent_success' => 'Un enlace para resetear la contraseña ha sido enviado a :email.', 'reset_password_sent_success' => 'Un enlace para resetear la contraseña ha sido enviado a :email.',
'reset_password_success' => 'Su password ha sido reseteado de manera éxitosa.', 'reset_password_success' => 'Su password ha sido reseteado de manera éxitosa.',
'email_reset_subject' => 'Resetee la contraseña de :appName', 'email_reset_subject' => 'Resetee la contraseña de :appName',
'email_reset_text' => 'Está recibiendo este correo electrónico debido a que recibimos una solicitud de reseteo de contraseña de su cuenta.', 'email_reset_text' => 'Está recibiendo este correo electrónico debido a que recibimos una solicitud de reseteo de contraseña de su cuenta.',
'email_reset_not_requested' => 'Si no ha solicitado un reseteo de la contraseña, no es requerida ninguna acción por su parte.', 'email_reset_not_requested' => 'Si no ha solicitado un reseteo de la contraseña, no es requerida ninguna acción por su parte.',
/** // Email Confirmation
* Email Confirmation
*/
'email_confirm_subject' => 'Confirme su correo electrónico en :appName', 'email_confirm_subject' => 'Confirme su correo electrónico en :appName',
'email_confirm_greeting' => '¡Gracias por unirse a :appName!', 'email_confirm_greeting' => '¡Gracias por unirse a :appName!',
'email_confirm_text' => 'Por favor confirme su dirección de correo electrónico haciendo click en el siguiente botón:', 'email_confirm_text' => 'Por favor confirme su dirección de correo electrónico haciendo click en el siguiente botón:',

View File

@ -1,9 +1,10 @@
<?php <?php
/**
* Common elements found throughout many areas of BookStack.
*/
return [ return [
/** // Buttons
* Buttons
*/
'cancel' => 'Cancelar', 'cancel' => 'Cancelar',
'confirm' => 'Confirmar', 'confirm' => 'Confirmar',
'back' => 'Atrás', 'back' => 'Atrás',
@ -12,18 +13,14 @@ return [
'select' => 'Seleccionar', 'select' => 'Seleccionar',
'more' => 'Más', 'more' => 'Más',
/** // Form Labels
* Form Labels
*/
'name' => 'Nombre', 'name' => 'Nombre',
'description' => 'Descripción', 'description' => 'Descripción',
'role' => 'Rol', 'role' => 'Rol',
'cover_image' => 'Imagen de portada', 'cover_image' => 'Imagen de portada',
'cover_image_description' => 'Esta imagen debe ser aproximadamente de 440x250px.', 'cover_image_description' => 'Esta imagen debe ser aproximadamente de 440x250px.',
/** // Actions
* Actions
*/
'actions' => 'Acciones', 'actions' => 'Acciones',
'view' => 'Ver', 'view' => 'Ver',
'create' => 'Crear', 'create' => 'Crear',
@ -40,9 +37,7 @@ return [
'remove' => 'Remover', 'remove' => 'Remover',
'add' => 'Añadir', 'add' => 'Añadir',
/** // Misc
* Misc
*/
'deleted_user' => 'Usuario borrado', 'deleted_user' => 'Usuario borrado',
'no_activity' => 'Ninguna actividad para mostrar', 'no_activity' => 'Ninguna actividad para mostrar',
'no_items' => 'No hay elementos disponibles', 'no_items' => 'No hay elementos disponibles',
@ -54,15 +49,11 @@ return [
'list_view' => 'Vista en Lista', 'list_view' => 'Vista en Lista',
'default' => 'Predeterminada', 'default' => 'Predeterminada',
/** // Header
* Header
*/
'view_profile' => 'Ver Perfil', 'view_profile' => 'Ver Perfil',
'edit_profile' => 'Editar Perfil', 'edit_profile' => 'Editar Perfil',
/** // Email Content
* Email Content
*/
'email_action_help' => 'Si está teniendo problemas clicando en el botón ":actionText", copie y pegue la siguiente URL en su navegador web:', 'email_action_help' => 'Si está teniendo problemas clicando en el botón ":actionText", copie y pegue la siguiente URL en su navegador web:',
'email_rights' => 'Todos los derechos reservados', 'email_rights' => 'Todos los derechos reservados',
]; ];

View File

@ -1,9 +1,10 @@
<?php <?php
/**
* Text used in custom JavaScript driven components.
*/
return [ return [
/** // Image Manager
* Image Manager
*/
'image_select' => 'Seleccionar Imagen', 'image_select' => 'Seleccionar Imagen',
'image_all' => 'Todas', 'image_all' => 'Todas',
'image_all_title' => 'Ver todas las imágenes', 'image_all_title' => 'Ver todas las imágenes',
@ -24,9 +25,7 @@ return [
'image_delete_success' => 'Imagen borrada exitosamente', 'image_delete_success' => 'Imagen borrada exitosamente',
'image_upload_remove' => 'Borrar', 'image_upload_remove' => 'Borrar',
/** // Code Editor
* Code editor
*/
'code_editor' => 'Editar Código', 'code_editor' => 'Editar Código',
'code_language' => 'Lenguaje del Código', 'code_language' => 'Lenguaje del Código',
'code_content' => 'Contenido del Código', 'code_content' => 'Contenido del Código',

View File

@ -1,9 +1,11 @@
<?php <?php
/**
* Text used for 'Entities' (Document Structure Elements) such as
* Books, Shelves, Chapters & Pages
*/
return [ return [
/** // Shared
* Shared
*/
'recently_created' => 'Recientemente creado', 'recently_created' => 'Recientemente creado',
'recently_created_pages' => 'Páginas recientemente creadas', 'recently_created_pages' => 'Páginas recientemente creadas',
'recently_updated_pages' => 'Páginas recientemente actualizadas', 'recently_updated_pages' => 'Páginas recientemente actualizadas',
@ -31,17 +33,13 @@ return [
'export_pdf' => 'Archivo PDF', 'export_pdf' => 'Archivo PDF',
'export_text' => 'Archivo de texto', 'export_text' => 'Archivo de texto',
/** // Permissions and restrictions
* Permissions and restrictions
*/
'permissions' => 'Permisos', 'permissions' => 'Permisos',
'permissions_intro' => 'Una vez habilitado, estos permisos tendrán prioridad por encima de cualquier permiso establecido.', 'permissions_intro' => 'Una vez habilitado, estos permisos tendrán prioridad por encima de cualquier permiso establecido.',
'permissions_enable' => 'Habilitar permisos personalizados', 'permissions_enable' => 'Habilitar permisos personalizados',
'permissions_save' => 'Guardar permisos', 'permissions_save' => 'Guardar permisos',
/** // Search
* Search
*/
'search_results' => 'Resultados de búsqueda', 'search_results' => 'Resultados de búsqueda',
'search_total_results_found' => 'Se han encontrado :count resultados|Se han encontrado :count resultados en total', 'search_total_results_found' => 'Se han encontrado :count resultados|Se han encontrado :count resultados en total',
'search_clear' => 'Limpiar resultados', 'search_clear' => 'Limpiar resultados',
@ -66,9 +64,7 @@ return [
'search_set_date' => 'fecha', 'search_set_date' => 'fecha',
'search_update' => 'Actualizar Búsqueda', 'search_update' => 'Actualizar Búsqueda',
/** // Shelves
* Shelves
*/
'shelf' => 'Estante', 'shelf' => 'Estante',
'shelves' => 'Estantes', 'shelves' => 'Estantes',
'shelves_long' => 'Estantes', 'shelves_long' => 'Estantes',
@ -98,9 +94,7 @@ return [
'shelves_copy_permissions_explain' => 'Esto aplicará los ajustes de permisos de este estante para todos sus libros. Antes de activarlo, asegúrese de que todos los cambios de permisos para este estante han sido guardados.', 'shelves_copy_permissions_explain' => 'Esto aplicará los ajustes de permisos de este estante para todos sus libros. Antes de activarlo, asegúrese de que todos los cambios de permisos para este estante han sido guardados.',
'shelves_copy_permission_success' => 'Permisos del estante copiados a :count libros', 'shelves_copy_permission_success' => 'Permisos del estante copiados a :count libros',
/** // Books
* Books
*/
'book' => 'Libro', 'book' => 'Libro',
'books' => 'Libros', 'books' => 'Libros',
'x_books' => ':count Libro|:count Libros', 'x_books' => ':count Libro|:count Libros',
@ -134,9 +128,7 @@ return [
'books_sort_show_other' => 'Mostrar otros libros', 'books_sort_show_other' => 'Mostrar otros libros',
'books_sort_save' => 'Guardar nuevo orden', 'books_sort_save' => 'Guardar nuevo orden',
/** // Chapters
* Chapters
*/
'chapter' => 'Capítulo', 'chapter' => 'Capítulo',
'chapters' => 'Capítulos', 'chapters' => 'Capítulos',
'x_chapters' => ':count Capítulo|:count Capítulos', 'x_chapters' => ':count Capítulo|:count Capítulos',
@ -159,9 +151,7 @@ return [
'chapters_permissions_success' => 'Permisos de capítulo actualizados', 'chapters_permissions_success' => 'Permisos de capítulo actualizados',
'chapters_search_this' => 'Buscar este capítulo', 'chapters_search_this' => 'Buscar este capítulo',
/** // Pages
* Pages
*/
'page' => 'Página', 'page' => 'Página',
'pages' => 'Páginas', 'pages' => 'Páginas',
'x_pages' => ':count Página|:count Páginas', 'x_pages' => ':count Página|:count Páginas',
@ -235,9 +225,7 @@ return [
'pages_draft_discarded' => 'Borrador descartado, el editor ha sido actualizado con el contenido de la página actual', 'pages_draft_discarded' => 'Borrador descartado, el editor ha sido actualizado con el contenido de la página actual',
'pages_specific' => 'Página específica', 'pages_specific' => 'Página específica',
/** // Editor Sidebar
* Editor sidebar
*/
'page_tags' => 'Etiquetas de Página', 'page_tags' => 'Etiquetas de Página',
'chapter_tags' => 'Etiquetas de Capítulo', 'chapter_tags' => 'Etiquetas de Capítulo',
'book_tags' => 'Etiquetas de Libro', 'book_tags' => 'Etiquetas de Libro',
@ -273,18 +261,14 @@ return [
'attachments_file_updated' => 'Fichero actualizado éxitosamente', 'attachments_file_updated' => 'Fichero actualizado éxitosamente',
'attachments_link_attached' => 'Enlace agregado éxitosamente a la ágina', 'attachments_link_attached' => 'Enlace agregado éxitosamente a la ágina',
/** // Profile View
* Profile View
*/
'profile_user_for_x' => 'Usuario para :time', 'profile_user_for_x' => 'Usuario para :time',
'profile_created_content' => 'Contenido creado', 'profile_created_content' => 'Contenido creado',
'profile_not_created_pages' => ':userName no ha creado ninguna página', 'profile_not_created_pages' => ':userName no ha creado ninguna página',
'profile_not_created_chapters' => ':userName no ha creado ningún capítulo', 'profile_not_created_chapters' => ':userName no ha creado ningún capítulo',
'profile_not_created_books' => ':userName no ha creado ningún libro', 'profile_not_created_books' => ':userName no ha creado ningún libro',
/** // Comments
* Comments
*/
'comment' => 'Comentario', 'comment' => 'Comentario',
'comments' => 'Comentarios', 'comments' => 'Comentarios',
'comment_add' => 'Añadir Comentario', 'comment_add' => 'Añadir Comentario',
@ -302,9 +286,7 @@ return [
'comment_delete_confirm' => '¿Está seguro de que quiere borrar este comentario?', 'comment_delete_confirm' => '¿Está seguro de que quiere borrar este comentario?',
'comment_in_reply_to' => 'En respuesta a :commentId', 'comment_in_reply_to' => 'En respuesta a :commentId',
/** // Revision
* Revision
*/
'revision_delete_confirm' => '¿Está seguro de que desea eliminar esta revisión?', 'revision_delete_confirm' => '¿Está seguro de que desea eliminar esta revisión?',
'revision_delete_success' => 'Revisión eliminada', 'revision_delete_success' => 'Revisión eliminada',
'revision_cannot_delete_latest' => 'No se puede eliminar la última revisión.' 'revision_cannot_delete_latest' => 'No se puede eliminar la última revisión.'

View File

@ -1,10 +1,8 @@
<?php <?php
return [
/** /**
* Error text strings. * Text shown in error messaging.
*/ */
return [
// Permissions // Permissions
'permission' => 'No tiene permisos para visualizar la página solicitada.', 'permission' => 'No tiene permisos para visualizar la página solicitada.',
@ -38,6 +36,7 @@ return [
'uploaded' => 'El servidor no permite la subida de ficheros de este tamaño. Intente subir un fichero de menor tamaño.', 'uploaded' => 'El servidor no permite la subida de ficheros de este tamaño. Intente subir un fichero de menor tamaño.',
'image_upload_error' => 'Ha ocurrido un error al subir la imagen', 'image_upload_error' => 'Ha ocurrido un error al subir la imagen',
'image_upload_type_error' => 'El tipo de imagen que se quiere subir no es válido', 'image_upload_type_error' => 'El tipo de imagen que se quiere subir no es válido',
'file_upload_timeout' => 'La carga del archivo ha caducado.',
// Attachments // Attachments
'attachment_page_mismatch' => 'Página no coincidente durante la subida del adjunto ', 'attachment_page_mismatch' => 'Página no coincidente durante la subida del adjunto ',
@ -80,4 +79,5 @@ return [
'error_occurred' => 'Ha ocurrido un error', 'error_occurred' => 'Ha ocurrido un error',
'app_down' => 'La aplicación :appName se encuentra caída en este momento', 'app_down' => 'La aplicación :appName se encuentra caída en este momento',
'back_soon' => 'Volverá a estar operativa pronto.', 'back_soon' => 'Volverá a estar operativa pronto.',
]; ];

View File

@ -1,17 +1,10 @@
<?php <?php
/**
return [ * Pagination Language Lines
* The following language lines are used by the paginator library to build
/* * the simple pagination links.
|--------------------------------------------------------------------------
| Pagination Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are used by the paginator library to build
| the simple pagination links. You are free to change them to anything
| you want to customize your views to better match your application.
|
*/ */
return [
'previous' => '&laquo; Anterior', 'previous' => '&laquo; Anterior',
'next' => 'Siguiente &raquo;', 'next' => 'Siguiente &raquo;',

View File

@ -1,17 +1,10 @@
<?php <?php
/**
return [ * Password Reminder Language Lines
* The following language lines are the default lines which match reasons
/* * that are given by the password broker for a password update attempt has failed.
|--------------------------------------------------------------------------
| Password Reminder Language Lines
|--------------------------------------------------------------------------
|
| The following language lines are the default lines which match reasons
| that are given by the password broker for a password update attempt
| has failed, such as for an invalid token or invalid new password.
|
*/ */
return [
'password' => 'La contraseña debe ser como mínimo de seis caracteres y coincidir con la confirmación.', 'password' => 'La contraseña debe ser como mínimo de seis caracteres y coincidir con la confirmación.',
'user' => "No podemos encontrar un usuario con esta dirección de correo electrónico.", 'user' => "No podemos encontrar un usuario con esta dirección de correo electrónico.",

View File

@ -1,21 +1,17 @@
<?php <?php
return [
/** /**
* Settings text strings * Settings text strings
* Contains all text strings used in the general settings sections of BookStack * Contains all text strings used in the general settings sections of BookStack
* including users and roles. * including users and roles.
*/ */
return [
// Common Messages
'settings' => 'Ajustes', 'settings' => 'Ajustes',
'settings_save' => 'Guardar ajustes', 'settings_save' => 'Guardar ajustes',
'settings_save_success' => 'Ajustes guardados', 'settings_save_success' => 'Ajustes guardados',
/** // App Settings
* App settings
*/
'app_settings' => 'Ajustes de la aplicación', 'app_settings' => 'Ajustes de la aplicación',
'app_name' => 'Nombre de la aplicación', 'app_name' => 'Nombre de la aplicación',
'app_name_desc' => 'Este nombre se muestra en la cabecera y en cualquier correo electrónico', 'app_name_desc' => 'Este nombre se muestra en la cabecera y en cualquier correo electrónico',
@ -37,10 +33,7 @@ return [
'app_disable_comments' => 'Deshabilitar comentarios', 'app_disable_comments' => 'Deshabilitar comentarios',
'app_disable_comments_desc' => 'Deshabilita los comentarios en todas las páginas de la aplicación. Los comentarios existentes no se muestran.', 'app_disable_comments_desc' => 'Deshabilita los comentarios en todas las páginas de la aplicación. Los comentarios existentes no se muestran.',
/** // Registration Settings
* Registration settings
*/
'reg_settings' => 'Ajustes de registro', 'reg_settings' => 'Ajustes de registro',
'reg_allow' => '¿Permitir registro?', 'reg_allow' => '¿Permitir registro?',
'reg_default_role' => 'Rol de usuario por defecto después del registro', 'reg_default_role' => 'Rol de usuario por defecto después del registro',
@ -50,10 +43,7 @@ return [
'reg_confirm_restrict_domain_desc' => 'Introduzca una lista separada por comas de los dominio a los que les gustaría restringir el registro de usuarios. A los usuarios les será enviado un correo electrónico para confirmar la dirección antes de que se le permita interactuar con la aplicación. <br> Tenga en cuenta que los usuarios podrán cambiar sus direcciones de correo electrónico después de registrarse exitosamente.', 'reg_confirm_restrict_domain_desc' => 'Introduzca una lista separada por comas de los dominio a los que les gustaría restringir el registro de usuarios. A los usuarios les será enviado un correo electrónico para confirmar la dirección antes de que se le permita interactuar con la aplicación. <br> Tenga en cuenta que los usuarios podrán cambiar sus direcciones de correo electrónico después de registrarse exitosamente.',
'reg_confirm_restrict_domain_placeholder' => 'Ninguna restricción establecida', 'reg_confirm_restrict_domain_placeholder' => 'Ninguna restricción establecida',
/** // Maintenance settings
* Maintenance settings
*/
'maint' => 'Mantenimiento', 'maint' => 'Mantenimiento',
'maint_image_cleanup' => 'Limpiar imágenes', 'maint_image_cleanup' => 'Limpiar imágenes',
'maint_image_cleanup_desc' => "Analiza las páginas y sus revisiones para comprobar qué imágenes y dibujos están siendo utilizadas y cuales no son necesarias. Asegúrate de crear una copia completa de la base de datos y de las imágenes antes de lanzar esta opción.", 'maint_image_cleanup_desc' => "Analiza las páginas y sus revisiones para comprobar qué imágenes y dibujos están siendo utilizadas y cuales no son necesarias. Asegúrate de crear una copia completa de la base de datos y de las imágenes antes de lanzar esta opción.",
@ -63,10 +53,7 @@ return [
'maint_image_cleanup_success' => '¡Se han encontrado y borrado :count imágenes posiblemente no utilizadas!', 'maint_image_cleanup_success' => '¡Se han encontrado y borrado :count imágenes posiblemente no utilizadas!',
'maint_image_cleanup_nothing_found' => '¡No se han encontrado imágenes sin utilizar, no se han borrado imágenes!', 'maint_image_cleanup_nothing_found' => '¡No se han encontrado imágenes sin utilizar, no se han borrado imágenes!',
/** // Role Settings
* Role settings
*/
'roles' => 'Roles', 'roles' => 'Roles',
'role_user_roles' => 'Roles de usuario', 'role_user_roles' => 'Roles de usuario',
'role_create' => 'Crear nuevo rol', 'role_create' => 'Crear nuevo rol',
@ -99,10 +86,7 @@ return [
'role_users' => 'Usuarios en este rol', 'role_users' => 'Usuarios en este rol',
'role_users_none' => 'No hay usuarios asignados a este rol', 'role_users_none' => 'No hay usuarios asignados a este rol',
/** // Users
* Users
*/
'users' => 'Usuarios', 'users' => 'Usuarios',
'user_profile' => 'Perfil de usuario', 'user_profile' => 'Perfil de usuario',
'users_add_new' => 'Agregar nuevo usuario', 'users_add_new' => 'Agregar nuevo usuario',

View File

@ -1,18 +1,13 @@
<?php <?php
/**
* Validation Lines
* The following language lines contain the default error messages used by
* the validator class. Some of these rules have multiple versions such
* as the size rules. Feel free to tweak each of these messages here.
*/
return [ return [
/* // Standard laravel validation lines
|--------------------------------------------------------------------------
| Validation Language Lines
|--------------------------------------------------------------------------
|
| The following language lines contain the default error messages used by
| the validator class. Some of these rules have multiple versions such
| as the size rules. Feel free to tweak each of these messages here.
|
*/
'accepted' => 'El :attribute debe ser aceptado.', 'accepted' => 'El :attribute debe ser aceptado.',
'active_url' => 'El :attribute no es una URL válida.', 'active_url' => 'El :attribute no es una URL válida.',
'after' => 'El :attribute debe ser una fecha posterior :date.', 'after' => 'El :attribute debe ser una fecha posterior :date.',
@ -75,34 +70,13 @@ return [
'unique' => 'El atributo :attribute ya ha sido tomado.', 'unique' => 'El atributo :attribute ya ha sido tomado.',
'url' => 'El atributo :attribute tiene un formato inválido.', 'url' => 'El atributo :attribute tiene un formato inválido.',
/* // Custom validation lines
|--------------------------------------------------------------------------
| Custom Validation Language Lines
|--------------------------------------------------------------------------
|
| Here you may specify custom validation messages for attributes using the
| convention "attribute.rule" to name the lines. This makes it quick to
| specify a specific custom language line for a given attribute rule.
|
*/
'custom' => [ 'custom' => [
'password-confirm' => [ 'password-confirm' => [
'required_with' => 'Requerida confirmación de contraseña', 'required_with' => 'Requerida confirmación de contraseña',
], ],
], ],
/* // Custom validation attributes
|--------------------------------------------------------------------------
| Custom Validation Attributes
|--------------------------------------------------------------------------
|
| The following language lines are used to swap attribute place-holders
| with something more reader friendly such as E-Mail Address instead
| of "email". This simply helps us make messages a little cleaner.
|
*/
'attributes' => [], 'attributes' => [],
]; ];

View File

@ -38,6 +38,7 @@ return [
'uploaded' => 'El servidor no permite subir archivos de este tamaño. Por favor intente un tamaño menor.', 'image_upload_error' => 'Ha ocurrido un error al subir la imagen', 'uploaded' => 'El servidor no permite subir archivos de este tamaño. Por favor intente un tamaño menor.', 'image_upload_error' => 'Ha ocurrido un error al subir la imagen',
'image_upload_error' => 'Ha ocurrido un error al subir la imagen', 'image_upload_error' => 'Ha ocurrido un error al subir la imagen',
'image_upload_type_error' => 'El tipo de imagen subida es inválido.', 'image_upload_type_error' => 'El tipo de imagen subida es inválido.',
'file_upload_timeout' => 'La carga del archivo ha caducado.',
// Attachments // Attachments
'attachment_page_mismatch' => 'Página no coincidente durante la subida del adjunto ', 'attachment_page_mismatch' => 'Página no coincidente durante la subida del adjunto ',

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