From b987bea37a593201107f207dc065e973e3ec39e8 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Tue, 2 Aug 2022 16:56:56 +0100 Subject: [PATCH 01/45] Added OIDC group sync functionality Is generally aligned with out SAML2 group sync functionality, but for OIDC based upon feedback in #3004. Neeeded the tangental addition of being able to define custom scopes on the initial auth request as some systems use this to provide additional id token claims such as groups. Includes tests to cover. Tested live using Okta. --- .env.example.complete | 4 ++ app/Auth/Access/Oidc/OidcOAuthProvider.php | 16 ++++- app/Auth/Access/Oidc/OidcService.php | 73 +++++++++++++++++++++- app/Config/oidc.php | 12 ++++ tests/Auth/OidcTest.php | 69 ++++++++++++++++++++ 5 files changed, 170 insertions(+), 4 deletions(-) diff --git a/.env.example.complete b/.env.example.complete index 45b1c7a86..c097af4f6 100644 --- a/.env.example.complete +++ b/.env.example.complete @@ -263,7 +263,11 @@ OIDC_ISSUER_DISCOVER=false OIDC_PUBLIC_KEY=null OIDC_AUTH_ENDPOINT=null OIDC_TOKEN_ENDPOINT=null +OIDC_ADDITIONAL_SCOPES=null OIDC_DUMP_USER_DETAILS=false +OIDC_USER_TO_GROUPS=false +OIDC_GROUP_ATTRIBUTE=groups +OIDC_REMOVE_FROM_GROUPS=false # Disable default third-party services such as Gravatar and Draw.IO # Service-specific options will override this option diff --git a/app/Auth/Access/Oidc/OidcOAuthProvider.php b/app/Auth/Access/Oidc/OidcOAuthProvider.php index 9b9d0524c..07bd980a3 100644 --- a/app/Auth/Access/Oidc/OidcOAuthProvider.php +++ b/app/Auth/Access/Oidc/OidcOAuthProvider.php @@ -30,6 +30,11 @@ class OidcOAuthProvider extends AbstractProvider */ protected $tokenEndpoint; + /** + * Scopes to use for the OIDC authorization call + */ + protected array $scopes = ['openid', 'profile', 'email']; + /** * Returns the base URL for authorizing a client. */ @@ -54,6 +59,15 @@ class OidcOAuthProvider extends AbstractProvider return ''; } + /** + * Add an additional scope to this provider upon the default. + */ + public function addScope(string $scope): void + { + $this->scopes[] = $scope; + $this->scopes = array_unique($this->scopes); + } + /** * Returns the default scopes used by this provider. * @@ -62,7 +76,7 @@ class OidcOAuthProvider extends AbstractProvider */ protected function getDefaultScopes(): array { - return ['openid', 'profile', 'email']; + return $this->scopes; } /** diff --git a/app/Auth/Access/Oidc/OidcService.php b/app/Auth/Access/Oidc/OidcService.php index eeacdb732..3443baaf6 100644 --- a/app/Auth/Access/Oidc/OidcService.php +++ b/app/Auth/Access/Oidc/OidcService.php @@ -2,6 +2,8 @@ namespace BookStack\Auth\Access\Oidc; +use BookStack\Auth\Access\GroupSyncService; +use Illuminate\Support\Arr; use function auth; use BookStack\Auth\Access\LoginService; use BookStack\Auth\Access\RegistrationService; @@ -26,15 +28,22 @@ class OidcService protected RegistrationService $registrationService; protected LoginService $loginService; protected HttpClient $httpClient; + protected GroupSyncService $groupService; /** * OpenIdService constructor. */ - public function __construct(RegistrationService $registrationService, LoginService $loginService, HttpClient $httpClient) + public function __construct( + RegistrationService $registrationService, + LoginService $loginService, + HttpClient $httpClient, + GroupSyncService $groupService + ) { $this->registrationService = $registrationService; $this->loginService = $loginService; $this->httpClient = $httpClient; + $this->groupService = $groupService; } /** @@ -117,10 +126,31 @@ class OidcService */ protected function getProvider(OidcProviderSettings $settings): OidcOAuthProvider { - return new OidcOAuthProvider($settings->arrayForProvider(), [ + $provider = new OidcOAuthProvider($settings->arrayForProvider(), [ 'httpClient' => $this->httpClient, 'optionProvider' => new HttpBasicAuthOptionProvider(), ]); + + foreach ($this->getAdditionalScopes() as $scope) { + $provider->addScope($scope); + } + + return $provider; + } + + /** + * Get any user-defined addition/custom scopes to apply to the authentication request. + * + * @return string[] + */ + protected function getAdditionalScopes(): array + { + $scopeConfig = $this->config()['additional_scopes'] ?: ''; + + $scopeArr = explode(',', $scopeConfig); + $scopeArr = array_map(fn(string $scope) => trim($scope), $scopeArr); + + return array_filter($scopeArr); } /** @@ -145,10 +175,32 @@ class OidcService return implode(' ', $displayName); } + /** + * Extract the assigned groups from the id token. + * + * @return string[] + */ + protected function getUserGroups(OidcIdToken $token): array + { + $groupsAttr = $this->config()['group_attribute']; + if (empty($groupsAttr)) { + return []; + } + + $groupsList = Arr::get($token->getAllClaims(), $groupsAttr); + if (!is_array($groupsList)) { + return []; + } + + return array_values(array_filter($groupsList, function($val) { + return is_string($val); + })); + } + /** * Extract the details of a user from an ID token. * - * @return array{name: string, email: string, external_id: string} + * @return array{name: string, email: string, external_id: string, groups: string[]} */ protected function getUserDetails(OidcIdToken $token): array { @@ -158,6 +210,7 @@ class OidcService 'external_id' => $id, 'email' => $token->getClaim('email'), 'name' => $this->getUserDisplayName($token, $id), + 'groups' => $this->getUserGroups($token), ]; } @@ -209,6 +262,12 @@ class OidcService throw new OidcException($exception->getMessage()); } + if ($this->shouldSyncGroups()) { + $groups = $userDetails['groups']; + $detachExisting = $this->config()['remove_from_groups']; + $this->groupService->syncUserWithFoundGroups($user, $groups, $detachExisting); + } + $this->loginService->login($user, 'oidc'); return $user; @@ -221,4 +280,12 @@ class OidcService { return config('oidc'); } + + /** + * Check if groups should be synced. + */ + protected function shouldSyncGroups(): bool + { + return $this->config()['user_to_groups'] !== false; + } } diff --git a/app/Config/oidc.php b/app/Config/oidc.php index 842ac8af6..8a9dd3a87 100644 --- a/app/Config/oidc.php +++ b/app/Config/oidc.php @@ -32,4 +32,16 @@ return [ // OAuth2 endpoints. 'authorization_endpoint' => env('OIDC_AUTH_ENDPOINT', null), 'token_endpoint' => env('OIDC_TOKEN_ENDPOINT', null), + + // Add extra scopes, upon those required, to the OIDC authentication request + // Multiple values can be provided comma seperated. + 'additional_scopes' => env('OIDC_ADDITIONAL_SCOPES', null), + + // Group sync options + // Enable syncing, upon login, of OIDC groups to BookStack roles + 'user_to_groups' => env('OIDC_USER_TO_GROUPS', false), + // Attribute, within a OIDC ID token, to find group names within + 'group_attribute' => env('OIDC_GROUP_ATTRIBUTE', 'groups'), + // When syncing groups, remove any groups that no longer match. Otherwise sync only adds new groups. + 'remove_from_groups' => env('OIDC_REMOVE_FROM_GROUPS', false), ]; diff --git a/tests/Auth/OidcTest.php b/tests/Auth/OidcTest.php index aa2c99a36..4215f6a54 100644 --- a/tests/Auth/OidcTest.php +++ b/tests/Auth/OidcTest.php @@ -3,6 +3,7 @@ namespace Tests\Auth; use BookStack\Actions\ActivityType; +use BookStack\Auth\Role; use BookStack\Auth\User; use GuzzleHttp\Psr7\Request; use GuzzleHttp\Psr7\Response; @@ -37,6 +38,10 @@ class OidcTest extends TestCase 'oidc.token_endpoint' => 'https://oidc.local/token', 'oidc.discover' => false, 'oidc.dump_user_details' => false, + 'oidc.additional_scopes' => '', + 'oidc.user_to_groups' => false, + 'oidc.group_attribute' => 'group', + 'oidc.remove_from_groups' => false, ]); } @@ -159,6 +164,17 @@ class OidcTest extends TestCase $this->assertActivityExists(ActivityType::AUTH_LOGIN, null, "oidc; ({$user->id}) Barry Scott"); } + public function test_login_uses_custom_additional_scopes_if_defined() + { + config()->set([ + 'oidc.additional_scopes' => 'groups, badgers', + ]); + + $redirect = $this->post('/oidc/login')->headers->get('location'); + + $this->assertStringContainsString('scope=openid%20profile%20email%20groups%20badgers', $redirect); + } + public function test_callback_fails_if_no_state_present_or_matching() { $this->get('/oidc/callback?code=SplxlOBeZQQYbYS6WxSbIA&state=abc124'); @@ -344,6 +360,59 @@ class OidcTest extends TestCase $this->assertTrue(auth()->check()); } + public function test_login_group_sync() + { + config()->set([ + 'oidc.user_to_groups' => true, + 'oidc.group_attribute' => 'groups', + 'oidc.remove_from_groups' => false, + ]); + $roleA = Role::factory()->create(['display_name' => 'Wizards']); + $roleB = Role::factory()->create(['display_name' => 'ZooFolks', 'external_auth_id' => 'zookeepers']); + $roleC = Role::factory()->create(['display_name' => 'Another Role']); + + $resp = $this->runLogin([ + 'email' => 'benny@example.com', + 'sub' => 'benny1010101', + 'groups' => ['Wizards', 'Zookeepers'] + ]); + $resp->assertRedirect('/'); + + /** @var User $user */ + $user = User::query()->where('email', '=', 'benny@example.com')->first(); + + $this->assertTrue($user->hasRole($roleA->id)); + $this->assertTrue($user->hasRole($roleB->id)); + $this->assertFalse($user->hasRole($roleC->id)); + } + + public function test_login_group_sync_with_nested_groups_in_token() + { + config()->set([ + 'oidc.user_to_groups' => true, + 'oidc.group_attribute' => 'my.custom.groups.attr', + 'oidc.remove_from_groups' => false, + ]); + $roleA = Role::factory()->create(['display_name' => 'Wizards']); + + $resp = $this->runLogin([ + 'email' => 'benny@example.com', + 'sub' => 'benny1010101', + 'my' => [ + 'custom' => [ + 'groups' => [ + 'attr' => ['Wizards'] + ] + ] + ] + ]); + $resp->assertRedirect('/'); + + /** @var User $user */ + $user = User::query()->where('email', '=', 'benny@example.com')->first(); + $this->assertTrue($user->hasRole($roleA->id)); + } + protected function withAutodiscovery() { config()->set([ From 9041e25476ca08479d6cbd84158274f86296e7e8 Mon Sep 17 00:00:00 2001 From: Daniel Schmelz Date: Mon, 15 Aug 2022 22:41:44 +0200 Subject: [PATCH 02/45] Fix typos --- readme.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/readme.md b/readme.md index 7c0f5cd86..83986525e 100644 --- a/readme.md +++ b/readme.md @@ -64,7 +64,7 @@ Below is a high-level road map view for BookStack to provide a sense of directio - **Platform REST API** - *(Most actions implemented, maturing)* - *A REST API covering, at minimum, control of core content models (Books, Chapters, Pages) for automation and platform extension.* - **Editor Alignment & Review** - *(Done)* - - *Review the page editors with goal of achieving increased interoperability & feature parity while also considering collaborative editing potential.* + - *Review the page editors with the goal of achieving increased interoperability & feature parity while also considering collaborative editing potential.* - **Permission System Review** - *(In Progress)* - *Improvement in how permissions are applied and a review of the efficiency of the permission & roles system.* - **Installation & Deployment Process Revamp** @@ -77,12 +77,12 @@ BookStack releases are each assigned a date-based version number in the format ` - `v20.12` - New feature released launched during December 2020. - `v21.06.2` - Second patch release upon the June 2021 feature release. -Patch releases are generally fairly minor, primarily intended for fixes and therefore is fairly unlikely to cause breakages upon update. +Patch releases are generally fairly minor, primarily intended for fixes and therefore are fairly unlikely to cause breakages upon update. Feature releases are generally larger, bringing new features in addition to fixes and enhancements. These releases have a greater chance of introducing breaking changes upon update, so it's worth checking for any notes in the [update guide](https://www.bookstackapp.com/docs/admin/updates/). Each BookStack release will have a [milestone](https://github.com/BookStackApp/BookStack/milestones) created with issues & pull requests assigned to it to define what will be in that release. Milestones are built up then worked through until complete at which point, after some testing and documentation updates, the release will be deployed. -Feature releases, and some patch releases, will be accompanied by a post on the [BookStack blog](https://www.bookstackapp.com/blog/) which will provide additional detail on features, changes & updates otherwise the [GitHub release page](https://github.com/BookStackApp/BookStack/releases) will show a list of changes. You can sign up to be alerted to new BookStack blogs posts (once per week maximum) [at this link](https://updates.bookstackapp.com/signup/bookstack-news-and-updates). +Feature releases, and some patch releases, will be accompanied by a post on the [BookStack blog](https://www.bookstackapp.com/blog/) which will provide additional detail on features, changes & updates otherwise the [GitHub release page](https://github.com/BookStackApp/BookStack/releases) will show a list of changes. You can sign up to be alerted to new BookStack blog posts (once per week maximum) [at this link](https://updates.bookstackapp.com/signup/bookstack-news-and-updates). ## 🛠️ Development & Testing @@ -170,7 +170,7 @@ NB : For some editors like Visual Studio Code, you might need to map your worksp ## 🌎 Translations -Translations for text within BookStack is managed through the [BookStack project on Crowdin](https://crowdin.com/project/bookstack). Some strings have colon-prefixed variables in such as `:userName`. Leave these values as they are as they will be replaced at run-time. Crowdin is the preferred way to provide translations, otherwise the raw translations files can be found within the `resources/lang` path. +Translations for text within BookStack is managed through the [BookStack project on Crowdin](https://crowdin.com/project/bookstack). Some strings have colon-prefixed variables such as `:userName`. Leave these values as they are as they will be replaced at run-time. Crowdin is the preferred way to provide translations, otherwise the raw translations files can be found within the `resources/lang` path. If you'd like a new language to be added to Crowdin, for you to be able to provide translations for, please [open a new issue here](https://github.com/BookStackApp/BookStack/issues/new?template=language_request.md). @@ -180,7 +180,7 @@ Please note, translations in BookStack are provided to the "Crowdin Global Trans Feel free to create issues to request new features or to report bugs & problems. Just please follow the template given when creating the issue. -Pull requests are welcome. Unless a small tweak or language update, It may be best to open the pull request early or create an issue for your intended change to discuss how it will fit in to the project and plan out the merge. Just because a feature request exists, or is tagged, does not mean that feature would be accepted into the core project. +Pull requests are welcome. Unless a small tweak or language update, It may be best to open the pull request early or create an issue for your intended change to discuss how it will fit into the project and plan out the merge. Just because a feature request exists, or is tagged, does not mean that feature would be accepted into the core project. Pull requests should be created from the `development` branch since they will be merged back into `development` once done. Please do not build from or request a merge into the `release` branch as this is only for publishing releases. If you are looking to alter CSS or JavaScript content please edit the source files found in `resources/`. Any CSS or JS files within `public` are built from these source files and therefore should not be edited directly. @@ -239,4 +239,4 @@ Note: This is not an exhaustive list of all libraries and projects that would be * [Bacon/BaconQrCode](https://github.com/Bacon/BaconQrCode) - _[BSD-2-Clause](https://github.com/Bacon/BaconQrCode/blob/master/LICENSE)_ * [phpseclib](https://github.com/phpseclib/phpseclib) - _[MIT](https://github.com/phpseclib/phpseclib/blob/master/LICENSE)_ * [Clockwork](https://github.com/itsgoingd/clockwork) - _[MIT](https://github.com/itsgoingd/clockwork/blob/master/LICENSE)_ -* [PHPStan](https://phpstan.org/) & [Larastan](https://github.com/nunomaduro/larastan) - _[MIT](https://github.com/phpstan/phpstan/blob/master/LICENSE) and [MIT](https://github.com/nunomaduro/larastan/blob/master/LICENSE.md)_ \ No newline at end of file +* [PHPStan](https://phpstan.org/) & [Larastan](https://github.com/nunomaduro/larastan) - _[MIT](https://github.com/phpstan/phpstan/blob/master/LICENSE) and [MIT](https://github.com/nunomaduro/larastan/blob/master/LICENSE.md)_ From 837fd74bf691129467361ce8066ba31f64408647 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Tue, 16 Aug 2022 11:27:22 +0100 Subject: [PATCH 03/45] Refactored search-based code to its own folder Also applied StyleCI changes --- app/Auth/Permissions/PermissionApplicator.php | 3 +-- app/Auth/User.php | 1 + app/Console/Commands/RegenerateSearch.php | 2 +- app/Entities/Models/Entity.php | 3 ++- .../Controllers/Api/SearchApiController.php | 6 ++--- .../Controllers/PageRevisionController.php | 8 +++--- app/Http/Controllers/SearchController.php | 6 ++--- .../Tools => Search}/SearchIndex.php | 3 +-- .../Tools => Search}/SearchOptions.php | 25 ++++--------------- .../SearchResultsFormatter.php | 2 +- .../Tools => Search}/SearchRunner.php | 5 ++-- .../Models => Search}/SearchTerm.php | 2 +- database/seeders/DummyContentSeeder.php | 2 +- database/seeders/LargeContentSeeder.php | 2 +- tests/Entity/SearchOptionsTest.php | 2 +- tests/FavouriteTest.php | 4 ++- 16 files changed, 31 insertions(+), 45 deletions(-) rename app/{Entities/Tools => Search}/SearchIndex.php (99%) rename app/{Entities/Tools => Search}/SearchOptions.php (94%) rename app/{Entities/Tools => Search}/SearchResultsFormatter.php (99%) rename app/{Entities/Tools => Search}/SearchRunner.php (99%) rename app/{Entities/Models => Search}/SearchTerm.php (91%) diff --git a/app/Auth/Permissions/PermissionApplicator.php b/app/Auth/Permissions/PermissionApplicator.php index 9a39f3e90..d840ccd16 100644 --- a/app/Auth/Permissions/PermissionApplicator.php +++ b/app/Auth/Permissions/PermissionApplicator.php @@ -74,9 +74,8 @@ class PermissionApplicator } foreach ($chain as $currentEntity) { - if (is_null($currentEntity->restricted)) { - throw new InvalidArgumentException("Entity restricted field used but has not been loaded"); + throw new InvalidArgumentException('Entity restricted field used but has not been loaded'); } if ($currentEntity->restricted) { diff --git a/app/Auth/User.php b/app/Auth/User.php index 393965e0d..6e66bc808 100644 --- a/app/Auth/User.php +++ b/app/Auth/User.php @@ -249,6 +249,7 @@ class User extends Model implements AuthenticatableContract, CanResetPasswordCon } $this->avatarUrl = $avatar; + return $avatar; } diff --git a/app/Console/Commands/RegenerateSearch.php b/app/Console/Commands/RegenerateSearch.php index 20e3fc798..ff584da56 100644 --- a/app/Console/Commands/RegenerateSearch.php +++ b/app/Console/Commands/RegenerateSearch.php @@ -3,7 +3,7 @@ namespace BookStack\Console\Commands; use BookStack\Entities\Models\Entity; -use BookStack\Entities\Tools\SearchIndex; +use BookStack\Search\SearchIndex; use Illuminate\Console\Command; use Illuminate\Support\Facades\DB; diff --git a/app/Entities/Models/Entity.php b/app/Entities/Models/Entity.php index 17f018a56..ffb9b9c7d 100644 --- a/app/Entities/Models/Entity.php +++ b/app/Entities/Models/Entity.php @@ -11,7 +11,6 @@ use BookStack\Auth\Permissions\EntityPermission; use BookStack\Auth\Permissions\JointPermission; use BookStack\Auth\Permissions\JointPermissionBuilder; use BookStack\Auth\Permissions\PermissionApplicator; -use BookStack\Entities\Tools\SearchIndex; use BookStack\Entities\Tools\SlugGenerator; use BookStack\Interfaces\Deletable; use BookStack\Interfaces\Favouritable; @@ -19,6 +18,8 @@ use BookStack\Interfaces\Loggable; use BookStack\Interfaces\Sluggable; use BookStack\Interfaces\Viewable; use BookStack\Model; +use BookStack\Search\SearchIndex; +use BookStack\Search\SearchTerm; use BookStack\Traits\HasCreatorAndUpdater; use BookStack\Traits\HasOwner; use Carbon\Carbon; diff --git a/app/Http/Controllers/Api/SearchApiController.php b/app/Http/Controllers/Api/SearchApiController.php index 5c4112f74..7ef714390 100644 --- a/app/Http/Controllers/Api/SearchApiController.php +++ b/app/Http/Controllers/Api/SearchApiController.php @@ -3,9 +3,9 @@ namespace BookStack\Http\Controllers\Api; use BookStack\Entities\Models\Entity; -use BookStack\Entities\Tools\SearchOptions; -use BookStack\Entities\Tools\SearchResultsFormatter; -use BookStack\Entities\Tools\SearchRunner; +use BookStack\Search\SearchOptions; +use BookStack\Search\SearchResultsFormatter; +use BookStack\Search\SearchRunner; use Illuminate\Http\Request; class SearchApiController extends ApiController diff --git a/app/Http/Controllers/PageRevisionController.php b/app/Http/Controllers/PageRevisionController.php index ea80e13cd..c4d5fbc7b 100644 --- a/app/Http/Controllers/PageRevisionController.php +++ b/app/Http/Controllers/PageRevisionController.php @@ -27,9 +27,9 @@ class PageRevisionController extends Controller { $page = $this->pageRepo->getBySlug($bookSlug, $pageSlug); $revisions = $page->revisions()->select([ - 'id', 'page_id', 'name', 'created_at', 'created_by', 'updated_at', - 'type', 'revision_number', 'summary', - ]) + 'id', 'page_id', 'name', 'created_at', 'created_by', 'updated_at', + 'type', 'revision_number', 'summary', + ]) ->selectRaw("IF(markdown = '', false, true) as is_markdown") ->with(['page.book', 'createdBy']) ->get(); @@ -38,7 +38,7 @@ class PageRevisionController extends Controller return view('pages.revisions', [ 'revisions' => $revisions, - 'page' => $page, + 'page' => $page, ]); } diff --git a/app/Http/Controllers/SearchController.php b/app/Http/Controllers/SearchController.php index 4a002298c..699733e37 100644 --- a/app/Http/Controllers/SearchController.php +++ b/app/Http/Controllers/SearchController.php @@ -3,10 +3,10 @@ namespace BookStack\Http\Controllers; use BookStack\Entities\Queries\Popular; -use BookStack\Entities\Tools\SearchOptions; -use BookStack\Entities\Tools\SearchResultsFormatter; -use BookStack\Entities\Tools\SearchRunner; use BookStack\Entities\Tools\SiblingFetcher; +use BookStack\Search\SearchOptions; +use BookStack\Search\SearchResultsFormatter; +use BookStack\Search\SearchRunner; use Illuminate\Http\Request; class SearchController extends Controller diff --git a/app/Entities/Tools/SearchIndex.php b/app/Search/SearchIndex.php similarity index 99% rename from app/Entities/Tools/SearchIndex.php rename to app/Search/SearchIndex.php index db44daadf..8c793a109 100644 --- a/app/Entities/Tools/SearchIndex.php +++ b/app/Search/SearchIndex.php @@ -1,12 +1,11 @@ =', '=', '<', '>', 'like', '!=']; + protected array $queryOperators = ['<=', '>=', '=', '<', '>', 'like', '!=']; /** * Retain a cache of score adjusted terms for specific search options. diff --git a/app/Entities/Models/SearchTerm.php b/app/Search/SearchTerm.php similarity index 91% rename from app/Entities/Models/SearchTerm.php rename to app/Search/SearchTerm.php index 4ec8d6c45..d416b0059 100644 --- a/app/Entities/Models/SearchTerm.php +++ b/app/Search/SearchTerm.php @@ -1,6 +1,6 @@ Date: Tue, 16 Aug 2022 13:23:53 +0100 Subject: [PATCH 04/45] Added system to extract model references from HTML content For the start of a managed cross-linking system. --- app/Util/CrossLinking/CrossLinkParser.php | 103 ++++++++++++++++++ .../ModelResolvers/BookLinkModelResolver.php | 26 +++++ .../BookshelfLinkModelResolver.php | 26 +++++ .../ChapterLinkModelResolver.php | 27 +++++ .../ModelResolvers/CrossLinkModelResolver.php | 13 +++ .../ModelResolvers/PageLinkModelResolver.php | 27 +++++ .../PagePermalinkModelResolver.php | 25 +++++ tests/Util/CrossLinkParserTest.php | 41 +++++++ 8 files changed, 288 insertions(+) create mode 100644 app/Util/CrossLinking/CrossLinkParser.php create mode 100644 app/Util/CrossLinking/ModelResolvers/BookLinkModelResolver.php create mode 100644 app/Util/CrossLinking/ModelResolvers/BookshelfLinkModelResolver.php create mode 100644 app/Util/CrossLinking/ModelResolvers/ChapterLinkModelResolver.php create mode 100644 app/Util/CrossLinking/ModelResolvers/CrossLinkModelResolver.php create mode 100644 app/Util/CrossLinking/ModelResolvers/PageLinkModelResolver.php create mode 100644 app/Util/CrossLinking/ModelResolvers/PagePermalinkModelResolver.php create mode 100644 tests/Util/CrossLinkParserTest.php diff --git a/app/Util/CrossLinking/CrossLinkParser.php b/app/Util/CrossLinking/CrossLinkParser.php new file mode 100644 index 000000000..774024d52 --- /dev/null +++ b/app/Util/CrossLinking/CrossLinkParser.php @@ -0,0 +1,103 @@ +modelResolvers = $modelResolvers; + } + + /** + * Extract any found models within the given HTML content. + * + * @returns Model[] + */ + public function extractLinkedModels(string $html): array + { + $models = []; + + $links = $this->getLinksFromContent($html); + + foreach ($links as $link) { + $model = $this->linkToModel($link); + if (!is_null($model)) { + $models[get_class($model) . ':' . $model->id] = $model; + } + } + + return array_values($models); + } + + /** + * Get a list of href values from the given document. + * + * @returns string[] + */ + protected function getLinksFromContent(string $html): array + { + $links = []; + + $html = '' . $html . ''; + libxml_use_internal_errors(true); + $doc = new DOMDocument(); + $doc->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8')); + + $xPath = new DOMXPath($doc); + $anchors = $xPath->query('//a[@href]'); + + /** @var \DOMElement $anchor */ + foreach ($anchors as $anchor) { + $links[] = $anchor->getAttribute('href'); + } + + return $links; + } + + /** + * Attempt to resolve the given link to a model using the instance model resolvers. + */ + protected function linkToModel(string $link): ?Model + { + foreach ($this->modelResolvers as $resolver) { + $model = $resolver->resolve($link); + if (!is_null($model)) { + return $model; + } + } + + return null; + } + + /** + * Create a new instance with a pre-defined set of model resolvers, specifically for the + * default set of entities within BookStack. + */ + public static function createWithEntityResolvers(): self + { + return new static([ + new PagePermalinkModelResolver(), + new PageLinkModelResolver(), + new ChapterLinkModelResolver(), + new BookLinkModelResolver(), + new BookshelfLinkModelResolver(), + ]); + } + +} \ No newline at end of file diff --git a/app/Util/CrossLinking/ModelResolvers/BookLinkModelResolver.php b/app/Util/CrossLinking/ModelResolvers/BookLinkModelResolver.php new file mode 100644 index 000000000..f2ee284cd --- /dev/null +++ b/app/Util/CrossLinking/ModelResolvers/BookLinkModelResolver.php @@ -0,0 +1,26 @@ +where('slug', '=', $bookSlug)->first(); + + return $model; + } +} \ No newline at end of file diff --git a/app/Util/CrossLinking/ModelResolvers/BookshelfLinkModelResolver.php b/app/Util/CrossLinking/ModelResolvers/BookshelfLinkModelResolver.php new file mode 100644 index 000000000..53cb89e3f --- /dev/null +++ b/app/Util/CrossLinking/ModelResolvers/BookshelfLinkModelResolver.php @@ -0,0 +1,26 @@ +where('slug', '=', $shelfSlug)->first(); + + return $model; + } +} \ No newline at end of file diff --git a/app/Util/CrossLinking/ModelResolvers/ChapterLinkModelResolver.php b/app/Util/CrossLinking/ModelResolvers/ChapterLinkModelResolver.php new file mode 100644 index 000000000..55afd183c --- /dev/null +++ b/app/Util/CrossLinking/ModelResolvers/ChapterLinkModelResolver.php @@ -0,0 +1,27 @@ +whereSlugs($bookSlug, $chapterSlug)->first(); + + return $model; + } +} \ No newline at end of file diff --git a/app/Util/CrossLinking/ModelResolvers/CrossLinkModelResolver.php b/app/Util/CrossLinking/ModelResolvers/CrossLinkModelResolver.php new file mode 100644 index 000000000..073764c66 --- /dev/null +++ b/app/Util/CrossLinking/ModelResolvers/CrossLinkModelResolver.php @@ -0,0 +1,13 @@ +whereSlugs($bookSlug, $pageSlug)->first(); + + return $model; + } +} \ No newline at end of file diff --git a/app/Util/CrossLinking/ModelResolvers/PagePermalinkModelResolver.php b/app/Util/CrossLinking/ModelResolvers/PagePermalinkModelResolver.php new file mode 100644 index 000000000..9b31f5013 --- /dev/null +++ b/app/Util/CrossLinking/ModelResolvers/PagePermalinkModelResolver.php @@ -0,0 +1,25 @@ +find($id); + + return $model; + } +} \ No newline at end of file diff --git a/tests/Util/CrossLinkParserTest.php b/tests/Util/CrossLinkParserTest.php new file mode 100644 index 000000000..f8ad59db2 --- /dev/null +++ b/tests/Util/CrossLinkParserTest.php @@ -0,0 +1,41 @@ +getEachEntityType(); + $otherPage = Page::query()->where('id', '!=', $entities['page']->id)->first(); + + $html = ' +Page Permalink +Page Link +Chapter Link +Book Link +Shelf Link +Settings Link + '; + + $parser = CrossLinkParser::createWithEntityResolvers(); + $results = $parser->extractLinkedModels($html); + + $this->assertCount(5, $results); + $this->assertEquals(get_class($otherPage), get_class($results[0])); + $this->assertEquals($otherPage->id, $results[0]->id); + $this->assertEquals(get_class($entities['page']), get_class($results[1])); + $this->assertEquals($entities['page']->id, $results[1]->id); + $this->assertEquals(get_class($entities['chapter']), get_class($results[2])); + $this->assertEquals($entities['chapter']->id, $results[2]->id); + $this->assertEquals(get_class($entities['book']), get_class($results[3])); + $this->assertEquals($entities['book']->id, $results[3]->id); + $this->assertEquals(get_class($entities['bookshelf']), get_class($results[4])); + $this->assertEquals($entities['bookshelf']->id, $results[4]->id); + } +} From 5d29d0cc7bb47cad7a662f1e6afc10cb97fe3ddd Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Wed, 17 Aug 2022 14:39:53 +0100 Subject: [PATCH 05/45] Added reference storage system, and command to re-index Also re-named/orgranized some files for this, to make them "References" specific instead of a subset of "Util". --- .../Commands/RegenerateCommentContent.php | 8 ++- .../Commands/RegeneratePermissions.php | 1 + app/Console/Commands/RegenerateReferences.php | 58 +++++++++++++++ app/Entities/Models/Entity.php | 17 +++++ .../CrossLinkParser.php | 16 ++--- .../ModelResolvers/BookLinkModelResolver.php | 4 +- .../BookshelfLinkModelResolver.php | 4 +- .../ChapterLinkModelResolver.php | 4 +- .../ModelResolvers/CrossLinkModelResolver.php | 2 +- .../ModelResolvers/PageLinkModelResolver.php | 4 +- .../PagePermalinkModelResolver.php | 2 +- app/References/Reference.php | 26 +++++++ app/References/ReferenceService.php | 71 +++++++++++++++++++ ...2_08_17_092941_create_references_table.php | 34 +++++++++ .../CrossLinkParserTest.php | 25 ++++++- 15 files changed, 253 insertions(+), 23 deletions(-) create mode 100644 app/Console/Commands/RegenerateReferences.php rename app/{Util/CrossLinking => References}/CrossLinkParser.php (82%) rename app/{Util/CrossLinking => References}/ModelResolvers/BookLinkModelResolver.php (87%) rename app/{Util/CrossLinking => References}/ModelResolvers/BookshelfLinkModelResolver.php (88%) rename app/{Util/CrossLinking => References}/ModelResolvers/ChapterLinkModelResolver.php (85%) rename app/{Util/CrossLinking => References}/ModelResolvers/CrossLinkModelResolver.php (77%) rename app/{Util/CrossLinking => References}/ModelResolvers/PageLinkModelResolver.php (85%) rename app/{Util/CrossLinking => References}/ModelResolvers/PagePermalinkModelResolver.php (90%) create mode 100644 app/References/Reference.php create mode 100644 app/References/ReferenceService.php create mode 100644 database/migrations/2022_08_17_092941_create_references_table.php rename tests/{Util => References}/CrossLinkParserTest.php (67%) diff --git a/app/Console/Commands/RegenerateCommentContent.php b/app/Console/Commands/RegenerateCommentContent.php index 587a5edb3..9da48fb0e 100644 --- a/app/Console/Commands/RegenerateCommentContent.php +++ b/app/Console/Commands/RegenerateCommentContent.php @@ -5,6 +5,7 @@ namespace BookStack\Console\Commands; use BookStack\Actions\Comment; use BookStack\Actions\CommentRepo; use Illuminate\Console\Command; +use Illuminate\Support\Facades\DB; class RegenerateCommentContent extends Command { @@ -43,9 +44,9 @@ class RegenerateCommentContent extends Command */ public function handle() { - $connection = \DB::getDefaultConnection(); + $connection = DB::getDefaultConnection(); if ($this->option('database') !== null) { - \DB::setDefaultConnection($this->option('database')); + DB::setDefaultConnection($this->option('database')); } Comment::query()->chunk(100, function ($comments) { @@ -55,7 +56,8 @@ class RegenerateCommentContent extends Command } }); - \DB::setDefaultConnection($connection); + DB::setDefaultConnection($connection); $this->comment('Comment HTML content has been regenerated'); + return 0; } } diff --git a/app/Console/Commands/RegeneratePermissions.php b/app/Console/Commands/RegeneratePermissions.php index 3396a445f..74f96fd42 100644 --- a/app/Console/Commands/RegeneratePermissions.php +++ b/app/Console/Commands/RegeneratePermissions.php @@ -50,5 +50,6 @@ class RegeneratePermissions extends Command DB::setDefaultConnection($connection); $this->comment('Permissions regenerated'); + return 0; } } diff --git a/app/Console/Commands/RegenerateReferences.php b/app/Console/Commands/RegenerateReferences.php new file mode 100644 index 000000000..93450c5ea --- /dev/null +++ b/app/Console/Commands/RegenerateReferences.php @@ -0,0 +1,58 @@ +references = $references; + parent::__construct(); + } + + /** + * Execute the console command. + * + * @return int + */ + public function handle() + { + $connection = DB::getDefaultConnection(); + + if ($this->option('database')) { + DB::setDefaultConnection($this->option('database')); + } + + $this->references->updateForAllPages(); + + DB::setDefaultConnection($connection); + + $this->comment('References have been regenerated'); + return 0; + } +} diff --git a/app/Entities/Models/Entity.php b/app/Entities/Models/Entity.php index ffb9b9c7d..26a52073e 100644 --- a/app/Entities/Models/Entity.php +++ b/app/Entities/Models/Entity.php @@ -18,6 +18,7 @@ use BookStack\Interfaces\Loggable; use BookStack\Interfaces\Sluggable; use BookStack\Interfaces\Viewable; use BookStack\Model; +use BookStack\References\Reference; use BookStack\Search\SearchIndex; use BookStack\Search\SearchTerm; use BookStack\Traits\HasCreatorAndUpdater; @@ -203,6 +204,22 @@ abstract class Entity extends Model implements Sluggable, Favouritable, Viewable return $this->morphMany(Deletion::class, 'deletable'); } + /** + * Get the references pointing from this entity to other items. + */ + public function referencesFrom(): MorphMany + { + return $this->morphMany(Reference::class, 'from'); + } + + /** + * Get the references pointing to this entity from other items. + */ + public function referencesTo(): MorphMany + { + return $this->morphMany(Reference::class, 'to'); + } + /** * Check if this instance or class is a certain type of entity. * Examples of $type are 'page', 'book', 'chapter'. diff --git a/app/Util/CrossLinking/CrossLinkParser.php b/app/References/CrossLinkParser.php similarity index 82% rename from app/Util/CrossLinking/CrossLinkParser.php rename to app/References/CrossLinkParser.php index 774024d52..22925884a 100644 --- a/app/Util/CrossLinking/CrossLinkParser.php +++ b/app/References/CrossLinkParser.php @@ -1,14 +1,14 @@ morphTo('from'); + } + + public function to(): MorphTo + { + return $this->morphTo('to'); + } +} diff --git a/app/References/ReferenceService.php b/app/References/ReferenceService.php new file mode 100644 index 000000000..7a1cf2fed --- /dev/null +++ b/app/References/ReferenceService.php @@ -0,0 +1,71 @@ +updateForPages([$page]); + } + + /** + * Update the outgoing references for all pages in the system. + */ + public function updateForAllPages(): void + { + Reference::query() + ->where('from_type', '=', (new Page())->getMorphClass()) + ->truncate(); + + Page::query()->select(['id', 'html'])->chunk(100, function(Collection $pages) { + $this->updateForPages($pages->all()); + }); + } + + /** + * Update the outgoing references for the pages in the given array. + * + * @param Page[] $pages + */ + protected function updateForPages(array $pages): void + { + if (count($pages) === 0) { + return; + } + + $parser = CrossLinkParser::createWithEntityResolvers(); + $references = []; + + $pageIds = array_map(fn(Page $page) => $page->id, $pages); + Reference::query() + ->where('from_type', '=', $pages[0]->getMorphClass()) + ->whereIn('from_id', $pageIds) + ->delete(); + + foreach ($pages as $page) { + $models = $parser->extractLinkedModels($page->html); + + foreach ($models as $model) { + $references[] = [ + 'from_id' => $page->id, + 'from_type' => $page->getMorphClass(), + 'to_id' => $model->id, + 'to_type' => $model->getMorphClass(), + ]; + } + } + + foreach (array_chunk($references, 1000) as $referenceDataChunk) { + Reference::query()->insert($referenceDataChunk); + } + } + +} \ No newline at end of file diff --git a/database/migrations/2022_08_17_092941_create_references_table.php b/database/migrations/2022_08_17_092941_create_references_table.php new file mode 100644 index 000000000..443bce551 --- /dev/null +++ b/database/migrations/2022_08_17_092941_create_references_table.php @@ -0,0 +1,34 @@ +id(); + $table->unsignedInteger('from_id')->index(); + $table->string('from_type', 25)->index(); + $table->unsignedInteger('to_id')->index(); + $table->string('to_type', 25)->index(); + }); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + Schema::dropIfExists('references'); + } +} diff --git a/tests/Util/CrossLinkParserTest.php b/tests/References/CrossLinkParserTest.php similarity index 67% rename from tests/Util/CrossLinkParserTest.php rename to tests/References/CrossLinkParserTest.php index f8ad59db2..42d78cb0a 100644 --- a/tests/Util/CrossLinkParserTest.php +++ b/tests/References/CrossLinkParserTest.php @@ -1,9 +1,10 @@ assertEquals(get_class($entities['bookshelf']), get_class($results[4])); $this->assertEquals($entities['bookshelf']->id, $results[4]->id); } + + public function test_similar_page_and_book_reference_links_dont_conflict() + { + $page = Page::query()->first(); + $book = $page->book; + + $html = ' +Page Link +Book Link + '; + + $parser = CrossLinkParser::createWithEntityResolvers(); + $results = $parser->extractLinkedModels($html); + + $this->assertCount(2, $results); + $this->assertEquals(get_class($page), get_class($results[0])); + $this->assertEquals($page->id, $results[0]->id); + $this->assertEquals(get_class($book), get_class($results[1])); + $this->assertEquals($book->id, $results[1]->id); + } } From 3290ab3ac939cfdbc374163bd34566f93d9d8df6 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Wed, 17 Aug 2022 16:59:23 +0100 Subject: [PATCH 06/45] Added regenerate-references command test Also updated model resolvers to only fetch model ID, to prevent bringing back way more data from database than desired. --- .../ModelResolvers/BookLinkModelResolver.php | 2 +- .../BookshelfLinkModelResolver.php | 2 +- .../ChapterLinkModelResolver.php | 2 +- .../ModelResolvers/PageLinkModelResolver.php | 2 +- .../PagePermalinkModelResolver.php | 2 +- app/References/ReferenceService.php | 2 +- .../RegenerateReferencesCommandTest.php | 32 +++++++++++++++++++ 7 files changed, 38 insertions(+), 6 deletions(-) create mode 100644 tests/Commands/RegenerateReferencesCommandTest.php diff --git a/app/References/ModelResolvers/BookLinkModelResolver.php b/app/References/ModelResolvers/BookLinkModelResolver.php index f33d97b84..459b13644 100644 --- a/app/References/ModelResolvers/BookLinkModelResolver.php +++ b/app/References/ModelResolvers/BookLinkModelResolver.php @@ -19,7 +19,7 @@ class BookLinkModelResolver implements CrossLinkModelResolver $bookSlug = $matches[1]; /** @var ?Book $model */ - $model = Book::query()->where('slug', '=', $bookSlug)->first(); + $model = Book::query()->where('slug', '=', $bookSlug)->first(['id']); return $model; } diff --git a/app/References/ModelResolvers/BookshelfLinkModelResolver.php b/app/References/ModelResolvers/BookshelfLinkModelResolver.php index ca5b8ca5f..7d1636689 100644 --- a/app/References/ModelResolvers/BookshelfLinkModelResolver.php +++ b/app/References/ModelResolvers/BookshelfLinkModelResolver.php @@ -19,7 +19,7 @@ class BookshelfLinkModelResolver implements CrossLinkModelResolver $shelfSlug = $matches[1]; /** @var ?Bookshelf $model */ - $model = Bookshelf::query()->where('slug', '=', $shelfSlug)->first(); + $model = Bookshelf::query()->where('slug', '=', $shelfSlug)->first(['id']); return $model; } diff --git a/app/References/ModelResolvers/ChapterLinkModelResolver.php b/app/References/ModelResolvers/ChapterLinkModelResolver.php index e15dba258..fbe75c4f6 100644 --- a/app/References/ModelResolvers/ChapterLinkModelResolver.php +++ b/app/References/ModelResolvers/ChapterLinkModelResolver.php @@ -20,7 +20,7 @@ class ChapterLinkModelResolver implements CrossLinkModelResolver $chapterSlug = $matches[2]; /** @var ?Chapter $model */ - $model = Chapter::query()->whereSlugs($bookSlug, $chapterSlug)->first(); + $model = Chapter::query()->whereSlugs($bookSlug, $chapterSlug)->first(['id']); return $model; } diff --git a/app/References/ModelResolvers/PageLinkModelResolver.php b/app/References/ModelResolvers/PageLinkModelResolver.php index f22f2734b..ead17e0a9 100644 --- a/app/References/ModelResolvers/PageLinkModelResolver.php +++ b/app/References/ModelResolvers/PageLinkModelResolver.php @@ -20,7 +20,7 @@ class PageLinkModelResolver implements CrossLinkModelResolver $pageSlug = $matches[2]; /** @var ?Page $model */ - $model = Page::query()->whereSlugs($bookSlug, $pageSlug)->first(); + $model = Page::query()->whereSlugs($bookSlug, $pageSlug)->first(['id']); return $model; } diff --git a/app/References/ModelResolvers/PagePermalinkModelResolver.php b/app/References/ModelResolvers/PagePermalinkModelResolver.php index 45396d54a..d59d41925 100644 --- a/app/References/ModelResolvers/PagePermalinkModelResolver.php +++ b/app/References/ModelResolvers/PagePermalinkModelResolver.php @@ -18,7 +18,7 @@ class PagePermalinkModelResolver implements CrossLinkModelResolver $id = intval($matches[1]); /** @var ?Page $model */ - $model = Page::query()->find($id); + $model = Page::query()->find($id, ['id']); return $model; } diff --git a/app/References/ReferenceService.php b/app/References/ReferenceService.php index 7a1cf2fed..fd7f74ae1 100644 --- a/app/References/ReferenceService.php +++ b/app/References/ReferenceService.php @@ -23,7 +23,7 @@ class ReferenceService { Reference::query() ->where('from_type', '=', (new Page())->getMorphClass()) - ->truncate(); + ->delete(); Page::query()->select(['id', 'html'])->chunk(100, function(Collection $pages) { $this->updateForPages($pages->all()); diff --git a/tests/Commands/RegenerateReferencesCommandTest.php b/tests/Commands/RegenerateReferencesCommandTest.php new file mode 100644 index 000000000..8906474af --- /dev/null +++ b/tests/Commands/RegenerateReferencesCommandTest.php @@ -0,0 +1,32 @@ +first(); + $book = $page->book; + + $page->html = 'Book Link'; + $page->save(); + + DB::table('references')->delete(); + + $this->artisan('bookstack:regenerate-references') + ->assertExitCode(0); + + $this->assertDatabaseHas('references', [ + 'from_id' => $page->id, + 'from_type' => $page->getMorphClass(), + 'to_id' => $book->id, + 'to_type' => $book->getMorphClass(), + ]); + } +} From bbe504c559dc8b540ce4c56d23423bdf10d69e5a Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Wed, 17 Aug 2022 17:37:27 +0100 Subject: [PATCH 07/45] Added reference handling on page actions Page update/create/restore/clone/delete. Added a couple of tests to cover a couple of those. --- app/Entities/Repos/PageRepo.php | 13 ++++-- app/Entities/Tools/TrashCan.php | 2 + app/References/Reference.php | 2 + tests/References/ReferencesTest.php | 67 +++++++++++++++++++++++++++++ 4 files changed, 81 insertions(+), 3 deletions(-) create mode 100644 tests/References/ReferencesTest.php diff --git a/app/Entities/Repos/PageRepo.php b/app/Entities/Repos/PageRepo.php index 60f1d1b01..09c664edc 100644 --- a/app/Entities/Repos/PageRepo.php +++ b/app/Entities/Repos/PageRepo.php @@ -16,20 +16,23 @@ use BookStack\Exceptions\MoveOperationException; use BookStack\Exceptions\NotFoundException; use BookStack\Exceptions\PermissionsException; use BookStack\Facades\Activity; +use BookStack\References\ReferenceService; use Exception; use Illuminate\Database\Eloquent\Builder; use Illuminate\Pagination\LengthAwarePaginator; class PageRepo { - protected $baseRepo; + protected BaseRepo $baseRepo; + protected ReferenceService $references; /** * PageRepo constructor. */ - public function __construct(BaseRepo $baseRepo) + public function __construct(BaseRepo $baseRepo, ReferenceService $references) { $this->baseRepo = $baseRepo; + $this->references = $references; } /** @@ -112,7 +115,7 @@ class PageRepo public function getParentFromSlugs(string $bookSlug, string $chapterSlug = null): Entity { if ($chapterSlug !== null) { - return $chapter = Chapter::visible()->whereSlugs($bookSlug, $chapterSlug)->firstOrFail(); + return Chapter::visible()->whereSlugs($bookSlug, $chapterSlug)->firstOrFail(); } return Book::visible()->where('slug', '=', $bookSlug)->firstOrFail(); @@ -170,6 +173,7 @@ class PageRepo $this->savePageRevision($draft, trans('entities.pages_initial_revision')); $draft->indexForSearch(); + $this->references->updateForPage($draft); $draft->refresh(); Activity::add(ActivityType::PAGE_CREATE, $draft); @@ -189,6 +193,7 @@ class PageRepo $this->updateTemplateStatusAndContentFromInput($page, $input); $this->baseRepo->update($page, $input); + $this->references->updateForPage($page); // Update with new details $page->revision_count++; @@ -332,6 +337,7 @@ class PageRepo $page->refreshSlug(); $page->save(); $page->indexForSearch(); + $this->references->updateForPage($page); $summary = trans('entities.pages_revision_restored_from', ['id' => strval($revisionId), 'summary' => $revision->summary]); $this->savePageRevision($page, $summary); @@ -430,6 +436,7 @@ class PageRepo ->skip(intval($revisionLimit)) ->take(10) ->get(['id']); + if ($revisionsToDelete->count() > 0) { PageRevision::query()->whereIn('id', $revisionsToDelete->pluck('id'))->delete(); } diff --git a/app/Entities/Tools/TrashCan.php b/app/Entities/Tools/TrashCan.php index abec2e2d5..7341a0328 100644 --- a/app/Entities/Tools/TrashCan.php +++ b/app/Entities/Tools/TrashCan.php @@ -376,6 +376,8 @@ class TrashCan $entity->searchTerms()->delete(); $entity->deletions()->delete(); $entity->favourites()->delete(); + $entity->referencesTo()->delete(); + $entity->referencesFrom()->delete(); if ($entity instanceof HasCoverImage && $entity->cover()->exists()) { $imageService = app()->make(ImageService::class); diff --git a/app/References/Reference.php b/app/References/Reference.php index a2a7bda10..5a490b5b5 100644 --- a/app/References/Reference.php +++ b/app/References/Reference.php @@ -14,6 +14,8 @@ use Illuminate\Database\Eloquent\Relations\MorphTo; */ class Reference extends Model { + public $timestamps = false; + public function from(): MorphTo { return $this->morphTo('from'); diff --git a/tests/References/ReferencesTest.php b/tests/References/ReferencesTest.php new file mode 100644 index 000000000..1285f5916 --- /dev/null +++ b/tests/References/ReferencesTest.php @@ -0,0 +1,67 @@ +first(); + $pageB = Page::query()->where('id', '!=', $pageA->id)->first(); + + $this->assertDatabaseMissing('references', ['from_id' => $pageA->id, 'from_type' => $pageA->getMorphClass()]); + + $this->asEditor()->put($pageA->getUrl(), [ + 'name' => 'Reference test', + 'html' => 'Testing' + ]); + + $this->assertDatabaseHas('references', [ + 'from_id' => $pageA->id, + 'from_type' => $pageA->getMorphClass(), + 'to_id' => $pageB->id, + 'to_type' => $pageB->getMorphClass(), + ]); + } + + public function test_references_deleted_on_entity_delete() + { + /** @var Page $pageA */ + /** @var Page $pageB */ + $pageA = Page::query()->first(); + $pageB = Page::query()->where('id', '!=', $pageA->id)->first(); + + $this->createReference($pageA, $pageB); + $this->createReference($pageB, $pageA); + + $this->assertDatabaseHas('references', ['from_id' => $pageA->id, 'from_type' => $pageA->getMorphClass()]); + $this->assertDatabaseHas('references', ['to_id' => $pageA->id, 'to_type' => $pageA->getMorphClass()]); + + app(PageRepo::class)->destroy($pageA); + app(TrashCan::class)->empty(); + + $this->assertDatabaseMissing('references', ['from_id' => $pageA->id, 'from_type' => $pageA->getMorphClass()]); + $this->assertDatabaseMissing('references', ['to_id' => $pageA->id, 'to_type' => $pageA->getMorphClass()]); + } + + protected function createReference(Model $from, Model $to) + { + (new Reference())->forceFill([ + 'from_type' => $from->getMorphClass(), + 'from_id' => $from->id, + 'to_type' => $to->getMorphClass(), + 'to_id' => $to->id, + ])->save(); + } + +} \ No newline at end of file From d5465726e2ef5f0cf129943abd3701bbc643cb28 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Fri, 19 Aug 2022 13:14:43 +0100 Subject: [PATCH 08/45] Added inbound references listing for pages --- app/Http/Controllers/ReferenceController.php | 47 ++++++++++++++++++++ resources/icons/popular.svg | 1 - resources/icons/reference.svg | 3 ++ resources/lang/en/entities.php | 5 +++ resources/views/pages/references.blade.php | 34 ++++++++++++++ routes/web.php | 2 + 6 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 app/Http/Controllers/ReferenceController.php create mode 100644 resources/icons/reference.svg create mode 100644 resources/views/pages/references.blade.php diff --git a/app/Http/Controllers/ReferenceController.php b/app/Http/Controllers/ReferenceController.php new file mode 100644 index 000000000..bed2c5f30 --- /dev/null +++ b/app/Http/Controllers/ReferenceController.php @@ -0,0 +1,47 @@ +permissions = $permissions; + } + + /** + * Display the references to a given page. + */ + public function page(string $bookSlug, string $pageSlug) + { + /** @var Page $page */ + $page = Page::visible()->whereSlugs($bookSlug, $pageSlug)->firstOrFail(); + + $baseQuery = $page->referencesTo() + ->where('from_type', '=', (new Page())->getMorphClass()) + ->with([ + 'from' => fn(Relation $query) => $query->select(Page::$listAttributes), + 'from.book' => fn(Relation $query) => $query->scopes('visible'), + 'from.chapter' => fn(Relation $query) => $query->scopes('visible') + ]); + + $references = $this->permissions->restrictEntityRelationQuery( + $baseQuery, + 'references', + 'from_id', + 'from_type' + )->get(); + + return view('pages.references', [ + 'page' => $page, + 'references' => $references, + ]); + } +} diff --git a/resources/icons/popular.svg b/resources/icons/popular.svg index ba1f918a5..2ac44f151 100644 --- a/resources/icons/popular.svg +++ b/resources/icons/popular.svg @@ -1,4 +1,3 @@ - \ No newline at end of file diff --git a/resources/icons/reference.svg b/resources/icons/reference.svg new file mode 100644 index 000000000..560ec5f37 --- /dev/null +++ b/resources/icons/reference.svg @@ -0,0 +1,3 @@ + + + diff --git a/resources/lang/en/entities.php b/resources/lang/en/entities.php index db1e8027b..a92b465b8 100644 --- a/resources/lang/en/entities.php +++ b/resources/lang/en/entities.php @@ -369,4 +369,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/views/pages/references.blade.php b/resources/views/pages/references.blade.php new file mode 100644 index 000000000..3f35a1629 --- /dev/null +++ b/resources/views/pages/references.blade.php @@ -0,0 +1,34 @@ +@extends('layouts.simple') + +@section('body') + +
+ +
+ @include('entities.breadcrumbs', ['crumbs' => [ + $page->book, + $page->chapter, + $page, + $page->getUrl('/references') => [ + 'text' => trans('entities.references'), + 'icon' => 'reference', + ] + ]]) +
+ +
+

{{ trans('entities.references') }}

+

{{ trans('entities.references_to_desc') }}

+ + @if(count($references) > 0) +
+ @include('entities.list', ['entities' => $references->pluck('from'), 'showPath' => true]) +
+ @else +

{{ trans('entities.references_none') }}

+ @endif + +
+
+ +@stop diff --git a/routes/web.php b/routes/web.php index 00841365a..a16960283 100644 --- a/routes/web.php +++ b/routes/web.php @@ -20,6 +20,7 @@ use BookStack\Http\Controllers\PageExportController; use BookStack\Http\Controllers\PageRevisionController; use BookStack\Http\Controllers\PageTemplateController; use BookStack\Http\Controllers\RecycleBinController; +use BookStack\Http\Controllers\ReferenceController; use BookStack\Http\Controllers\RoleController; use BookStack\Http\Controllers\SearchController; use BookStack\Http\Controllers\SettingController; @@ -110,6 +111,7 @@ Route::middleware('auth')->group(function () { Route::get('/books/{bookSlug}/draft/{pageId}/delete', [PageController::class, 'showDeleteDraft']); Route::get('/books/{bookSlug}/page/{pageSlug}/permissions', [PageController::class, 'showPermissions']); Route::put('/books/{bookSlug}/page/{pageSlug}/permissions', [PageController::class, 'permissions']); + Route::get('/books/{bookSlug}/page/{pageSlug}/references', [ReferenceController::class, 'page']); Route::put('/books/{bookSlug}/page/{pageSlug}', [PageController::class, 'update']); Route::delete('/books/{bookSlug}/page/{pageSlug}', [PageController::class, 'destroy']); Route::delete('/books/{bookSlug}/draft/{pageId}', [PageController::class, 'destroyDraft']); From d198332d3c7866d5eb807b9e07a4b95fd67b97c2 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Fri, 19 Aug 2022 22:40:44 +0100 Subject: [PATCH 09/45] Rolled out reference pages to all entities, added testing Including testing to check permissions applied to listed references. --- app/Http/Controllers/ReferenceController.php | 68 +++++++++++++++++-- resources/views/books/references.blade.php | 20 ++++++ resources/views/chapters/references.blade.php | 21 ++++++ resources/views/entities/references.blade.php | 13 ++++ resources/views/pages/references.blade.php | 14 +--- resources/views/shelves/references.blade.php | 20 ++++++ routes/web.php | 3 + tests/References/ReferencesTest.php | 40 +++++++++++ tests/TestCase.php | 2 +- 9 files changed, 182 insertions(+), 19 deletions(-) create mode 100644 resources/views/books/references.blade.php create mode 100644 resources/views/chapters/references.blade.php create mode 100644 resources/views/entities/references.blade.php create mode 100644 resources/views/shelves/references.blade.php diff --git a/app/Http/Controllers/ReferenceController.php b/app/Http/Controllers/ReferenceController.php index bed2c5f30..3af4feb06 100644 --- a/app/Http/Controllers/ReferenceController.php +++ b/app/Http/Controllers/ReferenceController.php @@ -3,7 +3,12 @@ namespace BookStack\Http\Controllers; use BookStack\Auth\Permissions\PermissionApplicator; +use BookStack\Entities\Models\Book; +use BookStack\Entities\Models\Bookshelf; +use BookStack\Entities\Models\Chapter; +use BookStack\Entities\Models\Entity; use BookStack\Entities\Models\Page; +use Illuminate\Database\Eloquent\Collection; use Illuminate\Database\Eloquent\Relations\Relation; class ReferenceController extends Controller @@ -23,8 +28,64 @@ class ReferenceController extends Controller { /** @var Page $page */ $page = Page::visible()->whereSlugs($bookSlug, $pageSlug)->firstOrFail(); + $references = $this->getEntityReferences($page); - $baseQuery = $page->referencesTo() + return view('pages.references', [ + 'page' => $page, + 'references' => $references, + ]); + } + + /** + * Display the references to a given chapter. + */ + public function chapter(string $bookSlug, string $chapterSlug) + { + /** @var Chapter $chapter */ + $chapter = Chapter::visible()->whereSlugs($bookSlug, $chapterSlug)->firstOrFail(); + $references = $this->getEntityReferences($chapter); + + return view('chapters.references', [ + 'chapter' => $chapter, + 'references' => $references, + ]); + } + + /** + * Display the references to a given book. + */ + public function book(string $slug) + { + $book = Book::visible()->where('slug', '=', $slug)->firstOrFail(); + $references = $this->getEntityReferences($book); + + return view('books.references', [ + 'book' => $book, + 'references' => $references, + ]); + } + + /** + * Display the references to a given shelf. + */ + public function shelf(string $slug) + { + $shelf = Bookshelf::visible()->where('slug', '=', $slug)->firstOrFail(); + $references = $this->getEntityReferences($shelf); + + return view('shelves.references', [ + 'shelf' => $shelf, + 'references' => $references, + ]); + } + + /** + * Query the references for the given entities. + * Loads the commonly required relations while taking permissions into account. + */ + protected function getEntityReferences(Entity $entity): Collection + { + $baseQuery = $entity->referencesTo() ->where('from_type', '=', (new Page())->getMorphClass()) ->with([ 'from' => fn(Relation $query) => $query->select(Page::$listAttributes), @@ -39,9 +100,6 @@ class ReferenceController extends Controller 'from_type' )->get(); - return view('pages.references', [ - 'page' => $page, - 'references' => $references, - ]); + return $references; } } diff --git a/resources/views/books/references.blade.php b/resources/views/books/references.blade.php new file mode 100644 index 000000000..2468ed111 --- /dev/null +++ b/resources/views/books/references.blade.php @@ -0,0 +1,20 @@ +@extends('layouts.simple') + +@section('body') + +
+ +
+ @include('entities.breadcrumbs', ['crumbs' => [ + $book, + $book->getUrl('/references') => [ + 'text' => trans('entities.references'), + 'icon' => 'reference', + ] + ]]) +
+ + @include('entities.references', ['references' => $references]) +
+ +@stop diff --git a/resources/views/chapters/references.blade.php b/resources/views/chapters/references.blade.php new file mode 100644 index 000000000..7241c2b55 --- /dev/null +++ b/resources/views/chapters/references.blade.php @@ -0,0 +1,21 @@ +@extends('layouts.simple') + +@section('body') + +
+ +
+ @include('entities.breadcrumbs', ['crumbs' => [ + $chapter->book, + $chapter, + $chapter->getUrl('/references') => [ + 'text' => trans('entities.references'), + 'icon' => 'reference', + ] + ]]) +
+ + @include('entities.references', ['references' => $references]) +
+ +@stop diff --git a/resources/views/entities/references.blade.php b/resources/views/entities/references.blade.php new file mode 100644 index 000000000..db9e167aa --- /dev/null +++ b/resources/views/entities/references.blade.php @@ -0,0 +1,13 @@ +
+

{{ trans('entities.references') }}

+

{{ trans('entities.references_to_desc') }}

+ + @if(count($references) > 0) +
+ @include('entities.list', ['entities' => $references->pluck('from'), 'showPath' => true]) +
+ @else +

{{ trans('entities.references_none') }}

+ @endif + +
\ No newline at end of file diff --git a/resources/views/pages/references.blade.php b/resources/views/pages/references.blade.php index 3f35a1629..42ae7076f 100644 --- a/resources/views/pages/references.blade.php +++ b/resources/views/pages/references.blade.php @@ -16,19 +16,7 @@ ]]) -
-

{{ trans('entities.references') }}

-

{{ trans('entities.references_to_desc') }}

- - @if(count($references) > 0) -
- @include('entities.list', ['entities' => $references->pluck('from'), 'showPath' => true]) -
- @else -

{{ trans('entities.references_none') }}

- @endif - -
+ @include('entities.references', ['references' => $references]) @stop diff --git a/resources/views/shelves/references.blade.php b/resources/views/shelves/references.blade.php new file mode 100644 index 000000000..7336c07af --- /dev/null +++ b/resources/views/shelves/references.blade.php @@ -0,0 +1,20 @@ +@extends('layouts.simple') + +@section('body') + +
+ +
+ @include('entities.breadcrumbs', ['crumbs' => [ + $shelf, + $shelf->getUrl('/references') => [ + 'text' => trans('entities.references'), + 'icon' => 'reference', + ] + ]]) +
+ + @include('entities.references', ['references' => $references]) +
+ +@stop diff --git a/routes/web.php b/routes/web.php index a16960283..dc46821cb 100644 --- a/routes/web.php +++ b/routes/web.php @@ -64,6 +64,7 @@ Route::middleware('auth')->group(function () { Route::get('/shelves/{slug}/permissions', [BookshelfController::class, 'showPermissions']); Route::put('/shelves/{slug}/permissions', [BookshelfController::class, 'permissions']); Route::post('/shelves/{slug}/copy-permissions', [BookshelfController::class, 'copyPermissions']); + Route::get('/shelves/{slug}/references', [ReferenceController::class, 'shelf']); // Book Creation Route::get('/shelves/{shelfSlug}/create-book', [BookController::class, 'create']); @@ -86,6 +87,7 @@ Route::middleware('auth')->group(function () { Route::post('/books/{bookSlug}/convert-to-shelf', [BookController::class, 'convertToShelf']); Route::get('/books/{bookSlug}/sort', [BookSortController::class, 'show']); Route::put('/books/{bookSlug}/sort', [BookSortController::class, 'update']); + Route::get('/books/{slug}/references', [ReferenceController::class, 'book']); Route::get('/books/{bookSlug}/export/html', [BookExportController::class, 'html']); Route::get('/books/{bookSlug}/export/pdf', [BookExportController::class, 'pdf']); Route::get('/books/{bookSlug}/export/markdown', [BookExportController::class, 'markdown']); @@ -142,6 +144,7 @@ Route::middleware('auth')->group(function () { Route::get('/books/{bookSlug}/chapter/{chapterSlug}/export/markdown', [ChapterExportController::class, 'markdown']); Route::get('/books/{bookSlug}/chapter/{chapterSlug}/export/plaintext', [ChapterExportController::class, 'plainText']); Route::put('/books/{bookSlug}/chapter/{chapterSlug}/permissions', [ChapterController::class, 'permissions']); + Route::get('/books/{bookSlug}/chapter/{chapterSlug}/references', [ReferenceController::class, 'chapter']); Route::get('/books/{bookSlug}/chapter/{chapterSlug}/delete', [ChapterController::class, 'showDelete']); Route::delete('/books/{bookSlug}/chapter/{chapterSlug}', [ChapterController::class, 'destroy']); diff --git a/tests/References/ReferencesTest.php b/tests/References/ReferencesTest.php index 1285f5916..20829b6b4 100644 --- a/tests/References/ReferencesTest.php +++ b/tests/References/ReferencesTest.php @@ -54,6 +54,46 @@ class ReferencesTest extends TestCase $this->assertDatabaseMissing('references', ['to_id' => $pageA->id, 'to_type' => $pageA->getMorphClass()]); } + public function test_references_to_visible_on_references_page() + { + $entities = $this->getEachEntityType(); + $this->asEditor(); + foreach ($entities as $entity) { + $this->createReference($entities['page'], $entity); + } + + foreach ($entities as $entity) { + $resp = $this->get($entity->getUrl('/references')); + $resp->assertSee('References'); + $resp->assertSee($entities['page']->name); + $resp->assertDontSee('There are no tracked references'); + } + } + + public function test_reference_not_visible_if_view_permission_does_not_permit() + { + /** @var Page $page */ + /** @var Page $pageB */ + $page = Page::query()->first(); + $pageB = Page::query()->where('id', '!=', $page->id)->first(); + $this->createReference($pageB, $page); + + $this->setEntityRestrictions($pageB); + + $this->asEditor()->get($page->getUrl('/references'))->assertDontSee($pageB->name); + $this->asAdmin()->get($page->getUrl('/references'))->assertSee($pageB->name); + } + + public function test_reference_page_shows_empty_state_with_no_references() + { + /** @var Page $page */ + $page = Page::query()->first(); + + $this->asEditor() + ->get($page->getUrl('/references')) + ->assertSee('There are no tracked references'); + } + protected function createReference(Model $from, Model $to) { (new Reference())->forceFill([ diff --git a/tests/TestCase.php b/tests/TestCase.php index 92ae33a4e..3ca7638c8 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -430,7 +430,7 @@ abstract class TestCase extends BaseTestCase } /** - * @return Entity[] + * @return array{page: Page, chapter: Chapter, book: Book, bookshelf: Bookshelf} */ protected function getEachEntityType(): array { From f634b4ea5767e6d823088c512872f9114322f7d0 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Sat, 20 Aug 2022 12:07:38 +0100 Subject: [PATCH 10/45] Added entity meta link to reference page Not totally happy with implementation as is requires extra service to be injected to core controllers, but does the job. Included test to cover. Updated some controller properties to be typed while there. --- app/Console/Commands/RegenerateReferences.php | 6 +- app/Entities/Repos/PageRepo.php | 6 +- app/Http/Controllers/BookController.php | 16 +++-- app/Http/Controllers/BookshelfController.php | 6 +- app/Http/Controllers/ChapterController.php | 26 ++++---- app/Http/Controllers/PageController.php | 6 +- app/Http/Controllers/ReferenceController.php | 44 +++---------- app/References/ReferenceFetcher.php | 62 +++++++++++++++++++ ...eferenceService.php => ReferenceStore.php} | 2 +- resources/lang/en/entities.php | 1 + resources/views/entities/meta.blade.php | 9 +++ tests/References/ReferencesTest.php | 22 +++++++ 12 files changed, 143 insertions(+), 63 deletions(-) create mode 100644 app/References/ReferenceFetcher.php rename app/References/{ReferenceService.php => ReferenceStore.php} (98%) diff --git a/app/Console/Commands/RegenerateReferences.php b/app/Console/Commands/RegenerateReferences.php index 93450c5ea..805db2207 100644 --- a/app/Console/Commands/RegenerateReferences.php +++ b/app/Console/Commands/RegenerateReferences.php @@ -2,7 +2,7 @@ namespace BookStack\Console\Commands; -use BookStack\References\ReferenceService; +use BookStack\References\ReferenceStore; use Illuminate\Console\Command; use Illuminate\Support\Facades\DB; @@ -22,14 +22,14 @@ class RegenerateReferences extends Command */ protected $description = 'Regenerate all the cross-item model reference index'; - protected ReferenceService $references; + protected ReferenceStore $references; /** * Create a new command instance. * * @return void */ - public function __construct(ReferenceService $references) + public function __construct(ReferenceStore $references) { $this->references = $references; parent::__construct(); diff --git a/app/Entities/Repos/PageRepo.php b/app/Entities/Repos/PageRepo.php index 09c664edc..40d1e6e53 100644 --- a/app/Entities/Repos/PageRepo.php +++ b/app/Entities/Repos/PageRepo.php @@ -16,7 +16,7 @@ use BookStack\Exceptions\MoveOperationException; use BookStack\Exceptions\NotFoundException; use BookStack\Exceptions\PermissionsException; use BookStack\Facades\Activity; -use BookStack\References\ReferenceService; +use BookStack\References\ReferenceStore; use Exception; use Illuminate\Database\Eloquent\Builder; use Illuminate\Pagination\LengthAwarePaginator; @@ -24,12 +24,12 @@ use Illuminate\Pagination\LengthAwarePaginator; class PageRepo { protected BaseRepo $baseRepo; - protected ReferenceService $references; + protected ReferenceStore $references; /** * PageRepo constructor. */ - public function __construct(BaseRepo $baseRepo, ReferenceService $references) + public function __construct(BaseRepo $baseRepo, ReferenceStore $references) { $this->baseRepo = $baseRepo; $this->references = $references; diff --git a/app/Http/Controllers/BookController.php b/app/Http/Controllers/BookController.php index c5b6d0bf6..a041267bb 100644 --- a/app/Http/Controllers/BookController.php +++ b/app/Http/Controllers/BookController.php @@ -15,19 +15,22 @@ use BookStack\Entities\Tools\ShelfContext; use BookStack\Exceptions\ImageUploadException; use BookStack\Exceptions\NotFoundException; use BookStack\Facades\Activity; +use BookStack\References\ReferenceFetcher; use Illuminate\Http\Request; use Illuminate\Validation\ValidationException; use Throwable; class BookController extends Controller { - protected $bookRepo; - protected $entityContextManager; + protected BookRepo $bookRepo; + protected ShelfContext $shelfContext; + protected ReferenceFetcher $referenceFetcher; - public function __construct(ShelfContext $entityContextManager, BookRepo $bookRepo) + public function __construct(ShelfContext $entityContextManager, BookRepo $bookRepo, ReferenceFetcher $referenceFetcher) { $this->bookRepo = $bookRepo; - $this->entityContextManager = $entityContextManager; + $this->shelfContext = $entityContextManager; + $this->referenceFetcher = $referenceFetcher; } /** @@ -44,7 +47,7 @@ class BookController extends Controller $popular = $this->bookRepo->getPopular(4); $new = $this->bookRepo->getRecentlyCreated(4); - $this->entityContextManager->clearShelfContext(); + $this->shelfContext->clearShelfContext(); $this->setPageTitle(trans('entities.books')); @@ -122,7 +125,7 @@ class BookController extends Controller View::incrementFor($book); if ($request->has('shelf')) { - $this->entityContextManager->setShelfContext(intval($request->get('shelf'))); + $this->shelfContext->setShelfContext(intval($request->get('shelf'))); } $this->setPageTitle($book->getShortName()); @@ -133,6 +136,7 @@ class BookController extends Controller 'bookChildren' => $bookChildren, 'bookParentShelves' => $bookParentShelves, 'activity' => $activities->entityActivity($book, 20, 1), + 'referenceCount' => $this->referenceFetcher->getPageReferenceCountToEntity($book), ]); } diff --git a/app/Http/Controllers/BookshelfController.php b/app/Http/Controllers/BookshelfController.php index ccbeb6484..2143b876a 100644 --- a/app/Http/Controllers/BookshelfController.php +++ b/app/Http/Controllers/BookshelfController.php @@ -10,6 +10,7 @@ use BookStack\Entities\Tools\PermissionsUpdater; use BookStack\Entities\Tools\ShelfContext; use BookStack\Exceptions\ImageUploadException; use BookStack\Exceptions\NotFoundException; +use BookStack\References\ReferenceFetcher; use Exception; use Illuminate\Http\Request; use Illuminate\Validation\ValidationException; @@ -18,11 +19,13 @@ class BookshelfController extends Controller { protected BookshelfRepo $shelfRepo; protected ShelfContext $shelfContext; + protected ReferenceFetcher $referenceFetcher; - public function __construct(BookshelfRepo $shelfRepo, ShelfContext $shelfContext) + public function __construct(BookshelfRepo $shelfRepo, ShelfContext $shelfContext, ReferenceFetcher $referenceFetcher) { $this->shelfRepo = $shelfRepo; $this->shelfContext = $shelfContext; + $this->referenceFetcher = $referenceFetcher; } /** @@ -124,6 +127,7 @@ class BookshelfController extends Controller 'activity' => $activities->entityActivity($shelf, 20, 1), 'order' => $order, 'sort' => $sort, + 'referenceCount' => $this->referenceFetcher->getPageReferenceCountToEntity($shelf), ]); } diff --git a/app/Http/Controllers/ChapterController.php b/app/Http/Controllers/ChapterController.php index 60eb52380..735c760be 100644 --- a/app/Http/Controllers/ChapterController.php +++ b/app/Http/Controllers/ChapterController.php @@ -13,20 +13,21 @@ use BookStack\Entities\Tools\PermissionsUpdater; use BookStack\Exceptions\MoveOperationException; use BookStack\Exceptions\NotFoundException; use BookStack\Exceptions\PermissionsException; +use BookStack\References\ReferenceFetcher; use Illuminate\Http\Request; use Illuminate\Validation\ValidationException; use Throwable; class ChapterController extends Controller { - protected $chapterRepo; + protected ChapterRepo $chapterRepo; + protected ReferenceFetcher $referenceFetcher; - /** - * ChapterController constructor. - */ - public function __construct(ChapterRepo $chapterRepo) + + public function __construct(ChapterRepo $chapterRepo, ReferenceFetcher $referenceFetcher) { $this->chapterRepo = $chapterRepo; + $this->referenceFetcher = $referenceFetcher; } /** @@ -77,13 +78,14 @@ class ChapterController extends Controller $this->setPageTitle($chapter->getShortName()); return view('chapters.show', [ - 'book' => $chapter->book, - 'chapter' => $chapter, - 'current' => $chapter, - 'sidebarTree' => $sidebarTree, - 'pages' => $pages, - 'next' => $nextPreviousLocator->getNext(), - 'previous' => $nextPreviousLocator->getPrevious(), + 'book' => $chapter->book, + 'chapter' => $chapter, + 'current' => $chapter, + 'sidebarTree' => $sidebarTree, + 'pages' => $pages, + 'next' => $nextPreviousLocator->getNext(), + 'previous' => $nextPreviousLocator->getPrevious(), + 'referenceCount' => $this->referenceFetcher->getPageReferenceCountToEntity($chapter), ]); } diff --git a/app/Http/Controllers/PageController.php b/app/Http/Controllers/PageController.php index 268dce057..748468b21 100644 --- a/app/Http/Controllers/PageController.php +++ b/app/Http/Controllers/PageController.php @@ -14,6 +14,7 @@ use BookStack\Entities\Tools\PageEditorData; use BookStack\Entities\Tools\PermissionsUpdater; use BookStack\Exceptions\NotFoundException; use BookStack\Exceptions\PermissionsException; +use BookStack\References\ReferenceFetcher; use Exception; use Illuminate\Database\Eloquent\Relations\BelongsTo; use Illuminate\Http\Request; @@ -23,13 +24,15 @@ use Throwable; class PageController extends Controller { protected PageRepo $pageRepo; + protected ReferenceFetcher $referenceFetcher; /** * PageController constructor. */ - public function __construct(PageRepo $pageRepo) + public function __construct(PageRepo $pageRepo, ReferenceFetcher $referenceFetcher) { $this->pageRepo = $pageRepo; + $this->referenceFetcher = $referenceFetcher; } /** @@ -160,6 +163,7 @@ class PageController extends Controller 'pageNav' => $pageNav, 'next' => $nextPreviousLocator->getNext(), 'previous' => $nextPreviousLocator->getPrevious(), + 'referenceCount' => $this->referenceFetcher->getPageReferenceCountToEntity($page), ]); } diff --git a/app/Http/Controllers/ReferenceController.php b/app/Http/Controllers/ReferenceController.php index 3af4feb06..07b143223 100644 --- a/app/Http/Controllers/ReferenceController.php +++ b/app/Http/Controllers/ReferenceController.php @@ -2,23 +2,19 @@ namespace BookStack\Http\Controllers; -use BookStack\Auth\Permissions\PermissionApplicator; use BookStack\Entities\Models\Book; use BookStack\Entities\Models\Bookshelf; use BookStack\Entities\Models\Chapter; -use BookStack\Entities\Models\Entity; use BookStack\Entities\Models\Page; -use Illuminate\Database\Eloquent\Collection; -use Illuminate\Database\Eloquent\Relations\Relation; +use BookStack\References\ReferenceFetcher; class ReferenceController extends Controller { + protected ReferenceFetcher $referenceFetcher; - protected PermissionApplicator $permissions; - - public function __construct(PermissionApplicator $permissions) + public function __construct(ReferenceFetcher $referenceFetcher) { - $this->permissions = $permissions; + $this->referenceFetcher = $referenceFetcher; } /** @@ -28,7 +24,7 @@ class ReferenceController extends Controller { /** @var Page $page */ $page = Page::visible()->whereSlugs($bookSlug, $pageSlug)->firstOrFail(); - $references = $this->getEntityReferences($page); + $references = $this->referenceFetcher->getPageReferencesToEntity($page); return view('pages.references', [ 'page' => $page, @@ -43,7 +39,7 @@ class ReferenceController extends Controller { /** @var Chapter $chapter */ $chapter = Chapter::visible()->whereSlugs($bookSlug, $chapterSlug)->firstOrFail(); - $references = $this->getEntityReferences($chapter); + $references = $this->referenceFetcher->getPageReferencesToEntity($chapter); return view('chapters.references', [ 'chapter' => $chapter, @@ -57,7 +53,7 @@ class ReferenceController extends Controller public function book(string $slug) { $book = Book::visible()->where('slug', '=', $slug)->firstOrFail(); - $references = $this->getEntityReferences($book); + $references = $this->referenceFetcher->getPageReferencesToEntity($book); return view('books.references', [ 'book' => $book, @@ -71,35 +67,11 @@ class ReferenceController extends Controller public function shelf(string $slug) { $shelf = Bookshelf::visible()->where('slug', '=', $slug)->firstOrFail(); - $references = $this->getEntityReferences($shelf); + $references = $this->referenceFetcher->getPageReferencesToEntity($shelf); return view('shelves.references', [ 'shelf' => $shelf, 'references' => $references, ]); } - - /** - * Query the references for the given entities. - * Loads the commonly required relations while taking permissions into account. - */ - protected function getEntityReferences(Entity $entity): Collection - { - $baseQuery = $entity->referencesTo() - ->where('from_type', '=', (new Page())->getMorphClass()) - ->with([ - 'from' => fn(Relation $query) => $query->select(Page::$listAttributes), - 'from.book' => fn(Relation $query) => $query->scopes('visible'), - 'from.chapter' => fn(Relation $query) => $query->scopes('visible') - ]); - - $references = $this->permissions->restrictEntityRelationQuery( - $baseQuery, - 'references', - 'from_id', - 'from_type' - )->get(); - - return $references; - } } diff --git a/app/References/ReferenceFetcher.php b/app/References/ReferenceFetcher.php new file mode 100644 index 000000000..fef2744d7 --- /dev/null +++ b/app/References/ReferenceFetcher.php @@ -0,0 +1,62 @@ +permissions = $permissions; + } + + /** + * Query and return the page references pointing to the given entity. + * Loads the commonly required relations while taking permissions into account. + */ + public function getPageReferencesToEntity(Entity $entity): Collection + { + $baseQuery = $entity->referencesTo() + ->where('from_type', '=', (new Page())->getMorphClass()) + ->with([ + 'from' => fn(Relation $query) => $query->select(Page::$listAttributes), + 'from.book' => fn(Relation $query) => $query->scopes('visible'), + 'from.chapter' => fn(Relation $query) => $query->scopes('visible') + ]); + + $references = $this->permissions->restrictEntityRelationQuery( + $baseQuery, + 'references', + 'from_id', + 'from_type' + )->get(); + + return $references; + } + + /** + * Returns the count of page references pointing to the given entity. + * Takes permissions into account. + */ + public function getPageReferenceCountToEntity(Entity $entity): int + { + $baseQuery = $entity->referencesTo() + ->where('from_type', '=', (new Page())->getMorphClass()); + + $count = $this->permissions->restrictEntityRelationQuery( + $baseQuery, + 'references', + 'from_id', + 'from_type' + )->count(); + + return $count; + } +} \ No newline at end of file diff --git a/app/References/ReferenceService.php b/app/References/ReferenceStore.php similarity index 98% rename from app/References/ReferenceService.php rename to app/References/ReferenceStore.php index fd7f74ae1..f6e3c04a3 100644 --- a/app/References/ReferenceService.php +++ b/app/References/ReferenceStore.php @@ -5,7 +5,7 @@ namespace BookStack\References; use BookStack\Entities\Models\Page; use Illuminate\Database\Eloquent\Collection; -class ReferenceService +class ReferenceStore { /** diff --git a/resources/lang/en/entities.php b/resources/lang/en/entities.php index a92b465b8..527665f88 100644 --- a/resources/lang/en/entities.php +++ b/resources/lang/en/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Updated :timeLength', 'meta_updated_name' => 'Updated :timeLength by :user', 'meta_owned_name' => 'Owned by :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Entity Select', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Images', diff --git a/resources/views/entities/meta.blade.php b/resources/views/entities/meta.blade.php index 83ff23762..ac91eeed3 100644 --- a/resources/views/entities/meta.blade.php +++ b/resources/views/entities/meta.blade.php @@ -59,4 +59,13 @@ {{ trans('entities.meta_updated', ['timeLength' => $entity->updated_at->diffForHumans()]) }} @endif + + @if($referenceCount ?? 0) + + @icon('reference') +
+ {!! trans_choice('entities.meta_reference_page_count', $referenceCount, ['count' => $referenceCount]) !!} +
+
+ @endif \ No newline at end of file diff --git a/tests/References/ReferencesTest.php b/tests/References/ReferencesTest.php index 20829b6b4..9ae226bb7 100644 --- a/tests/References/ReferencesTest.php +++ b/tests/References/ReferencesTest.php @@ -54,6 +54,28 @@ class ReferencesTest extends TestCase $this->assertDatabaseMissing('references', ['to_id' => $pageA->id, 'to_type' => $pageA->getMorphClass()]); } + public function test_references_to_count_visible_on_entity_show_view() + { + $entities = $this->getEachEntityType(); + /** @var Page $otherPage */ + $otherPage = Page::query()->where('id', '!=', $entities['page']->id)->first(); + + $this->asEditor(); + foreach ($entities as $entity) { + $this->createReference($entities['page'], $entity); + } + + foreach ($entities as $entity) { + $resp = $this->get($entity->getUrl()); + $resp->assertSee('Referenced on 1 page'); + $resp->assertDontSee('Referenced on 1 pages'); + } + + $this->createReference($otherPage, $entities['page']); + $resp = $this->get($entities['page']->getUrl()); + $resp->assertSee('Referenced on 2 pages'); + } + public function test_references_to_visible_on_references_page() { $entities = $this->getEachEntityType(); From 26ccb7b644d339da156f96ff53486a1ef500a61f Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Sat, 20 Aug 2022 21:09:07 +0100 Subject: [PATCH 11/45] Started work on reference on-change-updates Refactored out revision-specific actions within PageRepo for organisition and re-use for cross-linking work. --- app/Entities/Repos/PageRepo.php | 112 +++-------------------- app/Entities/Repos/RevisionRepo.php | 131 +++++++++++++++++++++++++++ app/References/CrossLinkReplacer.php | 47 ++++++++++ 3 files changed, 189 insertions(+), 101 deletions(-) create mode 100644 app/Entities/Repos/RevisionRepo.php create mode 100644 app/References/CrossLinkReplacer.php diff --git a/app/Entities/Repos/PageRepo.php b/app/Entities/Repos/PageRepo.php index 40d1e6e53..e491d6070 100644 --- a/app/Entities/Repos/PageRepo.php +++ b/app/Entities/Repos/PageRepo.php @@ -18,20 +18,21 @@ use BookStack\Exceptions\PermissionsException; use BookStack\Facades\Activity; use BookStack\References\ReferenceStore; use Exception; -use Illuminate\Database\Eloquent\Builder; use Illuminate\Pagination\LengthAwarePaginator; class PageRepo { protected BaseRepo $baseRepo; + protected RevisionRepo $revisionRepo; protected ReferenceStore $references; /** * PageRepo constructor. */ - public function __construct(BaseRepo $baseRepo, ReferenceStore $references) + public function __construct(BaseRepo $baseRepo, RevisionRepo $revisionRepo, ReferenceStore $references) { $this->baseRepo = $baseRepo; + $this->revisionRepo = $revisionRepo; $this->references = $references; } @@ -42,6 +43,7 @@ class PageRepo */ public function getById(int $id, array $relations = ['book']): Page { + /** @var Page $page */ $page = Page::visible()->with($relations)->find($id); if (!$page) { @@ -73,17 +75,7 @@ class PageRepo */ public function getByOldSlug(string $bookSlug, string $pageSlug): ?Page { - /** @var ?PageRevision $revision */ - $revision = PageRevision::query() - ->whereHas('page', function (Builder $query) { - $query->scopes('visible'); - }) - ->where('slug', '=', $pageSlug) - ->where('type', '=', 'version') - ->where('book_slug', '=', $bookSlug) - ->orderBy('created_at', 'desc') - ->with('page') - ->first(); + $revision = $this->revisionRepo->getBySlugs($bookSlug, $pageSlug); return $revision->page ?? null; } @@ -126,9 +118,7 @@ class PageRepo */ public function getUserDraft(Page $page): ?PageRevision { - $revision = $this->getUserDraftQuery($page)->first(); - - return $revision; + return $this->revisionRepo->getLatestDraftForCurrentUser($page); } /** @@ -171,7 +161,7 @@ class PageRepo $draft->refreshSlug(); $draft->save(); - $this->savePageRevision($draft, trans('entities.pages_initial_revision')); + $this->revisionRepo->storeNewForPage($draft, trans('entities.pages_initial_revision')); $draft->indexForSearch(); $this->references->updateForPage($draft); $draft->refresh(); @@ -200,7 +190,7 @@ class PageRepo $page->save(); // Remove all update drafts for this user & page. - $this->getUserDraftQuery($page)->delete(); + $this->revisionRepo->deleteDraftsForCurrentUser($page); // Save a revision after updating $summary = trim($input['summary'] ?? ''); @@ -208,7 +198,7 @@ class PageRepo $nameChanged = isset($input['name']) && $input['name'] !== $oldName; $markdownChanged = isset($input['markdown']) && $input['markdown'] !== $oldMarkdown; if ($htmlChanged || $nameChanged || $markdownChanged || $summary) { - $this->savePageRevision($page, $summary); + $this->revisionRepo->storeNewForPage($page, $summary); } Activity::add(ActivityType::PAGE_UPDATE, $page); @@ -244,32 +234,6 @@ class PageRepo } } - /** - * Saves a page revision into the system. - */ - protected function savePageRevision(Page $page, string $summary = null): PageRevision - { - $revision = new PageRevision(); - - $revision->name = $page->name; - $revision->html = $page->html; - $revision->markdown = $page->markdown; - $revision->text = $page->text; - $revision->page_id = $page->id; - $revision->slug = $page->slug; - $revision->book_slug = $page->book->slug; - $revision->created_by = user()->id; - $revision->created_at = $page->updated_at; - $revision->type = 'version'; - $revision->summary = $summary; - $revision->revision_number = $page->revision_count; - $revision->save(); - - $this->deleteOldRevisions($page); - - return $revision; - } - /** * Save a page update draft. */ @@ -285,7 +249,7 @@ class PageRepo } // Otherwise, save the data to a revision - $draft = $this->getPageRevisionToUpdate($page); + $draft = $this->revisionRepo->getNewDraftForCurrentUser($page); $draft->fill($input); if (!empty($input['markdown'])) { @@ -340,7 +304,7 @@ class PageRepo $this->references->updateForPage($page); $summary = trans('entities.pages_revision_restored_from', ['id' => strval($revisionId), 'summary' => $revision->summary]); - $this->savePageRevision($page, $summary); + $this->revisionRepo->storeNewForPage($page, $summary); Activity::add(ActivityType::PAGE_RESTORE, $page); Activity::add(ActivityType::REVISION_RESTORE, $revision); @@ -399,49 +363,6 @@ class PageRepo return $parentClass::visible()->where('id', '=', $entityId)->first(); } - /** - * Get a page revision to update for the given page. - * Checks for an existing revisions before providing a fresh one. - */ - protected function getPageRevisionToUpdate(Page $page): PageRevision - { - $drafts = $this->getUserDraftQuery($page)->get(); - if ($drafts->count() > 0) { - return $drafts->first(); - } - - $draft = new PageRevision(); - $draft->page_id = $page->id; - $draft->slug = $page->slug; - $draft->book_slug = $page->book->slug; - $draft->created_by = user()->id; - $draft->type = 'update_draft'; - - return $draft; - } - - /** - * Delete old revisions, for the given page, from the system. - */ - protected function deleteOldRevisions(Page $page) - { - $revisionLimit = config('app.revision_limit'); - if ($revisionLimit === false) { - return; - } - - $revisionsToDelete = PageRevision::query() - ->where('page_id', '=', $page->id) - ->orderBy('created_at', 'desc') - ->skip(intval($revisionLimit)) - ->take(10) - ->get(['id']); - - if ($revisionsToDelete->count() > 0) { - PageRevision::query()->whereIn('id', $revisionsToDelete->pluck('id'))->delete(); - } - } - /** * Get a new priority for a page. */ @@ -457,15 +378,4 @@ class PageRepo return (new BookContents($page->book))->getLastPriority() + 1; } - - /** - * Get the query to find the user's draft copies of the given page. - */ - protected function getUserDraftQuery(Page $page) - { - return PageRevision::query()->where('created_by', '=', user()->id) - ->where('type', 'update_draft') - ->where('page_id', '=', $page->id) - ->orderBy('created_at', 'desc'); - } } diff --git a/app/Entities/Repos/RevisionRepo.php b/app/Entities/Repos/RevisionRepo.php new file mode 100644 index 000000000..76d1d8553 --- /dev/null +++ b/app/Entities/Repos/RevisionRepo.php @@ -0,0 +1,131 @@ +whereHas('page', function (Builder $query) { + $query->scopes('visible'); + }) + ->where('slug', '=', $pageSlug) + ->where('type', '=', 'version') + ->where('book_slug', '=', $bookSlug) + ->orderBy('created_at', 'desc') + ->with('page') + ->first(); + + return $revision; + } + + /** + * Get the latest draft revision, for the given page, belonging to the current user. + */ + public function getLatestDraftForCurrentUser(Page $page): ?PageRevision + { + /** @var ?PageRevision $revision */ + $revision = $this->queryForCurrentUserDraft($page->id)->first(); + + return $revision; + } + + /** + * Delete all drafts revisions, for the given page, belonging to the current user. + */ + public function deleteDraftsForCurrentUser(Page $page): void + { + $this->queryForCurrentUserDraft($page->id)->delete(); + } + + /** + * Get a user update_draft page revision to update for the given page. + * Checks for an existing revisions before providing a fresh one. + */ + public function getNewDraftForCurrentUser(Page $page): PageRevision + { + $draft = $this->getLatestDraftForCurrentUser($page); + + if ($draft) { + return $draft; + } + + $draft = new PageRevision(); + $draft->page_id = $page->id; + $draft->slug = $page->slug; + $draft->book_slug = $page->book->slug; + $draft->created_by = user()->id; + $draft->type = 'update_draft'; + + return $draft; + } + + /** + * Store a new revision in the system for the given page. + */ + public function storeNewForPage(Page $page, string $summary = null): PageRevision + { + $revision = new PageRevision(); + + $revision->name = $page->name; + $revision->html = $page->html; + $revision->markdown = $page->markdown; + $revision->text = $page->text; + $revision->page_id = $page->id; + $revision->slug = $page->slug; + $revision->book_slug = $page->book->slug; + $revision->created_by = user()->id; + $revision->created_at = $page->updated_at; + $revision->type = 'version'; + $revision->summary = $summary; + $revision->revision_number = $page->revision_count; + $revision->save(); + + $this->deleteOldRevisions($page); + + return $revision; + } + + /** + * Delete old revisions, for the given page, from the system. + */ + protected function deleteOldRevisions(Page $page) + { + $revisionLimit = config('app.revision_limit'); + if ($revisionLimit === false) { + return; + } + + $revisionsToDelete = PageRevision::query() + ->where('page_id', '=', $page->id) + ->orderBy('created_at', 'desc') + ->skip(intval($revisionLimit)) + ->take(10) + ->get(['id']); + + if ($revisionsToDelete->count() > 0) { + PageRevision::query()->whereIn('id', $revisionsToDelete->pluck('id'))->delete(); + } + } + + /** + * Query update draft revisions for the current user. + */ + protected function queryForCurrentUserDraft(int $pageId): Builder + { + return PageRevision::query() + ->where('created_by', '=', user()->id) + ->where('type', 'update_draft') + ->where('page_id', '=', $pageId) + ->orderBy('created_at', 'desc'); + } +} \ No newline at end of file diff --git a/app/References/CrossLinkReplacer.php b/app/References/CrossLinkReplacer.php new file mode 100644 index 000000000..5581fe33f --- /dev/null +++ b/app/References/CrossLinkReplacer.php @@ -0,0 +1,47 @@ +referenceFetcher = $referenceFetcher; + $this->revisionRepo = $revisionRepo; + } + + public function updateEntityPageReferences(Entity $entity, string $oldLink) + { + $references = $this->referenceFetcher->getPageReferencesToEntity($entity); + $newLink = $entity->getUrl(); + + /** @var Reference $reference */ + foreach ($references as $reference) { + /** @var Page $page */ + $page = $reference->from; + $this->updateReferencesWithinPage($page, $oldLink, $newLink); + } + } + + protected function updateReferencesWithinPage(Page $page, string $oldLink, string $newLink) + { + $page = (clone $page)->refresh(); + $html = '';// TODO - Update HTML content + $markdown = '';// TODO - Update markdown content + + $page->html = $html; + $page->markdown = $markdown; + $page->revision_count++; + $page->save(); + + $summary = ''; // TODO - Get default summary from translations + $this->revisionRepo->storeNewForPage($page, $summary); + } +} \ No newline at end of file From 0dbf08453fcb79efc9aae21f5fa55f4547083456 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Sun, 21 Aug 2022 11:29:34 +0100 Subject: [PATCH 12/45] Built out cross link replacer, not yet tested --- app/References/CrossLinkReplacer.php | 53 ++++++++++++++++++++++++++-- resources/lang/en/entities.php | 1 + 2 files changed, 51 insertions(+), 3 deletions(-) diff --git a/app/References/CrossLinkReplacer.php b/app/References/CrossLinkReplacer.php index 5581fe33f..2df87fc83 100644 --- a/app/References/CrossLinkReplacer.php +++ b/app/References/CrossLinkReplacer.php @@ -5,6 +5,8 @@ namespace BookStack\References; use BookStack\Entities\Models\Entity; use BookStack\Entities\Models\Page; use BookStack\Entities\Repos\RevisionRepo; +use DOMDocument; +use DOMXPath; class CrossLinkReplacer { @@ -33,15 +35,60 @@ class CrossLinkReplacer protected function updateReferencesWithinPage(Page $page, string $oldLink, string $newLink) { $page = (clone $page)->refresh(); - $html = '';// TODO - Update HTML content - $markdown = '';// TODO - Update markdown content + $html = $this->updateLinksInHtml($page->html, $oldLink, $newLink); + $markdown = $this->updateLinksInMarkdown($page->markdown, $oldLink, $newLink); $page->html = $html; $page->markdown = $markdown; $page->revision_count++; $page->save(); - $summary = ''; // TODO - Get default summary from translations + $summary = trans('entities.pages_references_update_revision'); $this->revisionRepo->storeNewForPage($page, $summary); } + + protected function updateLinksInMarkdown(string $markdown, string $oldLink, string $newLink): string + { + if (empty($markdown)) { + return $markdown; + } + + $commonLinkRegex = '/(\[.*?\]\()' . preg_quote($oldLink) . '(.*?\))/i'; + $markdown = preg_replace($commonLinkRegex, '$1' . $newLink . '$2', $markdown); + + $referenceLinkRegex = '/(\[.*?\]:\s?)' . preg_quote($oldLink) . '(.*?)($|\s)/i'; + $markdown = preg_replace($referenceLinkRegex, '$1' . $newLink . '$2$3', $markdown); + + return $markdown; + } + + protected function updateLinksInHtml(string $html, string $oldLink, string $newLink): string + { + if (empty($html)) { + return $html; + } + + $html = '' . $html . ''; + libxml_use_internal_errors(true); + $doc = new DOMDocument(); + $doc->loadHTML(mb_convert_encoding($html, 'HTML-ENTITIES', 'UTF-8')); + + $xPath = new DOMXPath($doc); + $anchors = $xPath->query('//a[@href]'); + + /** @var \DOMElement $anchor */ + foreach ($anchors as $anchor) { + $link = $anchor->getAttribute('href'); + $updated = str_ireplace($oldLink, $newLink, $link); + $anchor->setAttribute('href', $updated); + } + + $html = ''; + $topElems = $doc->documentElement->childNodes->item(0)->childNodes; + foreach ($topElems as $child) { + $html .= $doc->saveHTML($child); + } + + return $html; + } } \ No newline at end of file diff --git a/resources/lang/en/entities.php b/resources/lang/en/entities.php index 527665f88..07d4b625d 100644 --- a/resources/lang/en/entities.php +++ b/resources/lang/en/entities.php @@ -249,6 +249,7 @@ return [ 'pages_edit_content_link' => 'Edit Content', 'pages_permissions_active' => 'Page Permissions Active', 'pages_initial_revision' => 'Initial publish', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'New Page', 'pages_editing_draft_notification' => 'You are currently editing a draft that was last saved :timeDiff.', 'pages_draft_edited_notification' => 'This page has been updated by since that time. It is recommended that you discard this draft.', From b86ee6d252b301a94796043f333abdb6603c304c Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Sun, 21 Aug 2022 18:05:19 +0100 Subject: [PATCH 13/45] Rolled out reference link updating logic usage Added test to cover updating of content on reference url change --- app/Entities/Models/BookChild.php | 7 +++ app/Entities/Repos/BaseRepo.php | 11 +++- app/Entities/Repos/PageRepo.php | 33 +++++++---- ...sLinkReplacer.php => ReferenceUpdater.php} | 6 +- tests/References/ReferencesTest.php | 59 +++++++++++++++++++ 5 files changed, 101 insertions(+), 15 deletions(-) rename app/References/{CrossLinkReplacer.php => ReferenceUpdater.php} (95%) diff --git a/app/Entities/Models/BookChild.php b/app/Entities/Models/BookChild.php index e1ba0b6f7..3b1ac1bab 100644 --- a/app/Entities/Models/BookChild.php +++ b/app/Entities/Models/BookChild.php @@ -2,6 +2,7 @@ namespace BookStack\Entities\Models; +use BookStack\References\ReferenceUpdater; use Illuminate\Database\Eloquent\Builder; use Illuminate\Database\Eloquent\Relations\BelongsTo; @@ -57,9 +58,15 @@ abstract class BookChild extends Entity */ public function changeBook(int $newBookId): Entity { + $oldUrl = $this->getUrl(); $this->book_id = $newBookId; $this->refreshSlug(); $this->save(); + + if ($oldUrl !== $this->getUrl()) { + app()->make(ReferenceUpdater::class)->updateEntityPageReferences($this, $oldUrl); + } + $this->refresh(); // Update all child pages if a chapter diff --git a/app/Entities/Repos/BaseRepo.php b/app/Entities/Repos/BaseRepo.php index 39b901383..cfde7fe1c 100644 --- a/app/Entities/Repos/BaseRepo.php +++ b/app/Entities/Repos/BaseRepo.php @@ -6,6 +6,7 @@ use BookStack\Actions\TagRepo; use BookStack\Entities\Models\Entity; use BookStack\Entities\Models\HasCoverImage; use BookStack\Exceptions\ImageUploadException; +use BookStack\References\ReferenceUpdater; use BookStack\Uploads\ImageRepo; use Illuminate\Http\UploadedFile; @@ -13,11 +14,13 @@ class BaseRepo { protected TagRepo $tagRepo; protected ImageRepo $imageRepo; + protected ReferenceUpdater $referenceUpdater; - public function __construct(TagRepo $tagRepo, ImageRepo $imageRepo) + public function __construct(TagRepo $tagRepo, ImageRepo $imageRepo, ReferenceUpdater $referenceUpdater) { $this->tagRepo = $tagRepo; $this->imageRepo = $imageRepo; + $this->referenceUpdater = $referenceUpdater; } /** @@ -48,6 +51,8 @@ class BaseRepo */ public function update(Entity $entity, array $input) { + $oldUrl = $entity->getUrl(); + $entity->fill($input); $entity->updated_by = user()->id; @@ -64,6 +69,10 @@ class BaseRepo $entity->rebuildPermissions(); $entity->indexForSearch(); + + if ($oldUrl !== $entity->getUrl()) { + $this->referenceUpdater->updateEntityPageReferences($entity, $oldUrl); + } } /** diff --git a/app/Entities/Repos/PageRepo.php b/app/Entities/Repos/PageRepo.php index e491d6070..c80cbdb14 100644 --- a/app/Entities/Repos/PageRepo.php +++ b/app/Entities/Repos/PageRepo.php @@ -17,6 +17,7 @@ use BookStack\Exceptions\NotFoundException; use BookStack\Exceptions\PermissionsException; use BookStack\Facades\Activity; use BookStack\References\ReferenceStore; +use BookStack\References\ReferenceUpdater; use Exception; use Illuminate\Pagination\LengthAwarePaginator; @@ -24,16 +25,23 @@ class PageRepo { protected BaseRepo $baseRepo; protected RevisionRepo $revisionRepo; - protected ReferenceStore $references; + protected ReferenceStore $referenceStore; + protected ReferenceUpdater $referenceUpdater; /** * PageRepo constructor. */ - public function __construct(BaseRepo $baseRepo, RevisionRepo $revisionRepo, ReferenceStore $references) + public function __construct( + BaseRepo $baseRepo, + RevisionRepo $revisionRepo, + ReferenceStore $referenceStore, + ReferenceUpdater $referenceUpdater + ) { $this->baseRepo = $baseRepo; $this->revisionRepo = $revisionRepo; - $this->references = $references; + $this->referenceStore = $referenceStore; + $this->referenceUpdater = $referenceUpdater; } /** @@ -127,11 +135,11 @@ class PageRepo public function getNewDraftPage(Entity $parent) { $page = (new Page())->forceFill([ - 'name' => trans('entities.pages_initial_name'), + 'name' => trans('entities.pages_initial_name'), 'created_by' => user()->id, - 'owned_by' => user()->id, + 'owned_by' => user()->id, 'updated_by' => user()->id, - 'draft' => true, + 'draft' => true, ]); if ($parent instanceof Chapter) { @@ -158,12 +166,10 @@ class PageRepo $draft->draft = false; $draft->revision_count = 1; $draft->priority = $this->getNewPriority($draft); - $draft->refreshSlug(); $draft->save(); $this->revisionRepo->storeNewForPage($draft, trans('entities.pages_initial_revision')); - $draft->indexForSearch(); - $this->references->updateForPage($draft); + $this->referenceStore->updateForPage($draft); $draft->refresh(); Activity::add(ActivityType::PAGE_CREATE, $draft); @@ -183,7 +189,7 @@ class PageRepo $this->updateTemplateStatusAndContentFromInput($page, $input); $this->baseRepo->update($page, $input); - $this->references->updateForPage($page); + $this->referenceStore->updateForPage($page); // Update with new details $page->revision_count++; @@ -283,6 +289,7 @@ class PageRepo */ public function restoreRevision(Page $page, int $revisionId): Page { + $oldUrl = $page->getUrl(); $page->revision_count++; /** @var PageRevision $revision */ @@ -301,11 +308,15 @@ class PageRepo $page->refreshSlug(); $page->save(); $page->indexForSearch(); - $this->references->updateForPage($page); + $this->referenceStore->updateForPage($page); $summary = trans('entities.pages_revision_restored_from', ['id' => strval($revisionId), 'summary' => $revision->summary]); $this->revisionRepo->storeNewForPage($page, $summary); + if ($oldUrl !== $page->getUrl()) { + $this->referenceUpdater->updateEntityPageReferences($page, $oldUrl); + } + Activity::add(ActivityType::PAGE_RESTORE, $page); Activity::add(ActivityType::REVISION_RESTORE, $revision); diff --git a/app/References/CrossLinkReplacer.php b/app/References/ReferenceUpdater.php similarity index 95% rename from app/References/CrossLinkReplacer.php rename to app/References/ReferenceUpdater.php index 2df87fc83..15619bc31 100644 --- a/app/References/CrossLinkReplacer.php +++ b/app/References/ReferenceUpdater.php @@ -8,7 +8,7 @@ use BookStack\Entities\Repos\RevisionRepo; use DOMDocument; use DOMXPath; -class CrossLinkReplacer +class ReferenceUpdater { protected ReferenceFetcher $referenceFetcher; protected RevisionRepo $revisionRepo; @@ -53,10 +53,10 @@ class CrossLinkReplacer return $markdown; } - $commonLinkRegex = '/(\[.*?\]\()' . preg_quote($oldLink) . '(.*?\))/i'; + $commonLinkRegex = '/(\[.*?\]\()' . preg_quote($oldLink, '/') . '(.*?\))/i'; $markdown = preg_replace($commonLinkRegex, '$1' . $newLink . '$2', $markdown); - $referenceLinkRegex = '/(\[.*?\]:\s?)' . preg_quote($oldLink) . '(.*?)($|\s)/i'; + $referenceLinkRegex = '/(\[.*?\]:\s?)' . preg_quote($oldLink, '/') . '(.*?)($|\s)/i'; $markdown = preg_replace($referenceLinkRegex, '$1' . $newLink . '$2$3', $markdown); return $markdown; diff --git a/tests/References/ReferencesTest.php b/tests/References/ReferencesTest.php index 9ae226bb7..82cd16680 100644 --- a/tests/References/ReferencesTest.php +++ b/tests/References/ReferencesTest.php @@ -2,6 +2,7 @@ namespace Tests\References; +use BookStack\Entities\Models\Book; use BookStack\Entities\Models\Page; use BookStack\Entities\Repos\PageRepo; use BookStack\Entities\Tools\TrashCan; @@ -116,6 +117,64 @@ class ReferencesTest extends TestCase ->assertSee('There are no tracked references'); } + public function test_pages_leading_to_entity_updated_on_url_change() + { + /** @var Page $pageA */ + /** @var Page $pageB */ + /** @var Book $book */ + $pageA = Page::query()->first(); + $pageB = Page::query()->where('id', '!=', $pageA->id)->first(); + $book = Book::query()->first(); + + foreach ([$pageA, $pageB] as $page) { + $page->html = 'Link'; + $page->save(); + $this->createReference($page, $book); + } + + $this->asEditor()->put($book->getUrl(), [ + 'name' => 'my updated book slugaroo', + ]); + + foreach ([$pageA, $pageB] as $page) { + $page->refresh(); + $this->assertStringContainsString('href="http://localhost/books/my-updated-book-slugaroo"', $page->html); + $this->assertDatabaseHas('page_revisions', [ + 'page_id' => $page->id, + 'summary' => 'System auto-update of internal links' + ]); + } + } + + public function test_markdown_links_leading_to_entity_updated_on_url_change() + { + /** @var Page $page */ + /** @var Book $book */ + $page = Page::query()->first(); + $book = Book::query()->first(); + + $bookUrl = $book->getUrl(); + $markdown = ' + [An awesome link](' . $bookUrl . ') + [An awesome link with query & hash](' . $bookUrl . '?test=yes#cats) + [An awesome link with path](' . $bookUrl . '/an/extra/trail) + [An awesome link with title](' . $bookUrl . ' "title") + [ref]: ' . $bookUrl . '?test=yes#dogs + [ref_without_space]:' . $bookUrl . ' + [ref_with_title]: ' . $bookUrl . ' "title"'; + $page->markdown = $markdown; + $page->save(); + $this->createReference($page, $book); + + $this->asEditor()->put($book->getUrl(), [ + 'name' => 'my updated book slugadoo', + ]); + + $page->refresh(); + $expected = str_replace($bookUrl, 'http://localhost/books/my-updated-book-slugadoo', $markdown); + $this->assertEquals($expected, $page->markdown); + } + protected function createReference(Model $from, Model $to) { (new Reference())->forceFill([ From d134639eca88830d6ce6a9ba816adc9e7bed4183 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Tue, 23 Aug 2022 16:31:34 +0100 Subject: [PATCH 14/45] Doubled default revision limit Due to potential increase of revision entries due to auto-changes. --- .env.example.complete | 2 +- app/Config/app.php | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/.env.example.complete b/.env.example.complete index 45b1c7a86..7a0e3cf25 100644 --- a/.env.example.complete +++ b/.env.example.complete @@ -295,7 +295,7 @@ APP_DEFAULT_DARK_MODE=false # 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 +REVISION_LIMIT=100 # Recycle Bin Lifetime # The number of days that content will remain in the recycle bin before diff --git a/app/Config/app.php b/app/Config/app.php index 53d399abe..e28ebe611 100644 --- a/app/Config/app.php +++ b/app/Config/app.php @@ -22,7 +22,7 @@ return [ // 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), + 'revision_limit' => env('REVISION_LIMIT', 100), // The number of days that content will remain in the recycle bin before // being considered for auto-removal. It is not a guarantee that content will From 760eff397f51e1bb616202dc6a8561ea52bac3a8 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Tue, 23 Aug 2022 17:05:42 +0100 Subject: [PATCH 15/45] Updated API docs with better request format explanation Explained the content-types accepted by BookStack. Made it clear that 'Content-Type' is expected on requests. Added example to shown how to achieve more complex formats using non-json requests. Also added link to api-scripts repo. Related to #3666 and #3652 --- .../api-docs/parts/getting-started.blade.php | 52 ++++++++++++++++++- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/resources/views/api-docs/parts/getting-started.blade.php b/resources/views/api-docs/parts/getting-started.blade.php index 0d271ec5d..76da73e45 100644 --- a/resources/views/api-docs/parts/getting-started.blade.php +++ b/resources/views/api-docs/parts/getting-started.blade.php @@ -2,6 +2,9 @@

This documentation covers use of the REST API.
+ Examples of API usage, in a variety of programming languages, can be found in the BookStack api-scripts repo on GitHub. + +

Some alternative options for extension and customization can be found below:

@@ -38,8 +41,53 @@
Request Format
-

The API is primarily design to be interfaced using JSON so the majority of API endpoints, that accept data, will read JSON request data although application/x-www-form-urlencoded request data is also accepted. Endpoints that receive file data will need data sent in a multipart/form-data format although this will be highlighted in the documentation for such endpoints.

-

For endpoints in this documentation that accept data, a "Body Parameters" table will be available showing the parameters that will accepted in the request. Any rules for the values of such parameters, such as the data-type or if they're required, will be shown alongside the parameter name.

+ +

+ For endpoints in this documentation that accept data a "Body Parameters" table will be available to show the parameters that are accepted in the request. + Any rules for the values of such parameters, such as the data-type or if they're required, will be shown alongside the parameter name. +

+ +

+ The API can accept request data in the following Content-Type formats: +

+ +
    +
  • application/json
  • +
  • application/x-www-form-urlencoded
  • +
  • multipart/form-data
  • +
+ +

+ Regardless of format chosen, ensure you set a Content-Type header on requests so that the system can correctly parse your request data. + The API is primarily designed to be interfaced using JSON, since responses are always in JSON format, hence examples in this documentation will be shown as JSON. + Some endpoints, such as those that receive file data, may require the use of multipart/form-data. This will be mentioned within the description for such endpoints. +

+ +

+ Some data may be expected in a more complex nested structure such as a nested object or array. + These can be sent in non-JSON request formats using square brackets to denote index keys or property names. + Below is an example of a JSON request body data and it's equivalent x-www-form-urlencoded representation. +

+ +

JSON

+ +
{
+  "name": "My new item",
+  "books": [105, 263],
+  "tags": [{"name": "Tag Name", "value": "Tag Value"}],
+}
+ +

x-www-form-urlencoded

+ +
name=My%20new%20item&books%5B0%5D=105&books%5B1%5D=263&tags%5B0%5D%5Bname%5D=Tag%20Name&tags%5B0%5D%5Bvalue%5D=Tag%20Value
+ +

x-www-form-urlencoded (Decoded for readability)

+ +
name=My new item
+books[0]=105
+books[1]=263
+tags[0][name]=Tag Name
+tags[0][value]=Tag Value

From 6edf2c155dd24c4876fc15481ffd74bf3b2e4d05 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Mon, 29 Aug 2022 17:30:26 +0100 Subject: [PATCH 16/45] Added maintenance action to regenerate references --- .../Controllers/MaintenanceController.php | 21 ++++++- resources/lang/en/settings.php | 4 ++ .../views/settings/maintenance.blade.php | 21 ++++++- routes/web.php | 1 + tests/{ => Settings}/RecycleBinTest.php | 3 +- tests/Settings/RegenerateReferencesTest.php | 55 +++++++++++++++++++ tests/{ => Settings}/TestEmailTest.php | 3 +- 7 files changed, 103 insertions(+), 5 deletions(-) rename tests/{ => Settings}/RecycleBinTest.php (99%) create mode 100644 tests/Settings/RegenerateReferencesTest.php rename tests/{ => Settings}/TestEmailTest.php (98%) diff --git a/app/Http/Controllers/MaintenanceController.php b/app/Http/Controllers/MaintenanceController.php index f13266d7c..8bfefb7ac 100644 --- a/app/Http/Controllers/MaintenanceController.php +++ b/app/Http/Controllers/MaintenanceController.php @@ -5,6 +5,7 @@ namespace BookStack\Http\Controllers; use BookStack\Actions\ActivityType; use BookStack\Entities\Tools\TrashCan; use BookStack\Notifications\TestEmail; +use BookStack\References\ReferenceStore; use BookStack\Uploads\ImageService; use Illuminate\Http\Request; @@ -74,6 +75,24 @@ class MaintenanceController extends Controller $this->showErrorNotification($errorMessage); } - return redirect('/settings/maintenance#image-cleanup')->withInput(); + return redirect('/settings/maintenance#image-cleanup'); + } + + /** + * Action to regenerate the reference index in the system. + */ + public function regenerateReferences(ReferenceStore $referenceStore) + { + $this->checkPermission('settings-manage'); + $this->logActivity(ActivityType::MAINTENANCE_ACTION_RUN, 'regenerate-references'); + + try { + $referenceStore->updateForAllPages(); + $this->showSuccessNotification(trans('settings.maint_regen_references_success')); + } catch (\Exception $exception) { + $this->showErrorNotification($exception->getMessage()); + } + + return redirect('/settings/maintenance#regenerate-references'); } } diff --git a/resources/lang/en/settings.php b/resources/lang/en/settings.php index 3bfe70bc4..9dbd96c5a 100755 --- a/resources/lang/en/settings.php +++ b/resources/lang/en/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Congratulations! As you received this email notification, your email settings seem to be configured properly.', 'maint_recycle_bin_desc' => 'Deleted shelves, books, chapters & pages are sent to the recycle bin so they can be restored or permanently deleted. Older items in the recycle bin may be automatically removed after a while depending on system configuration.', 'maint_recycle_bin_open' => 'Open Recycle Bin', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Recycle Bin', diff --git a/resources/views/settings/maintenance.blade.php b/resources/views/settings/maintenance.blade.php index a2a9ebc81..7ee966e00 100644 --- a/resources/views/settings/maintenance.blade.php +++ b/resources/views/settings/maintenance.blade.php @@ -25,9 +25,10 @@

{{ trans('settings.maint_image_cleanup') }}

-
+

{{ trans('settings.maint_image_cleanup_desc') }}

+

{{ trans('settings.maint_timeout_command_note') }}

@@ -55,7 +56,7 @@

{{ trans('settings.maint_send_test_email') }}

-
+

{{ trans('settings.maint_send_test_email_desc') }}

@@ -68,5 +69,21 @@
+
+

{{ trans('settings.maint_regen_references') }}

+
+
+

{{ trans('settings.maint_regen_references_desc') }}

+

{{ trans('settings.maint_timeout_command_note') }}

+
+
+ + {!! csrf_field() !!} + + +
+
+
+
@stop diff --git a/routes/web.php b/routes/web.php index dc46821cb..26d4b6f13 100644 --- a/routes/web.php +++ b/routes/web.php @@ -218,6 +218,7 @@ Route::middleware('auth')->group(function () { Route::get('/settings/maintenance', [MaintenanceController::class, 'index']); Route::delete('/settings/maintenance/cleanup-images', [MaintenanceController::class, 'cleanupImages']); Route::post('/settings/maintenance/send-test-email', [MaintenanceController::class, 'sendTestEmail']); + Route::post('/settings/maintenance/regenerate-references', [MaintenanceController::class, 'regenerateReferences']); // Recycle Bin Route::get('/settings/recycle-bin', [RecycleBinController::class, 'index']); diff --git a/tests/RecycleBinTest.php b/tests/Settings/RecycleBinTest.php similarity index 99% rename from tests/RecycleBinTest.php rename to tests/Settings/RecycleBinTest.php index 0e0524338..465c1aaad 100644 --- a/tests/RecycleBinTest.php +++ b/tests/Settings/RecycleBinTest.php @@ -1,6 +1,6 @@ asAdmin()->get('/settings/maintenance'); + $formCssSelector = 'form[action$="/settings/maintenance/regenerate-references"]'; + $html = $this->withHtml($pageView); + $html->assertElementExists('#regenerate-references'); + $html->assertElementExists($formCssSelector); + $html->assertElementContains($formCssSelector . ' button', 'Regenerate References'); + } + + public function test_action_runs_reference_regen() + { + $this->mock(ReferenceStore::class) + ->shouldReceive('updateForAllPages') + ->once(); + + $resp = $this->asAdmin()->post('/settings/maintenance/regenerate-references'); + $resp->assertRedirect('/settings/maintenance#regenerate-references'); + $this->assertSessionHas('success', 'Reference index has been regenerated!'); + $this->assertActivityExists(ActivityType::MAINTENANCE_ACTION_RUN, null, 'regenerate-references'); + } + + public function test_settings_manage_permission_required() + { + $editor = $this->getEditor(); + $resp = $this->actingAs($editor)->post('/settings/maintenance/regenerate-references'); + $this->assertPermissionError($resp); + + $this->giveUserPermissions($editor, ['settings-manage']); + + $resp = $this->actingAs($editor)->post('/settings/maintenance/regenerate-references'); + $this->assertNotPermissionError($resp); + } + + public function test_action_failed_shown_as_error_notification() + { + $this->mock(ReferenceStore::class) + ->shouldReceive('updateForAllPages') + ->andThrow(\Exception::class, 'A badger stopped the task'); + + $resp = $this->asAdmin()->post('/settings/maintenance/regenerate-references'); + $resp->assertRedirect('/settings/maintenance#regenerate-references'); + $this->assertSessionError('A badger stopped the task'); + } +} diff --git a/tests/TestEmailTest.php b/tests/Settings/TestEmailTest.php similarity index 98% rename from tests/TestEmailTest.php rename to tests/Settings/TestEmailTest.php index 97f98225d..31c51158f 100644 --- a/tests/TestEmailTest.php +++ b/tests/Settings/TestEmailTest.php @@ -1,10 +1,11 @@ Date: Mon, 29 Aug 2022 17:39:50 +0100 Subject: [PATCH 17/45] Fixed phpstan wanring about usage of static --- app/References/CrossLinkParser.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/app/References/CrossLinkParser.php b/app/References/CrossLinkParser.php index 22925884a..1bf1c7d37 100644 --- a/app/References/CrossLinkParser.php +++ b/app/References/CrossLinkParser.php @@ -91,7 +91,7 @@ class CrossLinkParser */ public static function createWithEntityResolvers(): self { - return new static([ + return new self([ new PagePermalinkModelResolver(), new PageLinkModelResolver(), new ChapterLinkModelResolver(), From 1cc7c649dc3a5e1adc0c1bbcee1e7adb61bbd968 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Mon, 29 Aug 2022 17:46:41 +0100 Subject: [PATCH 18/45] Applied StyleCi changes, updated php deps --- app/Auth/Access/Oidc/OidcOAuthProvider.php | 2 +- app/Auth/Access/Oidc/OidcService.php | 17 +- app/Config/app.php | 2 +- .../Commands/RegenerateCommentContent.php | 1 + .../Commands/RegeneratePermissions.php | 1 + app/Console/Commands/RegenerateReferences.php | 1 + app/Entities/Repos/PageRepo.php | 15 +- app/Entities/Repos/RevisionRepo.php | 2 +- app/Http/Controllers/ChapterController.php | 1 - app/Http/Controllers/ReferenceController.php | 8 +- app/References/CrossLinkParser.php | 3 +- .../ModelResolvers/BookLinkModelResolver.php | 4 +- .../BookshelfLinkModelResolver.php | 4 +- .../ChapterLinkModelResolver.php | 2 +- .../ModelResolvers/CrossLinkModelResolver.php | 2 +- .../ModelResolvers/PageLinkModelResolver.php | 2 +- .../PagePermalinkModelResolver.php | 2 +- app/References/Reference.php | 5 +- app/References/ReferenceFetcher.php | 8 +- app/References/ReferenceStore.php | 14 +- app/References/ReferenceUpdater.php | 2 +- composer.lock | 821 ++++++++---------- tests/Auth/OidcTest.php | 12 +- .../RegenerateReferencesCommandTest.php | 6 +- tests/References/CrossLinkParserTest.php | 4 +- tests/References/ReferencesTest.php | 20 +- 26 files changed, 435 insertions(+), 526 deletions(-) diff --git a/app/Auth/Access/Oidc/OidcOAuthProvider.php b/app/Auth/Access/Oidc/OidcOAuthProvider.php index 07bd980a3..d577d8947 100644 --- a/app/Auth/Access/Oidc/OidcOAuthProvider.php +++ b/app/Auth/Access/Oidc/OidcOAuthProvider.php @@ -31,7 +31,7 @@ class OidcOAuthProvider extends AbstractProvider protected $tokenEndpoint; /** - * Scopes to use for the OIDC authorization call + * Scopes to use for the OIDC authorization call. */ protected array $scopes = ['openid', 'profile', 'email']; diff --git a/app/Auth/Access/Oidc/OidcService.php b/app/Auth/Access/Oidc/OidcService.php index 3443baaf6..c4d847804 100644 --- a/app/Auth/Access/Oidc/OidcService.php +++ b/app/Auth/Access/Oidc/OidcService.php @@ -2,9 +2,8 @@ namespace BookStack\Auth\Access\Oidc; -use BookStack\Auth\Access\GroupSyncService; -use Illuminate\Support\Arr; use function auth; +use BookStack\Auth\Access\GroupSyncService; use BookStack\Auth\Access\LoginService; use BookStack\Auth\Access\RegistrationService; use BookStack\Auth\User; @@ -12,6 +11,7 @@ use BookStack\Exceptions\JsonDebugException; use BookStack\Exceptions\StoppedAuthenticationException; use BookStack\Exceptions\UserRegistrationException; use function config; +use Illuminate\Support\Arr; use Illuminate\Support\Facades\Cache; use League\OAuth2\Client\OptionProvider\HttpBasicAuthOptionProvider; use League\OAuth2\Client\Provider\Exception\IdentityProviderException; @@ -35,11 +35,10 @@ class OidcService */ public function __construct( RegistrationService $registrationService, - LoginService $loginService, - HttpClient $httpClient, - GroupSyncService $groupService - ) - { + LoginService $loginService, + HttpClient $httpClient, + GroupSyncService $groupService + ) { $this->registrationService = $registrationService; $this->loginService = $loginService; $this->httpClient = $httpClient; @@ -148,7 +147,7 @@ class OidcService $scopeConfig = $this->config()['additional_scopes'] ?: ''; $scopeArr = explode(',', $scopeConfig); - $scopeArr = array_map(fn(string $scope) => trim($scope), $scopeArr); + $scopeArr = array_map(fn (string $scope) => trim($scope), $scopeArr); return array_filter($scopeArr); } @@ -192,7 +191,7 @@ class OidcService return []; } - return array_values(array_filter($groupsList, function($val) { + return array_values(array_filter($groupsList, function ($val) { return is_string($val); })); } diff --git a/app/Config/app.php b/app/Config/app.php index e28ebe611..ad0b1db0d 100644 --- a/app/Config/app.php +++ b/app/Config/app.php @@ -22,7 +22,7 @@ return [ // 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', 100), + 'revision_limit' => env('REVISION_LIMIT', 100), // The number of days that content will remain in the recycle bin before // being considered for auto-removal. It is not a guarantee that content will diff --git a/app/Console/Commands/RegenerateCommentContent.php b/app/Console/Commands/RegenerateCommentContent.php index 9da48fb0e..3e25dc8a3 100644 --- a/app/Console/Commands/RegenerateCommentContent.php +++ b/app/Console/Commands/RegenerateCommentContent.php @@ -58,6 +58,7 @@ class RegenerateCommentContent extends Command DB::setDefaultConnection($connection); $this->comment('Comment HTML content has been regenerated'); + return 0; } } diff --git a/app/Console/Commands/RegeneratePermissions.php b/app/Console/Commands/RegeneratePermissions.php index 74f96fd42..efb3535d6 100644 --- a/app/Console/Commands/RegeneratePermissions.php +++ b/app/Console/Commands/RegeneratePermissions.php @@ -50,6 +50,7 @@ class RegeneratePermissions extends Command DB::setDefaultConnection($connection); $this->comment('Permissions regenerated'); + return 0; } } diff --git a/app/Console/Commands/RegenerateReferences.php b/app/Console/Commands/RegenerateReferences.php index 805db2207..805fd922d 100644 --- a/app/Console/Commands/RegenerateReferences.php +++ b/app/Console/Commands/RegenerateReferences.php @@ -53,6 +53,7 @@ class RegenerateReferences extends Command DB::setDefaultConnection($connection); $this->comment('References have been regenerated'); + return 0; } } diff --git a/app/Entities/Repos/PageRepo.php b/app/Entities/Repos/PageRepo.php index c80cbdb14..c8eddc398 100644 --- a/app/Entities/Repos/PageRepo.php +++ b/app/Entities/Repos/PageRepo.php @@ -32,12 +32,11 @@ class PageRepo * PageRepo constructor. */ public function __construct( - BaseRepo $baseRepo, - RevisionRepo $revisionRepo, - ReferenceStore $referenceStore, + BaseRepo $baseRepo, + RevisionRepo $revisionRepo, + ReferenceStore $referenceStore, ReferenceUpdater $referenceUpdater - ) - { + ) { $this->baseRepo = $baseRepo; $this->revisionRepo = $revisionRepo; $this->referenceStore = $referenceStore; @@ -135,11 +134,11 @@ class PageRepo public function getNewDraftPage(Entity $parent) { $page = (new Page())->forceFill([ - 'name' => trans('entities.pages_initial_name'), + 'name' => trans('entities.pages_initial_name'), 'created_by' => user()->id, - 'owned_by' => user()->id, + 'owned_by' => user()->id, 'updated_by' => user()->id, - 'draft' => true, + 'draft' => true, ]); if ($parent instanceof Chapter) { diff --git a/app/Entities/Repos/RevisionRepo.php b/app/Entities/Repos/RevisionRepo.php index 76d1d8553..064327ee9 100644 --- a/app/Entities/Repos/RevisionRepo.php +++ b/app/Entities/Repos/RevisionRepo.php @@ -128,4 +128,4 @@ class RevisionRepo ->where('page_id', '=', $pageId) ->orderBy('created_at', 'desc'); } -} \ No newline at end of file +} diff --git a/app/Http/Controllers/ChapterController.php b/app/Http/Controllers/ChapterController.php index 735c760be..6695c2868 100644 --- a/app/Http/Controllers/ChapterController.php +++ b/app/Http/Controllers/ChapterController.php @@ -23,7 +23,6 @@ class ChapterController extends Controller protected ChapterRepo $chapterRepo; protected ReferenceFetcher $referenceFetcher; - public function __construct(ChapterRepo $chapterRepo, ReferenceFetcher $referenceFetcher) { $this->chapterRepo = $chapterRepo; diff --git a/app/Http/Controllers/ReferenceController.php b/app/Http/Controllers/ReferenceController.php index 07b143223..1daf1818c 100644 --- a/app/Http/Controllers/ReferenceController.php +++ b/app/Http/Controllers/ReferenceController.php @@ -27,7 +27,7 @@ class ReferenceController extends Controller $references = $this->referenceFetcher->getPageReferencesToEntity($page); return view('pages.references', [ - 'page' => $page, + 'page' => $page, 'references' => $references, ]); } @@ -42,7 +42,7 @@ class ReferenceController extends Controller $references = $this->referenceFetcher->getPageReferencesToEntity($chapter); return view('chapters.references', [ - 'chapter' => $chapter, + 'chapter' => $chapter, 'references' => $references, ]); } @@ -56,7 +56,7 @@ class ReferenceController extends Controller $references = $this->referenceFetcher->getPageReferencesToEntity($book); return view('books.references', [ - 'book' => $book, + 'book' => $book, 'references' => $references, ]); } @@ -70,7 +70,7 @@ class ReferenceController extends Controller $references = $this->referenceFetcher->getPageReferencesToEntity($shelf); return view('shelves.references', [ - 'shelf' => $shelf, + 'shelf' => $shelf, 'references' => $references, ]); } diff --git a/app/References/CrossLinkParser.php b/app/References/CrossLinkParser.php index 1bf1c7d37..37db203df 100644 --- a/app/References/CrossLinkParser.php +++ b/app/References/CrossLinkParser.php @@ -99,5 +99,4 @@ class CrossLinkParser new BookshelfLinkModelResolver(), ]); } - -} \ No newline at end of file +} diff --git a/app/References/ModelResolvers/BookLinkModelResolver.php b/app/References/ModelResolvers/BookLinkModelResolver.php index 459b13644..12b2c594a 100644 --- a/app/References/ModelResolvers/BookLinkModelResolver.php +++ b/app/References/ModelResolvers/BookLinkModelResolver.php @@ -19,8 +19,8 @@ class BookLinkModelResolver implements CrossLinkModelResolver $bookSlug = $matches[1]; /** @var ?Book $model */ - $model = Book::query()->where('slug', '=', $bookSlug)->first(['id']); + $model = Book::query()->where('slug', '=', $bookSlug)->first(['id']); return $model; } -} \ No newline at end of file +} diff --git a/app/References/ModelResolvers/BookshelfLinkModelResolver.php b/app/References/ModelResolvers/BookshelfLinkModelResolver.php index 7d1636689..5d403ac69 100644 --- a/app/References/ModelResolvers/BookshelfLinkModelResolver.php +++ b/app/References/ModelResolvers/BookshelfLinkModelResolver.php @@ -19,8 +19,8 @@ class BookshelfLinkModelResolver implements CrossLinkModelResolver $shelfSlug = $matches[1]; /** @var ?Bookshelf $model */ - $model = Bookshelf::query()->where('slug', '=', $shelfSlug)->first(['id']); + $model = Bookshelf::query()->where('slug', '=', $shelfSlug)->first(['id']); return $model; } -} \ No newline at end of file +} diff --git a/app/References/ModelResolvers/ChapterLinkModelResolver.php b/app/References/ModelResolvers/ChapterLinkModelResolver.php index fbe75c4f6..b3eb7e7dc 100644 --- a/app/References/ModelResolvers/ChapterLinkModelResolver.php +++ b/app/References/ModelResolvers/ChapterLinkModelResolver.php @@ -24,4 +24,4 @@ class ChapterLinkModelResolver implements CrossLinkModelResolver return $model; } -} \ No newline at end of file +} diff --git a/app/References/ModelResolvers/CrossLinkModelResolver.php b/app/References/ModelResolvers/CrossLinkModelResolver.php index 5cfd02060..f2cb49779 100644 --- a/app/References/ModelResolvers/CrossLinkModelResolver.php +++ b/app/References/ModelResolvers/CrossLinkModelResolver.php @@ -10,4 +10,4 @@ interface CrossLinkModelResolver * Resolve the given href link value to a model. */ public function resolve(string $link): ?Model; -} \ No newline at end of file +} diff --git a/app/References/ModelResolvers/PageLinkModelResolver.php b/app/References/ModelResolvers/PageLinkModelResolver.php index ead17e0a9..bf08d7bfc 100644 --- a/app/References/ModelResolvers/PageLinkModelResolver.php +++ b/app/References/ModelResolvers/PageLinkModelResolver.php @@ -24,4 +24,4 @@ class PageLinkModelResolver implements CrossLinkModelResolver return $model; } -} \ No newline at end of file +} diff --git a/app/References/ModelResolvers/PagePermalinkModelResolver.php b/app/References/ModelResolvers/PagePermalinkModelResolver.php index d59d41925..9537ee268 100644 --- a/app/References/ModelResolvers/PagePermalinkModelResolver.php +++ b/app/References/ModelResolvers/PagePermalinkModelResolver.php @@ -22,4 +22,4 @@ class PagePermalinkModelResolver implements CrossLinkModelResolver return $model; } -} \ No newline at end of file +} diff --git a/app/References/Reference.php b/app/References/Reference.php index 5a490b5b5..1a1c56af3 100644 --- a/app/References/Reference.php +++ b/app/References/Reference.php @@ -2,14 +2,13 @@ namespace BookStack\References; -use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Database\Eloquent\Relations\MorphTo; /** - * @property int $from_id + * @property int $from_id * @property string $from_type - * @property int $to_id + * @property int $to_id * @property string $to_type */ class Reference extends Model diff --git a/app/References/ReferenceFetcher.php b/app/References/ReferenceFetcher.php index fef2744d7..a73463a95 100644 --- a/app/References/ReferenceFetcher.php +++ b/app/References/ReferenceFetcher.php @@ -26,9 +26,9 @@ class ReferenceFetcher $baseQuery = $entity->referencesTo() ->where('from_type', '=', (new Page())->getMorphClass()) ->with([ - 'from' => fn(Relation $query) => $query->select(Page::$listAttributes), - 'from.book' => fn(Relation $query) => $query->scopes('visible'), - 'from.chapter' => fn(Relation $query) => $query->scopes('visible') + 'from' => fn (Relation $query) => $query->select(Page::$listAttributes), + 'from.book' => fn (Relation $query) => $query->scopes('visible'), + 'from.chapter' => fn (Relation $query) => $query->scopes('visible'), ]); $references = $this->permissions->restrictEntityRelationQuery( @@ -59,4 +59,4 @@ class ReferenceFetcher return $count; } -} \ No newline at end of file +} diff --git a/app/References/ReferenceStore.php b/app/References/ReferenceStore.php index f6e3c04a3..4c6db35c5 100644 --- a/app/References/ReferenceStore.php +++ b/app/References/ReferenceStore.php @@ -7,7 +7,6 @@ use Illuminate\Database\Eloquent\Collection; class ReferenceStore { - /** * Update the outgoing references for the given page. */ @@ -25,7 +24,7 @@ class ReferenceStore ->where('from_type', '=', (new Page())->getMorphClass()) ->delete(); - Page::query()->select(['id', 'html'])->chunk(100, function(Collection $pages) { + Page::query()->select(['id', 'html'])->chunk(100, function (Collection $pages) { $this->updateForPages($pages->all()); }); } @@ -44,7 +43,7 @@ class ReferenceStore $parser = CrossLinkParser::createWithEntityResolvers(); $references = []; - $pageIds = array_map(fn(Page $page) => $page->id, $pages); + $pageIds = array_map(fn (Page $page) => $page->id, $pages); Reference::query() ->where('from_type', '=', $pages[0]->getMorphClass()) ->whereIn('from_id', $pageIds) @@ -55,10 +54,10 @@ class ReferenceStore foreach ($models as $model) { $references[] = [ - 'from_id' => $page->id, + 'from_id' => $page->id, 'from_type' => $page->getMorphClass(), - 'to_id' => $model->id, - 'to_type' => $model->getMorphClass(), + 'to_id' => $model->id, + 'to_type' => $model->getMorphClass(), ]; } } @@ -67,5 +66,4 @@ class ReferenceStore Reference::query()->insert($referenceDataChunk); } } - -} \ No newline at end of file +} diff --git a/app/References/ReferenceUpdater.php b/app/References/ReferenceUpdater.php index 15619bc31..d90591ab6 100644 --- a/app/References/ReferenceUpdater.php +++ b/app/References/ReferenceUpdater.php @@ -91,4 +91,4 @@ class ReferenceUpdater return $html; } -} \ No newline at end of file +} diff --git a/composer.lock b/composer.lock index 6118ee4e8..f869d997a 100644 --- a/composer.lock +++ b/composer.lock @@ -58,16 +58,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.231.14", + "version": "3.234.4", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "6b79b9c8204813d9674ffa7badcd567d7f608165" + "reference": "8d56ddb99632200273bb933cbf82b758ab9cde2a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/6b79b9c8204813d9674ffa7badcd567d7f608165", - "reference": "6b79b9c8204813d9674ffa7badcd567d7f608165", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/8d56ddb99632200273bb933cbf82b758ab9cde2a", + "reference": "8d56ddb99632200273bb933cbf82b758ab9cde2a", "shasum": "" }, "require": { @@ -144,9 +144,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.231.14" + "source": "https://github.com/aws/aws-sdk-php/tree/3.234.4" }, - "time": "2022-07-26T18:20:14+00:00" + "time": "2022-08-26T18:20:48+00:00" }, { "name": "bacon/bacon-qr-code", @@ -559,16 +559,16 @@ }, { "name": "doctrine/dbal", - "version": "3.3.7", + "version": "3.4.2", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "9f79d4650430b582f4598fe0954ef4d52fbc0a8a" + "reference": "22de295f10edbe00df74f517612f1fbd711131e2" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/9f79d4650430b582f4598fe0954ef4d52fbc0a8a", - "reference": "9f79d4650430b582f4598fe0954ef4d52fbc0a8a", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/22de295f10edbe00df74f517612f1fbd711131e2", + "reference": "22de295f10edbe00df74f517612f1fbd711131e2", "shasum": "" }, "require": { @@ -576,21 +576,21 @@ "doctrine/cache": "^1.11|^2.0", "doctrine/deprecations": "^0.5.3|^1", "doctrine/event-manager": "^1.0", - "php": "^7.3 || ^8.0", + "php": "^7.4 || ^8.0", "psr/cache": "^1|^2|^3", "psr/log": "^1|^2|^3" }, "require-dev": { "doctrine/coding-standard": "9.0.0", "jetbrains/phpstorm-stubs": "2022.1", - "phpstan/phpstan": "1.7.13", - "phpstan/phpstan-strict-rules": "^1.2", - "phpunit/phpunit": "9.5.20", - "psalm/plugin-phpunit": "0.16.1", - "squizlabs/php_codesniffer": "3.7.0", - "symfony/cache": "^5.2|^6.0", - "symfony/console": "^2.7|^3.0|^4.0|^5.0|^6.0", - "vimeo/psalm": "4.23.0" + "phpstan/phpstan": "1.8.2", + "phpstan/phpstan-strict-rules": "^1.3", + "phpunit/phpunit": "9.5.21", + "psalm/plugin-phpunit": "0.17.0", + "squizlabs/php_codesniffer": "3.7.1", + "symfony/cache": "^5.4|^6.0", + "symfony/console": "^4.4|^5.4|^6.0", + "vimeo/psalm": "4.24.0" }, "suggest": { "symfony/console": "For helpful console commands such as SQL execution and import of files." @@ -650,7 +650,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.3.7" + "source": "https://github.com/doctrine/dbal/tree/3.4.2" }, "funding": [ { @@ -666,7 +666,7 @@ "type": "tidelift" } ], - "time": "2022-06-13T21:43:03+00:00" + "time": "2022-08-21T14:21:06+00:00" }, { "name": "doctrine/deprecations", @@ -713,34 +713,31 @@ }, { "name": "doctrine/event-manager", - "version": "1.1.1", + "version": "1.1.2", "source": { "type": "git", "url": "https://github.com/doctrine/event-manager.git", - "reference": "41370af6a30faa9dc0368c4a6814d596e81aba7f" + "reference": "eb2ecf80e3093e8f3c2769ac838e27d8ede8e683" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/event-manager/zipball/41370af6a30faa9dc0368c4a6814d596e81aba7f", - "reference": "41370af6a30faa9dc0368c4a6814d596e81aba7f", + "url": "https://api.github.com/repos/doctrine/event-manager/zipball/eb2ecf80e3093e8f3c2769ac838e27d8ede8e683", + "reference": "eb2ecf80e3093e8f3c2769ac838e27d8ede8e683", "shasum": "" }, "require": { "php": "^7.1 || ^8.0" }, "conflict": { - "doctrine/common": "<2.9@dev" + "doctrine/common": "<2.9" }, "require-dev": { - "doctrine/coding-standard": "^6.0", - "phpunit/phpunit": "^7.0" + "doctrine/coding-standard": "^9", + "phpstan/phpstan": "~1.4.10 || ^1.5.4", + "phpunit/phpunit": "^7.5 || ^8.5 || ^9.5", + "vimeo/psalm": "^4.22" }, "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.0.x-dev" - } - }, "autoload": { "psr-4": { "Doctrine\\Common\\": "lib/Doctrine/Common" @@ -787,7 +784,7 @@ ], "support": { "issues": "https://github.com/doctrine/event-manager/issues", - "source": "https://github.com/doctrine/event-manager/tree/1.1.x" + "source": "https://github.com/doctrine/event-manager/tree/1.1.2" }, "funding": [ { @@ -803,7 +800,7 @@ "type": "tidelift" } ], - "time": "2020-05-29T18:28:51+00:00" + "time": "2022-07-27T22:18:11+00:00" }, { "name": "doctrine/inflector", @@ -1244,24 +1241,24 @@ }, { "name": "graham-campbell/result-type", - "version": "v1.0.4", + "version": "v1.1.0", "source": { "type": "git", "url": "https://github.com/GrahamCampbell/Result-Type.git", - "reference": "0690bde05318336c7221785f2a932467f98b64ca" + "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/0690bde05318336c7221785f2a932467f98b64ca", - "reference": "0690bde05318336c7221785f2a932467f98b64ca", + "url": "https://api.github.com/repos/GrahamCampbell/Result-Type/zipball/a878d45c1914464426dc94da61c9e1d36ae262a8", + "reference": "a878d45c1914464426dc94da61c9e1d36ae262a8", "shasum": "" }, "require": { - "php": "^7.0 || ^8.0", - "phpoption/phpoption": "^1.8" + "php": "^7.2.5 || ^8.0", + "phpoption/phpoption": "^1.9" }, "require-dev": { - "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8" + "phpunit/phpunit": "^8.5.28 || ^9.5.21" }, "type": "library", "autoload": { @@ -1290,7 +1287,7 @@ ], "support": { "issues": "https://github.com/GrahamCampbell/Result-Type/issues", - "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.0.4" + "source": "https://github.com/GrahamCampbell/Result-Type/tree/v1.1.0" }, "funding": [ { @@ -1302,20 +1299,20 @@ "type": "tidelift" } ], - "time": "2021-11-21T21:41:47+00:00" + "time": "2022-07-30T15:56:11+00:00" }, { "name": "guzzlehttp/guzzle", - "version": "7.4.5", + "version": "7.5.0", "source": { "type": "git", "url": "https://github.com/guzzle/guzzle.git", - "reference": "1dd98b0564cb3f6bd16ce683cb755f94c10fbd82" + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/guzzle/zipball/1dd98b0564cb3f6bd16ce683cb755f94c10fbd82", - "reference": "1dd98b0564cb3f6bd16ce683cb755f94c10fbd82", + "url": "https://api.github.com/repos/guzzle/guzzle/zipball/b50a2a1251152e43f6a37f0fa053e730a67d25ba", + "reference": "b50a2a1251152e43f6a37f0fa053e730a67d25ba", "shasum": "" }, "require": { @@ -1330,10 +1327,10 @@ "psr/http-client-implementation": "1.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", + "bamarni/composer-bin-plugin": "^1.8.1", "ext-curl": "*", "php-http/client-integration-tests": "^3.0", - "phpunit/phpunit": "^8.5.5 || ^9.3.5", + "phpunit/phpunit": "^8.5.29 || ^9.5.23", "psr/log": "^1.1 || ^2.0 || ^3.0" }, "suggest": { @@ -1343,8 +1340,12 @@ }, "type": "library", "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, "branch-alias": { - "dev-master": "7.4-dev" + "dev-master": "7.5-dev" } }, "autoload": { @@ -1410,7 +1411,7 @@ ], "support": { "issues": "https://github.com/guzzle/guzzle/issues", - "source": "https://github.com/guzzle/guzzle/tree/7.4.5" + "source": "https://github.com/guzzle/guzzle/tree/7.5.0" }, "funding": [ { @@ -1426,20 +1427,20 @@ "type": "tidelift" } ], - "time": "2022-06-20T22:16:13+00:00" + "time": "2022-08-28T15:39:27+00:00" }, { "name": "guzzlehttp/promises", - "version": "1.5.1", + "version": "1.5.2", "source": { "type": "git", "url": "https://github.com/guzzle/promises.git", - "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da" + "reference": "b94b2807d85443f9719887892882d0329d1e2598" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/promises/zipball/fe752aedc9fd8fcca3fe7ad05d419d32998a06da", - "reference": "fe752aedc9fd8fcca3fe7ad05d419d32998a06da", + "url": "https://api.github.com/repos/guzzle/promises/zipball/b94b2807d85443f9719887892882d0329d1e2598", + "reference": "b94b2807d85443f9719887892882d0329d1e2598", "shasum": "" }, "require": { @@ -1494,7 +1495,7 @@ ], "support": { "issues": "https://github.com/guzzle/promises/issues", - "source": "https://github.com/guzzle/promises/tree/1.5.1" + "source": "https://github.com/guzzle/promises/tree/1.5.2" }, "funding": [ { @@ -1510,20 +1511,20 @@ "type": "tidelift" } ], - "time": "2021-10-22T20:56:57+00:00" + "time": "2022-08-28T14:55:35+00:00" }, { "name": "guzzlehttp/psr7", - "version": "2.4.0", + "version": "2.4.1", "source": { "type": "git", "url": "https://github.com/guzzle/psr7.git", - "reference": "13388f00956b1503577598873fffb5ae994b5737" + "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/guzzle/psr7/zipball/13388f00956b1503577598873fffb5ae994b5737", - "reference": "13388f00956b1503577598873fffb5ae994b5737", + "url": "https://api.github.com/repos/guzzle/psr7/zipball/69568e4293f4fa993f3b0e51c9723e1e17c41379", + "reference": "69568e4293f4fa993f3b0e51c9723e1e17c41379", "shasum": "" }, "require": { @@ -1537,15 +1538,19 @@ "psr/http-message-implementation": "1.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", + "bamarni/composer-bin-plugin": "^1.8.1", "http-interop/http-factory-tests": "^0.9", - "phpunit/phpunit": "^8.5.8 || ^9.3.10" + "phpunit/phpunit": "^8.5.29 || ^9.5.23" }, "suggest": { "laminas/laminas-httphandlerrunner": "Emit PSR-7 responses" }, "type": "library", "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": false + }, "branch-alias": { "dev-master": "2.4-dev" } @@ -1609,7 +1614,7 @@ ], "support": { "issues": "https://github.com/guzzle/psr7/issues", - "source": "https://github.com/guzzle/psr7/tree/2.4.0" + "source": "https://github.com/guzzle/psr7/tree/2.4.1" }, "funding": [ { @@ -1625,7 +1630,7 @@ "type": "tidelift" } ], - "time": "2022-06-20T21:43:11+00:00" + "time": "2022-08-28T14:45:39+00:00" }, { "name": "intervention/image", @@ -2019,16 +2024,16 @@ }, { "name": "laravel/socialite", - "version": "v5.5.3", + "version": "v5.5.5", "source": { "type": "git", "url": "https://github.com/laravel/socialite.git", - "reference": "9dfc76b31ee041c45a7cae86f23339784abde46d" + "reference": "ce8b2f967eead5a6bae74449e207be6f8046edc3" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/socialite/zipball/9dfc76b31ee041c45a7cae86f23339784abde46d", - "reference": "9dfc76b31ee041c45a7cae86f23339784abde46d", + "url": "https://api.github.com/repos/laravel/socialite/zipball/ce8b2f967eead5a6bae74449e207be6f8046edc3", + "reference": "ce8b2f967eead5a6bae74449e207be6f8046edc3", "shasum": "" }, "require": { @@ -2084,7 +2089,7 @@ "issues": "https://github.com/laravel/socialite/issues", "source": "https://github.com/laravel/socialite" }, - "time": "2022-07-18T13:51:19+00:00" + "time": "2022-08-20T21:32:07+00:00" }, { "name": "laravel/tinker", @@ -2760,16 +2765,16 @@ }, { "name": "masterminds/html5", - "version": "2.7.5", + "version": "2.7.6", "source": { "type": "git", "url": "https://github.com/Masterminds/html5-php.git", - "reference": "f640ac1bdddff06ea333a920c95bbad8872429ab" + "reference": "897eb517a343a2281f11bc5556d6548db7d93947" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/f640ac1bdddff06ea333a920c95bbad8872429ab", - "reference": "f640ac1bdddff06ea333a920c95bbad8872429ab", + "url": "https://api.github.com/repos/Masterminds/html5-php/zipball/897eb517a343a2281f11bc5556d6548db7d93947", + "reference": "897eb517a343a2281f11bc5556d6548db7d93947", "shasum": "" }, "require": { @@ -2823,9 +2828,9 @@ ], "support": { "issues": "https://github.com/Masterminds/html5-php/issues", - "source": "https://github.com/Masterminds/html5-php/tree/2.7.5" + "source": "https://github.com/Masterminds/html5-php/tree/2.7.6" }, - "time": "2021-07-01T14:25:37+00:00" + "time": "2022-08-18T16:18:26+00:00" }, { "name": "monolog/monolog", @@ -2992,16 +2997,16 @@ }, { "name": "nesbot/carbon", - "version": "2.59.1", + "version": "2.62.0", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "a9000603ea337c8df16cc41f8b6be95a65f4d0f5" + "reference": "7507aec3d626797ce2123cf6c6556683be22b5f8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/a9000603ea337c8df16cc41f8b6be95a65f4d0f5", - "reference": "a9000603ea337c8df16cc41f8b6be95a65f4d0f5", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7507aec3d626797ce2123cf6c6556683be22b5f8", + "reference": "7507aec3d626797ce2123cf6c6556683be22b5f8", "shasum": "" }, "require": { @@ -3090,7 +3095,7 @@ "type": "tidelift" } ], - "time": "2022-06-29T21:43:55+00:00" + "time": "2022-08-28T19:48:05+00:00" }, { "name": "nikic/php-parser", @@ -3478,29 +3483,33 @@ }, { "name": "phpoption/phpoption", - "version": "1.8.1", + "version": "1.9.0", "source": { "type": "git", "url": "https://github.com/schmittjoh/php-option.git", - "reference": "eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15" + "reference": "dc5ff11e274a90cc1c743f66c9ad700ce50db9ab" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15", - "reference": "eab7a0df01fe2344d172bff4cd6dbd3f8b84ad15", + "url": "https://api.github.com/repos/schmittjoh/php-option/zipball/dc5ff11e274a90cc1c743f66c9ad700ce50db9ab", + "reference": "dc5ff11e274a90cc1c743f66c9ad700ce50db9ab", "shasum": "" }, "require": { - "php": "^7.0 || ^8.0" + "php": "^7.2.5 || ^8.0" }, "require-dev": { - "bamarni/composer-bin-plugin": "^1.4.1", - "phpunit/phpunit": "^6.5.14 || ^7.5.20 || ^8.5.19 || ^9.5.8" + "bamarni/composer-bin-plugin": "^1.8", + "phpunit/phpunit": "^8.5.28 || ^9.5.21" }, "type": "library", "extra": { + "bamarni-bin": { + "bin-links": true, + "forward-command": true + }, "branch-alias": { - "dev-master": "1.8-dev" + "dev-master": "1.9-dev" } }, "autoload": { @@ -3533,7 +3542,7 @@ ], "support": { "issues": "https://github.com/schmittjoh/php-option/issues", - "source": "https://github.com/schmittjoh/php-option/tree/1.8.1" + "source": "https://github.com/schmittjoh/php-option/tree/1.9.0" }, "funding": [ { @@ -3545,7 +3554,7 @@ "type": "tidelift" } ], - "time": "2021-12-04T23:24:31+00:00" + "time": "2022-07-30T15:51:26+00:00" }, { "name": "phpseclib/phpseclib", @@ -4184,16 +4193,16 @@ }, { "name": "psy/psysh", - "version": "v0.11.7", + "version": "v0.11.8", "source": { "type": "git", "url": "https://github.com/bobthecow/psysh.git", - "reference": "77fc7270031fbc28f9a7bea31385da5c4855cb7a" + "reference": "f455acf3645262ae389b10e9beba0c358aa6994e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/bobthecow/psysh/zipball/77fc7270031fbc28f9a7bea31385da5c4855cb7a", - "reference": "77fc7270031fbc28f9a7bea31385da5c4855cb7a", + "url": "https://api.github.com/repos/bobthecow/psysh/zipball/f455acf3645262ae389b10e9beba0c358aa6994e", + "reference": "f455acf3645262ae389b10e9beba0c358aa6994e", "shasum": "" }, "require": { @@ -4254,9 +4263,9 @@ ], "support": { "issues": "https://github.com/bobthecow/psysh/issues", - "source": "https://github.com/bobthecow/psysh/tree/v0.11.7" + "source": "https://github.com/bobthecow/psysh/tree/v0.11.8" }, - "time": "2022-07-07T13:49:11+00:00" + "time": "2022-07-28T14:25:11+00:00" }, { "name": "ralouphie/getallheaders", @@ -5044,16 +5053,16 @@ }, { "name": "symfony/console", - "version": "v5.4.10", + "version": "v5.4.12", "source": { "type": "git", "url": "https://github.com/symfony/console.git", - "reference": "4d671ab4ddac94ee439ea73649c69d9d200b5000" + "reference": "c072aa8f724c3af64e2c7a96b796a4863d24dba1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/console/zipball/4d671ab4ddac94ee439ea73649c69d9d200b5000", - "reference": "4d671ab4ddac94ee439ea73649c69d9d200b5000", + "url": "https://api.github.com/repos/symfony/console/zipball/c072aa8f724c3af64e2c7a96b796a4863d24dba1", + "reference": "c072aa8f724c3af64e2c7a96b796a4863d24dba1", "shasum": "" }, "require": { @@ -5123,7 +5132,7 @@ "terminal" ], "support": { - "source": "https://github.com/symfony/console/tree/v5.4.10" + "source": "https://github.com/symfony/console/tree/v5.4.12" }, "funding": [ { @@ -5139,20 +5148,20 @@ "type": "tidelift" } ], - "time": "2022-06-26T13:00:04+00:00" + "time": "2022-08-17T13:18:05+00:00" }, { "name": "symfony/css-selector", - "version": "v5.4.3", + "version": "v5.4.11", "source": { "type": "git", "url": "https://github.com/symfony/css-selector.git", - "reference": "b0a190285cd95cb019237851205b8140ef6e368e" + "reference": "c1681789f059ab756001052164726ae88512ae3d" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/css-selector/zipball/b0a190285cd95cb019237851205b8140ef6e368e", - "reference": "b0a190285cd95cb019237851205b8140ef6e368e", + "url": "https://api.github.com/repos/symfony/css-selector/zipball/c1681789f059ab756001052164726ae88512ae3d", + "reference": "c1681789f059ab756001052164726ae88512ae3d", "shasum": "" }, "require": { @@ -5189,7 +5198,7 @@ "description": "Converts CSS selectors to XPath expressions", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/css-selector/tree/v5.4.3" + "source": "https://github.com/symfony/css-selector/tree/v5.4.11" }, "funding": [ { @@ -5205,7 +5214,7 @@ "type": "tidelift" } ], - "time": "2022-01-02T09:53:40+00:00" + "time": "2022-06-27T16:58:25+00:00" }, { "name": "symfony/deprecation-contracts", @@ -5276,16 +5285,16 @@ }, { "name": "symfony/error-handler", - "version": "v5.4.9", + "version": "v5.4.11", "source": { "type": "git", "url": "https://github.com/symfony/error-handler.git", - "reference": "c116cda1f51c678782768dce89a45f13c949455d" + "reference": "f75d17cb4769eb38cd5fccbda95cd80a054d35c8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/error-handler/zipball/c116cda1f51c678782768dce89a45f13c949455d", - "reference": "c116cda1f51c678782768dce89a45f13c949455d", + "url": "https://api.github.com/repos/symfony/error-handler/zipball/f75d17cb4769eb38cd5fccbda95cd80a054d35c8", + "reference": "f75d17cb4769eb38cd5fccbda95cd80a054d35c8", "shasum": "" }, "require": { @@ -5327,7 +5336,7 @@ "description": "Provides tools to manage errors and ease debugging PHP code", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/error-handler/tree/v5.4.9" + "source": "https://github.com/symfony/error-handler/tree/v5.4.11" }, "funding": [ { @@ -5343,7 +5352,7 @@ "type": "tidelift" } ], - "time": "2022-05-21T13:57:48+00:00" + "time": "2022-07-29T07:37:50+00:00" }, { "name": "symfony/event-dispatcher", @@ -5511,16 +5520,16 @@ }, { "name": "symfony/finder", - "version": "v5.4.8", + "version": "v5.4.11", "source": { "type": "git", "url": "https://github.com/symfony/finder.git", - "reference": "9b630f3427f3ebe7cd346c277a1408b00249dad9" + "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/finder/zipball/9b630f3427f3ebe7cd346c277a1408b00249dad9", - "reference": "9b630f3427f3ebe7cd346c277a1408b00249dad9", + "url": "https://api.github.com/repos/symfony/finder/zipball/7872a66f57caffa2916a584db1aa7f12adc76f8c", + "reference": "7872a66f57caffa2916a584db1aa7f12adc76f8c", "shasum": "" }, "require": { @@ -5554,7 +5563,7 @@ "description": "Finds files and directories via an intuitive fluent interface", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/finder/tree/v5.4.8" + "source": "https://github.com/symfony/finder/tree/v5.4.11" }, "funding": [ { @@ -5570,20 +5579,20 @@ "type": "tidelift" } ], - "time": "2022-04-15T08:07:45+00:00" + "time": "2022-07-29T07:37:50+00:00" }, { "name": "symfony/http-foundation", - "version": "v5.4.10", + "version": "v5.4.12", "source": { "type": "git", "url": "https://github.com/symfony/http-foundation.git", - "reference": "e7793b7906f72a8cc51054fbca9dcff7a8af1c1e" + "reference": "f4bfe9611b113b15d98a43da68ec9b5a00d56791" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-foundation/zipball/e7793b7906f72a8cc51054fbca9dcff7a8af1c1e", - "reference": "e7793b7906f72a8cc51054fbca9dcff7a8af1c1e", + "url": "https://api.github.com/repos/symfony/http-foundation/zipball/f4bfe9611b113b15d98a43da68ec9b5a00d56791", + "reference": "f4bfe9611b113b15d98a43da68ec9b5a00d56791", "shasum": "" }, "require": { @@ -5595,8 +5604,11 @@ "require-dev": { "predis/predis": "~1.0", "symfony/cache": "^4.4|^5.0|^6.0", + "symfony/dependency-injection": "^5.4|^6.0", "symfony/expression-language": "^4.4|^5.0|^6.0", - "symfony/mime": "^4.4|^5.0|^6.0" + "symfony/http-kernel": "^5.4.12|^6.0.12|^6.1.4", + "symfony/mime": "^4.4|^5.0|^6.0", + "symfony/rate-limiter": "^5.2|^6.0" }, "suggest": { "symfony/mime": "To use the file extension guesser" @@ -5627,7 +5639,7 @@ "description": "Defines an object-oriented layer for the HTTP specification", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-foundation/tree/v5.4.10" + "source": "https://github.com/symfony/http-foundation/tree/v5.4.12" }, "funding": [ { @@ -5643,20 +5655,20 @@ "type": "tidelift" } ], - "time": "2022-06-19T13:13:40+00:00" + "time": "2022-08-19T07:33:17+00:00" }, { "name": "symfony/http-kernel", - "version": "v5.4.10", + "version": "v5.4.12", "source": { "type": "git", "url": "https://github.com/symfony/http-kernel.git", - "reference": "255ae3b0a488d78fbb34da23d3e0c059874b5948" + "reference": "37f660fa3bcd78fe4893ce23ebe934618ec099be" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/http-kernel/zipball/255ae3b0a488d78fbb34da23d3e0c059874b5948", - "reference": "255ae3b0a488d78fbb34da23d3e0c059874b5948", + "url": "https://api.github.com/repos/symfony/http-kernel/zipball/37f660fa3bcd78fe4893ce23ebe934618ec099be", + "reference": "37f660fa3bcd78fe4893ce23ebe934618ec099be", "shasum": "" }, "require": { @@ -5739,7 +5751,7 @@ "description": "Provides a structured process for converting a Request into a Response", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/http-kernel/tree/v5.4.10" + "source": "https://github.com/symfony/http-kernel/tree/v5.4.12" }, "funding": [ { @@ -5755,20 +5767,20 @@ "type": "tidelift" } ], - "time": "2022-06-26T16:57:59+00:00" + "time": "2022-08-26T14:40:40+00:00" }, { "name": "symfony/mime", - "version": "v5.4.10", + "version": "v5.4.12", "source": { "type": "git", "url": "https://github.com/symfony/mime.git", - "reference": "02265e1e5111c3cd7480387af25e82378b7ab9cc" + "reference": "03876e9c5a36f5b45e7d9a381edda5421eff8a90" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/mime/zipball/02265e1e5111c3cd7480387af25e82378b7ab9cc", - "reference": "02265e1e5111c3cd7480387af25e82378b7ab9cc", + "url": "https://api.github.com/repos/symfony/mime/zipball/03876e9c5a36f5b45e7d9a381edda5421eff8a90", + "reference": "03876e9c5a36f5b45e7d9a381edda5421eff8a90", "shasum": "" }, "require": { @@ -5822,7 +5834,7 @@ "mime-type" ], "support": { - "source": "https://github.com/symfony/mime/tree/v5.4.10" + "source": "https://github.com/symfony/mime/tree/v5.4.12" }, "funding": [ { @@ -5838,7 +5850,7 @@ "type": "tidelift" } ], - "time": "2022-06-09T12:22:40+00:00" + "time": "2022-08-19T14:24:03+00:00" }, { "name": "symfony/polyfill-ctype", @@ -6659,16 +6671,16 @@ }, { "name": "symfony/process", - "version": "v5.4.8", + "version": "v5.4.11", "source": { "type": "git", "url": "https://github.com/symfony/process.git", - "reference": "597f3fff8e3e91836bb0bd38f5718b56ddbde2f3" + "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/process/zipball/597f3fff8e3e91836bb0bd38f5718b56ddbde2f3", - "reference": "597f3fff8e3e91836bb0bd38f5718b56ddbde2f3", + "url": "https://api.github.com/repos/symfony/process/zipball/6e75fe6874cbc7e4773d049616ab450eff537bf1", + "reference": "6e75fe6874cbc7e4773d049616ab450eff537bf1", "shasum": "" }, "require": { @@ -6701,7 +6713,7 @@ "description": "Executes commands in sub-processes", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/process/tree/v5.4.8" + "source": "https://github.com/symfony/process/tree/v5.4.11" }, "funding": [ { @@ -6717,20 +6729,20 @@ "type": "tidelift" } ], - "time": "2022-04-08T05:07:18+00:00" + "time": "2022-06-27T16:58:25+00:00" }, { "name": "symfony/routing", - "version": "v5.4.8", + "version": "v5.4.11", "source": { "type": "git", "url": "https://github.com/symfony/routing.git", - "reference": "e07817bb6244ea33ef5ad31abc4a9288bef3f2f7" + "reference": "3e01ccd9b2a3a4167ba2b3c53612762300300226" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/routing/zipball/e07817bb6244ea33ef5ad31abc4a9288bef3f2f7", - "reference": "e07817bb6244ea33ef5ad31abc4a9288bef3f2f7", + "url": "https://api.github.com/repos/symfony/routing/zipball/3e01ccd9b2a3a4167ba2b3c53612762300300226", + "reference": "3e01ccd9b2a3a4167ba2b3c53612762300300226", "shasum": "" }, "require": { @@ -6791,7 +6803,7 @@ "url" ], "support": { - "source": "https://github.com/symfony/routing/tree/v5.4.8" + "source": "https://github.com/symfony/routing/tree/v5.4.11" }, "funding": [ { @@ -6807,7 +6819,7 @@ "type": "tidelift" } ], - "time": "2022-04-18T21:45:37+00:00" + "time": "2022-07-20T13:00:38+00:00" }, { "name": "symfony/service-contracts", @@ -6894,16 +6906,16 @@ }, { "name": "symfony/string", - "version": "v5.4.10", + "version": "v5.4.12", "source": { "type": "git", "url": "https://github.com/symfony/string.git", - "reference": "4432bc7df82a554b3e413a8570ce2fea90e94097" + "reference": "2fc515e512d721bf31ea76bd02fe23ada4640058" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/string/zipball/4432bc7df82a554b3e413a8570ce2fea90e94097", - "reference": "4432bc7df82a554b3e413a8570ce2fea90e94097", + "url": "https://api.github.com/repos/symfony/string/zipball/2fc515e512d721bf31ea76bd02fe23ada4640058", + "reference": "2fc515e512d721bf31ea76bd02fe23ada4640058", "shasum": "" }, "require": { @@ -6960,7 +6972,7 @@ "utf8" ], "support": { - "source": "https://github.com/symfony/string/tree/v5.4.10" + "source": "https://github.com/symfony/string/tree/v5.4.12" }, "funding": [ { @@ -6976,20 +6988,20 @@ "type": "tidelift" } ], - "time": "2022-06-26T15:57:47+00:00" + "time": "2022-08-12T17:03:11+00:00" }, { "name": "symfony/translation", - "version": "v5.4.9", + "version": "v5.4.12", "source": { "type": "git", "url": "https://github.com/symfony/translation.git", - "reference": "1639abc1177d26bcd4320e535e664cef067ab0ca" + "reference": "42ecc77eb4f229ce2df702a648ec93b8478d76ae" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/translation/zipball/1639abc1177d26bcd4320e535e664cef067ab0ca", - "reference": "1639abc1177d26bcd4320e535e664cef067ab0ca", + "url": "https://api.github.com/repos/symfony/translation/zipball/42ecc77eb4f229ce2df702a648ec93b8478d76ae", + "reference": "42ecc77eb4f229ce2df702a648ec93b8478d76ae", "shasum": "" }, "require": { @@ -7057,7 +7069,7 @@ "description": "Provides tools to internationalize your application", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/translation/tree/v5.4.9" + "source": "https://github.com/symfony/translation/tree/v5.4.12" }, "funding": [ { @@ -7073,7 +7085,7 @@ "type": "tidelift" } ], - "time": "2022-05-06T12:33:37+00:00" + "time": "2022-08-02T15:52:22+00:00" }, { "name": "symfony/translation-contracts", @@ -7155,16 +7167,16 @@ }, { "name": "symfony/var-dumper", - "version": "v5.4.9", + "version": "v5.4.11", "source": { "type": "git", "url": "https://github.com/symfony/var-dumper.git", - "reference": "af52239a330fafd192c773795520dc2dd62b5657" + "reference": "b8f306d7b8ef34fb3db3305be97ba8e088fb4861" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/var-dumper/zipball/af52239a330fafd192c773795520dc2dd62b5657", - "reference": "af52239a330fafd192c773795520dc2dd62b5657", + "url": "https://api.github.com/repos/symfony/var-dumper/zipball/b8f306d7b8ef34fb3db3305be97ba8e088fb4861", + "reference": "b8f306d7b8ef34fb3db3305be97ba8e088fb4861", "shasum": "" }, "require": { @@ -7224,7 +7236,7 @@ "dump" ], "support": { - "source": "https://github.com/symfony/var-dumper/tree/v5.4.9" + "source": "https://github.com/symfony/var-dumper/tree/v5.4.11" }, "funding": [ { @@ -7240,7 +7252,7 @@ "type": "tidelift" } ], - "time": "2022-05-21T10:24:18+00:00" + "time": "2022-07-20T13:00:38+00:00" }, { "name": "tijsverkoyen/css-to-inline-styles", @@ -7586,25 +7598,99 @@ "time": "2022-07-20T07:14:26+00:00" }, { - "name": "composer/composer", - "version": "2.3.10", + "name": "composer/class-map-generator", + "version": "1.0.0", "source": { "type": "git", - "url": "https://github.com/composer/composer.git", - "reference": "ebac357c0a41359f3981098729042ed6dedc97ba" + "url": "https://github.com/composer/class-map-generator.git", + "reference": "1e1cb2b791facb2dfe32932a7718cf2571187513" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/composer/composer/zipball/ebac357c0a41359f3981098729042ed6dedc97ba", - "reference": "ebac357c0a41359f3981098729042ed6dedc97ba", + "url": "https://api.github.com/repos/composer/class-map-generator/zipball/1e1cb2b791facb2dfe32932a7718cf2571187513", + "reference": "1e1cb2b791facb2dfe32932a7718cf2571187513", + "shasum": "" + }, + "require": { + "composer/pcre": "^2 || ^3", + "php": "^7.2 || ^8.0", + "symfony/finder": "^4.4 || ^5.3 || ^6" + }, + "require-dev": { + "phpstan/phpstan": "^1.6", + "phpstan/phpstan-deprecation-rules": "^1", + "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan-strict-rules": "^1.1", + "symfony/filesystem": "^5.4 || ^6", + "symfony/phpunit-bridge": "^5" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "1.x-dev" + } + }, + "autoload": { + "psr-4": { + "Composer\\ClassMapGenerator\\": "src" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "https://seld.be" + } + ], + "description": "Utilities to scan PHP code and generate class maps.", + "keywords": [ + "classmap" + ], + "support": { + "issues": "https://github.com/composer/class-map-generator/issues", + "source": "https://github.com/composer/class-map-generator/tree/1.0.0" + }, + "funding": [ + { + "url": "https://packagist.com", + "type": "custom" + }, + { + "url": "https://github.com/composer", + "type": "github" + }, + { + "url": "https://tidelift.com/funding/github/packagist/composer/composer", + "type": "tidelift" + } + ], + "time": "2022-06-19T11:31:27+00:00" + }, + { + "name": "composer/composer", + "version": "2.4.1", + "source": { + "type": "git", + "url": "https://github.com/composer/composer.git", + "reference": "777d542e3af65f8e7a66a4d98ce7a697da339414" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/composer/composer/zipball/777d542e3af65f8e7a66a4d98ce7a697da339414", + "reference": "777d542e3af65f8e7a66a4d98ce7a697da339414", "shasum": "" }, "require": { "composer/ca-bundle": "^1.0", + "composer/class-map-generator": "^1.0", "composer/metadata-minifier": "^1.0", "composer/pcre": "^2 || ^3", "composer/semver": "^3.0", - "composer/spdx-licenses": "^1.2", + "composer/spdx-licenses": "^1.5.7", "composer/xdebug-handler": "^2.0.2 || ^3.0.3", "justinrainbow/json-schema": "^5.2.11", "php": "^7.2.5 || ^8.0", @@ -7612,7 +7698,8 @@ "react/promise": "^2.8", "seld/jsonlint": "^1.4", "seld/phar-utils": "^1.2", - "symfony/console": "^5.4.7 || ^6.0.7", + "seld/signal-handler": "^2.0", + "symfony/console": "^5.4.11 || ^6.0.11", "symfony/filesystem": "^5.4 || ^6.0", "symfony/finder": "^5.4 || ^6.0", "symfony/polyfill-php73": "^1.24", @@ -7638,7 +7725,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-main": "2.3-dev" + "dev-main": "2.4-dev" }, "phpstan": { "includes": [ @@ -7677,7 +7764,7 @@ "support": { "irc": "ircs://irc.libera.chat:6697/composer", "issues": "https://github.com/composer/composer/issues", - "source": "https://github.com/composer/composer/tree/2.3.10" + "source": "https://github.com/composer/composer/tree/2.4.1" }, "funding": [ { @@ -7693,7 +7780,7 @@ "type": "tidelift" } ], - "time": "2022-07-13T13:48:23+00:00" + "time": "2022-08-20T09:44:50+00:00" }, { "name": "composer/metadata-minifier", @@ -8305,16 +8392,16 @@ }, { "name": "itsgoingd/clockwork", - "version": "v5.1.6", + "version": "v5.1.7", "source": { "type": "git", "url": "https://github.com/itsgoingd/clockwork.git", - "reference": "9df41432da1d8cb39c7fda383ddcc02231c83ff3" + "reference": "2cad6c75dc2b96cbfd48c0511bb035a4e328c17f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/itsgoingd/clockwork/zipball/9df41432da1d8cb39c7fda383ddcc02231c83ff3", - "reference": "9df41432da1d8cb39c7fda383ddcc02231c83ff3", + "url": "https://api.github.com/repos/itsgoingd/clockwork/zipball/2cad6c75dc2b96cbfd48c0511bb035a4e328c17f", + "reference": "2cad6c75dc2b96cbfd48c0511bb035a4e328c17f", "shasum": "" }, "require": { @@ -8361,7 +8448,7 @@ ], "support": { "issues": "https://github.com/itsgoingd/clockwork/issues", - "source": "https://github.com/itsgoingd/clockwork/tree/v5.1.6" + "source": "https://github.com/itsgoingd/clockwork/tree/v5.1.7" }, "funding": [ { @@ -8369,7 +8456,7 @@ "type": "github" } ], - "time": "2022-04-12T21:35:47+00:00" + "time": "2022-08-14T21:23:22+00:00" }, { "name": "justinrainbow/json-schema", @@ -8868,233 +8955,6 @@ }, "time": "2022-02-21T01:04:05+00:00" }, - { - "name": "phpdocumentor/reflection-common", - "version": "2.2.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionCommon.git", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionCommon/zipball/1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "reference": "1d01c49d4ed62f25aa84a747ad35d5a16924662b", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-2.x": "2.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src/" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Jaap van Otterdijk", - "email": "opensource@ijaap.nl" - } - ], - "description": "Common reflection classes used by phpdocumentor to reflect the code structure", - "homepage": "http://www.phpdoc.org", - "keywords": [ - "FQSEN", - "phpDocumentor", - "phpdoc", - "reflection", - "static analysis" - ], - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionCommon/issues", - "source": "https://github.com/phpDocumentor/ReflectionCommon/tree/2.x" - }, - "time": "2020-06-27T09:03:43+00:00" - }, - { - "name": "phpdocumentor/reflection-docblock", - "version": "5.3.0", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/ReflectionDocBlock.git", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/ReflectionDocBlock/zipball/622548b623e81ca6d78b721c5e029f4ce664f170", - "reference": "622548b623e81ca6d78b721c5e029f4ce664f170", - "shasum": "" - }, - "require": { - "ext-filter": "*", - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.2", - "phpdocumentor/type-resolver": "^1.3", - "webmozart/assert": "^1.9.1" - }, - "require-dev": { - "mockery/mockery": "~1.3.2", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "5.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - }, - { - "name": "Jaap van Otterdijk", - "email": "account@ijaap.nl" - } - ], - "description": "With this component, a library can provide support for annotations via DocBlocks or otherwise retrieve information that is embedded in a DocBlock.", - "support": { - "issues": "https://github.com/phpDocumentor/ReflectionDocBlock/issues", - "source": "https://github.com/phpDocumentor/ReflectionDocBlock/tree/5.3.0" - }, - "time": "2021-10-19T17:43:47+00:00" - }, - { - "name": "phpdocumentor/type-resolver", - "version": "1.6.1", - "source": { - "type": "git", - "url": "https://github.com/phpDocumentor/TypeResolver.git", - "reference": "77a32518733312af16a44300404e945338981de3" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpDocumentor/TypeResolver/zipball/77a32518733312af16a44300404e945338981de3", - "reference": "77a32518733312af16a44300404e945338981de3", - "shasum": "" - }, - "require": { - "php": "^7.2 || ^8.0", - "phpdocumentor/reflection-common": "^2.0" - }, - "require-dev": { - "ext-tokenizer": "*", - "psalm/phar": "^4.8" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-1.x": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "phpDocumentor\\Reflection\\": "src" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Mike van Riel", - "email": "me@mikevanriel.com" - } - ], - "description": "A PSR-5 based resolver of Class names, Types and Structural Element Names", - "support": { - "issues": "https://github.com/phpDocumentor/TypeResolver/issues", - "source": "https://github.com/phpDocumentor/TypeResolver/tree/1.6.1" - }, - "time": "2022-03-15T21:29:03+00:00" - }, - { - "name": "phpspec/prophecy", - "version": "v1.15.0", - "source": { - "type": "git", - "url": "https://github.com/phpspec/prophecy.git", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13" - }, - "dist": { - "type": "zip", - "url": "https://api.github.com/repos/phpspec/prophecy/zipball/bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "reference": "bbcd7380b0ebf3961ee21409db7b38bc31d69a13", - "shasum": "" - }, - "require": { - "doctrine/instantiator": "^1.2", - "php": "^7.2 || ~8.0, <8.2", - "phpdocumentor/reflection-docblock": "^5.2", - "sebastian/comparator": "^3.0 || ^4.0", - "sebastian/recursion-context": "^3.0 || ^4.0" - }, - "require-dev": { - "phpspec/phpspec": "^6.0 || ^7.0", - "phpunit/phpunit": "^8.0 || ^9.0" - }, - "type": "library", - "extra": { - "branch-alias": { - "dev-master": "1.x-dev" - } - }, - "autoload": { - "psr-4": { - "Prophecy\\": "src/Prophecy" - } - }, - "notification-url": "https://packagist.org/downloads/", - "license": [ - "MIT" - ], - "authors": [ - { - "name": "Konstantin Kudryashov", - "email": "ever.zet@gmail.com", - "homepage": "http://everzet.com" - }, - { - "name": "Marcello Duarte", - "email": "marcello.duarte@gmail.com" - } - ], - "description": "Highly opinionated mocking framework for PHP 5.3+", - "homepage": "https://github.com/phpspec/prophecy", - "keywords": [ - "Double", - "Dummy", - "fake", - "mock", - "spy", - "stub" - ], - "support": { - "issues": "https://github.com/phpspec/prophecy/issues", - "source": "https://github.com/phpspec/prophecy/tree/v1.15.0" - }, - "time": "2021-12-08T12:19:24+00:00" - }, { "name": "phpstan/phpstan", "version": "1.8.2", @@ -9156,23 +9016,23 @@ }, { "name": "phpunit/php-code-coverage", - "version": "9.2.15", + "version": "9.2.16", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f" + "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2e9da11878c4202f97915c1cb4bb1ca318a63f5f", - "reference": "2e9da11878c4202f97915c1cb4bb1ca318a63f5f", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2593003befdcc10db5e213f9f28814f5aa8ac073", + "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073", "shasum": "" }, "require": { "ext-dom": "*", "ext-libxml": "*", "ext-xmlwriter": "*", - "nikic/php-parser": "^4.13.0", + "nikic/php-parser": "^4.14", "php": ">=7.3", "phpunit/php-file-iterator": "^3.0.3", "phpunit/php-text-template": "^2.0.2", @@ -9221,7 +9081,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.15" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.16" }, "funding": [ { @@ -9229,7 +9089,7 @@ "type": "github" } ], - "time": "2022-03-07T09:28:20+00:00" + "time": "2022-08-20T05:26:47+00:00" }, { "name": "phpunit/php-file-iterator", @@ -9474,16 +9334,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.21", + "version": "9.5.23", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "0e32b76be457de00e83213528f6bb37e2a38fcb1" + "reference": "888556852e7e9bbeeedb9656afe46118765ade34" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/0e32b76be457de00e83213528f6bb37e2a38fcb1", - "reference": "0e32b76be457de00e83213528f6bb37e2a38fcb1", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/888556852e7e9bbeeedb9656afe46118765ade34", + "reference": "888556852e7e9bbeeedb9656afe46118765ade34", "shasum": "" }, "require": { @@ -9498,7 +9358,6 @@ "phar-io/manifest": "^2.0.3", "phar-io/version": "^3.0.2", "php": ">=7.3", - "phpspec/prophecy": "^1.12.1", "phpunit/php-code-coverage": "^9.2.13", "phpunit/php-file-iterator": "^3.0.5", "phpunit/php-invoker": "^3.1.1", @@ -9516,9 +9375,6 @@ "sebastian/type": "^3.0", "sebastian/version": "^3.0.2" }, - "require-dev": { - "phpspec/prophecy-phpunit": "^2.0.1" - }, "suggest": { "ext-soap": "*", "ext-xdebug": "*" @@ -9560,7 +9416,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.21" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.23" }, "funding": [ { @@ -9572,7 +9428,7 @@ "type": "github" } ], - "time": "2022-06-19T12:14:25+00:00" + "time": "2022-08-22T14:01:36+00:00" }, { "name": "react/promise", @@ -10507,16 +10363,16 @@ }, { "name": "sebastian/type", - "version": "3.0.0", + "version": "3.1.0", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/type.git", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad" + "reference": "fb44e1cc6e557418387ad815780360057e40753e" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", - "reference": "b233b84bc4465aff7b57cf1c4bc75c86d00d6dad", + "url": "https://api.github.com/repos/sebastianbergmann/type/zipball/fb44e1cc6e557418387ad815780360057e40753e", + "reference": "fb44e1cc6e557418387ad815780360057e40753e", "shasum": "" }, "require": { @@ -10528,7 +10384,7 @@ "type": "library", "extra": { "branch-alias": { - "dev-master": "3.0-dev" + "dev-master": "3.1-dev" } }, "autoload": { @@ -10551,7 +10407,7 @@ "homepage": "https://github.com/sebastianbergmann/type", "support": { "issues": "https://github.com/sebastianbergmann/type/issues", - "source": "https://github.com/sebastianbergmann/type/tree/3.0.0" + "source": "https://github.com/sebastianbergmann/type/tree/3.1.0" }, "funding": [ { @@ -10559,7 +10415,7 @@ "type": "github" } ], - "time": "2022-03-15T09:54:48+00:00" + "time": "2022-08-29T06:55:37+00:00" }, { "name": "sebastian/version", @@ -10726,6 +10582,67 @@ }, "time": "2021-12-10T11:20:11+00:00" }, + { + "name": "seld/signal-handler", + "version": "2.0.1", + "source": { + "type": "git", + "url": "https://github.com/Seldaek/signal-handler.git", + "reference": "f69d119511dc0360440cdbdaa71829c149b7be75" + }, + "dist": { + "type": "zip", + "url": "https://api.github.com/repos/Seldaek/signal-handler/zipball/f69d119511dc0360440cdbdaa71829c149b7be75", + "reference": "f69d119511dc0360440cdbdaa71829c149b7be75", + "shasum": "" + }, + "require": { + "php": ">=7.2.0" + }, + "require-dev": { + "phpstan/phpstan": "^1", + "phpstan/phpstan-deprecation-rules": "^1.0", + "phpstan/phpstan-phpunit": "^1", + "phpstan/phpstan-strict-rules": "^1.3", + "phpunit/phpunit": "^7.5.20 || ^8.5.23", + "psr/log": "^1 || ^2 || ^3" + }, + "type": "library", + "extra": { + "branch-alias": { + "dev-main": "2.x-dev" + } + }, + "autoload": { + "psr-4": { + "Seld\\Signal\\": "src/" + } + }, + "notification-url": "https://packagist.org/downloads/", + "license": [ + "MIT" + ], + "authors": [ + { + "name": "Jordi Boggiano", + "email": "j.boggiano@seld.be", + "homepage": "http://seld.be" + } + ], + "description": "Simple unix signal handler that silently fails where signals are not supported for easy cross-platform development", + "keywords": [ + "posix", + "sigint", + "signal", + "sigterm", + "unix" + ], + "support": { + "issues": "https://github.com/Seldaek/signal-handler/issues", + "source": "https://github.com/Seldaek/signal-handler/tree/2.0.1" + }, + "time": "2022-07-20T18:31:45+00:00" + }, { "name": "ssddanbrown/asserthtml", "version": "v1.0.1", @@ -10784,16 +10701,16 @@ }, { "name": "symfony/dom-crawler", - "version": "v5.4.9", + "version": "v5.4.12", "source": { "type": "git", "url": "https://github.com/symfony/dom-crawler.git", - "reference": "a213cbc80382320b0efdccdcdce232f191fafe3a" + "reference": "291c1e92281a09152dda089f782e23dedd34bd4f" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/a213cbc80382320b0efdccdcdce232f191fafe3a", - "reference": "a213cbc80382320b0efdccdcdce232f191fafe3a", + "url": "https://api.github.com/repos/symfony/dom-crawler/zipball/291c1e92281a09152dda089f782e23dedd34bd4f", + "reference": "291c1e92281a09152dda089f782e23dedd34bd4f", "shasum": "" }, "require": { @@ -10839,7 +10756,7 @@ "description": "Eases DOM navigation for HTML and XML documents", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/dom-crawler/tree/v5.4.9" + "source": "https://github.com/symfony/dom-crawler/tree/v5.4.12" }, "funding": [ { @@ -10855,20 +10772,20 @@ "type": "tidelift" } ], - "time": "2022-05-04T14:46:32+00:00" + "time": "2022-08-03T13:09:21+00:00" }, { "name": "symfony/filesystem", - "version": "v5.4.9", + "version": "v5.4.12", "source": { "type": "git", "url": "https://github.com/symfony/filesystem.git", - "reference": "36a017fa4cce1eff1b8e8129ff53513abcef05ba" + "reference": "2d67c1f9a1937406a9be3171b4b22250c0a11447" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/symfony/filesystem/zipball/36a017fa4cce1eff1b8e8129ff53513abcef05ba", - "reference": "36a017fa4cce1eff1b8e8129ff53513abcef05ba", + "url": "https://api.github.com/repos/symfony/filesystem/zipball/2d67c1f9a1937406a9be3171b4b22250c0a11447", + "reference": "2d67c1f9a1937406a9be3171b4b22250c0a11447", "shasum": "" }, "require": { @@ -10903,7 +10820,7 @@ "description": "Provides basic utilities for the filesystem", "homepage": "https://symfony.com", "support": { - "source": "https://github.com/symfony/filesystem/tree/v5.4.9" + "source": "https://github.com/symfony/filesystem/tree/v5.4.12" }, "funding": [ { @@ -10919,7 +10836,7 @@ "type": "tidelift" } ], - "time": "2022-05-20T13:55:35+00:00" + "time": "2022-08-02T13:48:16+00:00" }, { "name": "theseer/tokenizer", diff --git a/tests/Auth/OidcTest.php b/tests/Auth/OidcTest.php index 4215f6a54..8c6e0635f 100644 --- a/tests/Auth/OidcTest.php +++ b/tests/Auth/OidcTest.php @@ -374,7 +374,7 @@ class OidcTest extends TestCase $resp = $this->runLogin([ 'email' => 'benny@example.com', 'sub' => 'benny1010101', - 'groups' => ['Wizards', 'Zookeepers'] + 'groups' => ['Wizards', 'Zookeepers'], ]); $resp->assertRedirect('/'); @@ -398,13 +398,13 @@ class OidcTest extends TestCase $resp = $this->runLogin([ 'email' => 'benny@example.com', 'sub' => 'benny1010101', - 'my' => [ + 'my' => [ 'custom' => [ 'groups' => [ - 'attr' => ['Wizards'] - ] - ] - ] + 'attr' => ['Wizards'], + ], + ], + ], ]); $resp->assertRedirect('/'); diff --git a/tests/Commands/RegenerateReferencesCommandTest.php b/tests/Commands/RegenerateReferencesCommandTest.php index 8906474af..27dde749b 100644 --- a/tests/Commands/RegenerateReferencesCommandTest.php +++ b/tests/Commands/RegenerateReferencesCommandTest.php @@ -23,10 +23,10 @@ class RegenerateReferencesCommandTest extends TestCase ->assertExitCode(0); $this->assertDatabaseHas('references', [ - 'from_id' => $page->id, + 'from_id' => $page->id, 'from_type' => $page->getMorphClass(), - 'to_id' => $book->id, - 'to_type' => $book->getMorphClass(), + 'to_id' => $book->id, + 'to_type' => $book->getMorphClass(), ]); } } diff --git a/tests/References/CrossLinkParserTest.php b/tests/References/CrossLinkParserTest.php index 42d78cb0a..856b699c3 100644 --- a/tests/References/CrossLinkParserTest.php +++ b/tests/References/CrossLinkParserTest.php @@ -2,14 +2,12 @@ namespace Tests\References; -use BookStack\Entities\Models\Book; use BookStack\Entities\Models\Page; use BookStack\References\CrossLinkParser; use Tests\TestCase; class CrossLinkParserTest extends TestCase { - public function test_instance_with_entity_resolvers_matches_entity_links() { $entities = $this->getEachEntityType(); @@ -17,7 +15,7 @@ class CrossLinkParserTest extends TestCase $html = ' Page Permalink -Page Link +Page Link Chapter Link Book Link Shelf Link diff --git a/tests/References/ReferencesTest.php b/tests/References/ReferencesTest.php index 82cd16680..a067aadfa 100644 --- a/tests/References/ReferencesTest.php +++ b/tests/References/ReferencesTest.php @@ -12,7 +12,6 @@ use Tests\TestCase; class ReferencesTest extends TestCase { - public function test_references_created_on_page_update() { /** @var Page $pageA */ @@ -24,14 +23,14 @@ class ReferencesTest extends TestCase $this->asEditor()->put($pageA->getUrl(), [ 'name' => 'Reference test', - 'html' => 'Testing' + 'html' => 'Testing', ]); $this->assertDatabaseHas('references', [ - 'from_id' => $pageA->id, + 'from_id' => $pageA->id, 'from_type' => $pageA->getMorphClass(), - 'to_id' => $pageB->id, - 'to_type' => $pageB->getMorphClass(), + 'to_id' => $pageB->id, + 'to_type' => $pageB->getMorphClass(), ]); } @@ -141,7 +140,7 @@ class ReferencesTest extends TestCase $this->assertStringContainsString('href="http://localhost/books/my-updated-book-slugaroo"', $page->html); $this->assertDatabaseHas('page_revisions', [ 'page_id' => $page->id, - 'summary' => 'System auto-update of internal links' + 'summary' => 'System auto-update of internal links', ]); } } @@ -179,10 +178,9 @@ class ReferencesTest extends TestCase { (new Reference())->forceFill([ 'from_type' => $from->getMorphClass(), - 'from_id' => $from->id, - 'to_type' => $to->getMorphClass(), - 'to_id' => $to->id, + 'from_id' => $from->id, + 'to_type' => $to->getMorphClass(), + 'to_id' => $to->id, ])->save(); } - -} \ No newline at end of file +} From 9153be963dc95704e6e66c3de118d36a32f0d025 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Tue, 30 Aug 2022 22:00:32 +0100 Subject: [PATCH 19/45] Added book child reference handling on book url change Closes #3683 --- app/References/ReferenceUpdater.php | 30 ++++++++++++++++- tests/References/ReferencesTest.php | 51 +++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+), 1 deletion(-) diff --git a/app/References/ReferenceUpdater.php b/app/References/ReferenceUpdater.php index d90591ab6..2f7b70a87 100644 --- a/app/References/ReferenceUpdater.php +++ b/app/References/ReferenceUpdater.php @@ -2,6 +2,7 @@ namespace BookStack\References; +use BookStack\Entities\Models\Book; use BookStack\Entities\Models\Entity; use BookStack\Entities\Models\Page; use BookStack\Entities\Repos\RevisionRepo; @@ -21,7 +22,7 @@ class ReferenceUpdater public function updateEntityPageReferences(Entity $entity, string $oldLink) { - $references = $this->referenceFetcher->getPageReferencesToEntity($entity); + $references = $this->getReferencesToUpdate($entity); $newLink = $entity->getUrl(); /** @var Reference $reference */ @@ -32,6 +33,33 @@ class ReferenceUpdater } } + /** + * @return Reference[] + */ + protected function getReferencesToUpdate(Entity $entity): array + { + /** @var Reference[] $references */ + $references = $this->referenceFetcher->getPageReferencesToEntity($entity)->values()->all(); + + if ($entity instanceof Book) { + $pages = $entity->pages()->get(['id']); + $chapters = $entity->chapters()->get(['id']); + $children = $pages->concat($chapters); + foreach ($children as $bookChild) { + $childRefs = $this->referenceFetcher->getPageReferencesToEntity($bookChild)->values()->all(); + array_push($references, ...$childRefs); + } + } + + $deduped = []; + foreach ($references as $reference) { + $key = $reference->from_id . ':' . $reference->from_type; + $deduped[$key] = $reference; + } + + return array_values($deduped); + } + protected function updateReferencesWithinPage(Page $page, string $oldLink, string $newLink) { $page = (clone $page)->refresh(); diff --git a/tests/References/ReferencesTest.php b/tests/References/ReferencesTest.php index a067aadfa..3fd68d647 100644 --- a/tests/References/ReferencesTest.php +++ b/tests/References/ReferencesTest.php @@ -3,6 +3,7 @@ namespace Tests\References; use BookStack\Entities\Models\Book; +use BookStack\Entities\Models\Chapter; use BookStack\Entities\Models\Page; use BookStack\Entities\Repos\PageRepo; use BookStack\Entities\Tools\TrashCan; @@ -145,6 +146,56 @@ class ReferencesTest extends TestCase } } + public function test_pages_linking_to_other_page_updated_on_parent_book_url_change() + { + /** @var Page $bookPage */ + /** @var Page $otherPage */ + /** @var Book $book */ + $bookPage = Page::query()->first(); + $otherPage = Page::query()->where('id', '!=', $bookPage->id)->first(); + $book = $bookPage->book; + + $otherPage->html = 'Link'; + $otherPage->save(); + $this->createReference($otherPage, $bookPage); + + $this->asEditor()->put($book->getUrl(), [ + 'name' => 'my updated book slugaroo', + ]); + + $otherPage->refresh(); + $this->assertStringContainsString('href="http://localhost/books/my-updated-book-slugaroo/page/' . $bookPage->slug . '"', $otherPage->html); + $this->assertDatabaseHas('page_revisions', [ + 'page_id' => $otherPage->id, + 'summary' => 'System auto-update of internal links', + ]); + } + + public function test_pages_linking_to_chapter_updated_on_parent_book_url_change() + { + /** @var Chapter $bookChapter */ + /** @var Page $otherPage */ + /** @var Book $book */ + $bookChapter = Chapter::query()->first(); + $otherPage = Page::query()->first(); + $book = $bookChapter->book; + + $otherPage->html = 'Link'; + $otherPage->save(); + $this->createReference($otherPage, $bookChapter); + + $this->asEditor()->put($book->getUrl(), [ + 'name' => 'my updated book slugaroo', + ]); + + $otherPage->refresh(); + $this->assertStringContainsString('href="http://localhost/books/my-updated-book-slugaroo/chapter/' . $bookChapter->slug . '"', $otherPage->html); + $this->assertDatabaseHas('page_revisions', [ + 'page_id' => $otherPage->id, + 'summary' => 'System auto-update of internal links', + ]); + } + public function test_markdown_links_leading_to_entity_updated_on_url_change() { /** @var Page $page */ From f092c97748ffb9b67f8475b39f8f4f4c29ada0fc Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Tue, 30 Aug 2022 22:12:52 +0100 Subject: [PATCH 20/45] Fixed lack of url reference updating on book child move --- app/Entities/Models/BookChild.php | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/app/Entities/Models/BookChild.php b/app/Entities/Models/BookChild.php index 3b1ac1bab..ed08f16e6 100644 --- a/app/Entities/Models/BookChild.php +++ b/app/Entities/Models/BookChild.php @@ -62,13 +62,12 @@ abstract class BookChild extends Entity $this->book_id = $newBookId; $this->refreshSlug(); $this->save(); + $this->refresh(); if ($oldUrl !== $this->getUrl()) { app()->make(ReferenceUpdater::class)->updateEntityPageReferences($this, $oldUrl); } - $this->refresh(); - // Update all child pages if a chapter if ($this instanceof Chapter) { foreach ($this->pages()->withTrashed()->get() as $page) { From 34c63e1c303c60f6ca9e149f61b5665d0108f248 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Thu, 1 Sep 2022 12:53:34 +0100 Subject: [PATCH 21/45] Added test & update to prevent page creation w/ empty slug Caused by changes to page repo in reference work, This adds back in the slug generate although at a more central place. Adds a test case to cover the problematic scenario. --- app/Entities/Repos/BaseRepo.php | 2 +- tests/Entity/PageDraftTest.php | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/app/Entities/Repos/BaseRepo.php b/app/Entities/Repos/BaseRepo.php index cfde7fe1c..747d1b176 100644 --- a/app/Entities/Repos/BaseRepo.php +++ b/app/Entities/Repos/BaseRepo.php @@ -56,7 +56,7 @@ class BaseRepo $entity->fill($input); $entity->updated_by = user()->id; - if ($entity->isDirty('name')) { + if ($entity->isDirty('name') || empty($entity->slug)) { $entity->refreshSlug(); } diff --git a/tests/Entity/PageDraftTest.php b/tests/Entity/PageDraftTest.php index 0b44e5f0b..6fd9a7f70 100644 --- a/tests/Entity/PageDraftTest.php +++ b/tests/Entity/PageDraftTest.php @@ -204,4 +204,32 @@ class PageDraftTest extends TestCase $draft->refresh(); $this->assertStringContainsString('href="https://example.com"', $draft->html); } + + public function test_slug_generated_on_draft_publish_to_page_when_no_name_change() + { + /** @var Book $book */ + $book = Book::query()->first(); + $this->asEditor()->get($book->getUrl('/create-page')); + /** @var Page $draft */ + $draft = Page::query()->where('draft', '=', true)->where('book_id', '=', $book->id)->firstOrFail(); + + $this->put('/ajax/page/' . $draft->id . '/save-draft', [ + 'name' => 'My page', + 'markdown' => "Update test", + ])->assertOk(); + + $draft->refresh(); + $this->assertEmpty($draft->slug); + + $this->post($draft->getUrl(), [ + 'name' => 'My page', + 'markdown' => "# My markdown page" + ]); + + $this->assertDatabaseHas('pages', [ + 'id' => $draft->id, + 'draft' => false, + 'slug' => 'my-page', + ]); + } } From 1afc915aed0eebfbd7976170d25b6028e6b30cf2 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Thu, 1 Sep 2022 13:11:59 +0100 Subject: [PATCH 22/45] Fixed missing nested list indent next to floated content Fixes #3672 --- resources/sass/_text.scss | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/resources/sass/_text.scss b/resources/sass/_text.scss index 51f315614..4eab8959a 100644 --- a/resources/sass/_text.scss +++ b/resources/sass/_text.scss @@ -274,6 +274,9 @@ span.highlight { * Lists */ ul, ol { + padding-left: $-m * 2.0; + padding-right: $-m * 2.0; + display: flow-root; p { margin: 0; } @@ -292,11 +295,6 @@ ol { list-style: decimal; } -ol, ul { - padding-left: $-m * 2.0; - padding-right: $-m * 2.0; -} - li > ol, li > ul { margin-top: 0; margin-bottom: 0; From 9da3130a12301c9b2cc52a3bb6ada2d65a66c106 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Thu, 1 Sep 2022 14:55:35 +0100 Subject: [PATCH 23/45] Aligned bookshelf terminology to consistently be 'Shelf' For #3553 EN only, other languages should be handled via CrowdIn --- resources/lang/en/activities.php | 14 +++++------ resources/lang/en/entities.php | 25 +++++++++---------- resources/lang/en/errors.php | 2 +- resources/views/books/show.blade.php | 2 +- .../views/settings/roles/parts/form.blade.php | 2 +- 5 files changed, 22 insertions(+), 23 deletions(-) diff --git a/resources/lang/en/activities.php b/resources/lang/en/activities.php index edddf9aeb..f348bff1f 100644 --- a/resources/lang/en/activities.php +++ b/resources/lang/en/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Book successfully re-sorted', // Bookshelves - 'bookshelf_create' => 'created bookshelf', - 'bookshelf_create_notification' => 'Bookshelf successfully created', - 'bookshelf_create_from_book' => 'converted book to bookshelf', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf', - 'bookshelf_update' => 'updated bookshelf', - 'bookshelf_update_notification' => 'Bookshelf successfully updated', - 'bookshelf_delete' => 'deleted bookshelf', - 'bookshelf_delete_notification' => 'Bookshelf successfully deleted', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" has been added to your favourites', diff --git a/resources/lang/en/entities.php b/resources/lang/en/entities.php index 07d4b625d..1720801d2 100644 --- a/resources/lang/en/entities.php +++ b/resources/lang/en/entities.php @@ -78,7 +78,6 @@ return [ 'shelf' => 'Shelf', 'shelves' => 'Shelves', 'x_shelves' => ':count Shelf|:count Shelves', - 'shelves_long' => 'Bookshelves', 'shelves_empty' => 'No shelves have been created', 'shelves_create' => 'Create New Shelf', 'shelves_popular' => 'Popular Shelves', @@ -92,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'This shelf has no books assigned to it', 'shelves_edit_and_assign' => 'Edit shelf to assign books', - 'shelves_edit_named' => 'Edit Bookshelf :name', - 'shelves_edit' => 'Edit Bookshelf', - 'shelves_delete' => 'Delete Bookshelf', - 'shelves_delete_named' => 'Delete Bookshelf :name', - 'shelves_delete_explain' => "This will delete the bookshelf with the name ':name'. Contained books will not be deleted.", - 'shelves_delete_confirmation' => 'Are you sure you want to delete this bookshelf?', - 'shelves_permissions' => 'Bookshelf Permissions', - 'shelves_permissions_updated' => 'Bookshelf Permissions Updated', - 'shelves_permissions_active' => 'Bookshelf Permissions Active', - 'shelves_permissions_cascade_warning' => 'Permissions on bookshelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Copy Permissions to Books', 'shelves_copy_permissions' => 'Copy Permissions', - '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_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Book', diff --git a/resources/lang/en/errors.php b/resources/lang/en/errors.php index f023b6bdf..52f96cbe7 100644 --- a/resources/lang/en/errors.php +++ b/resources/lang/en/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Entity not found', - 'bookshelf_not_found' => 'Bookshelf not found', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Book not found', 'page_not_found' => 'Page not found', 'chapter_not_found' => 'Chapter not found', diff --git a/resources/views/books/show.blade.php b/resources/views/books/show.blade.php index 03801f9a5..76a4a6005 100644 --- a/resources/views/books/show.blade.php +++ b/resources/views/books/show.blade.php @@ -162,7 +162,7 @@ @if(count($bookParentShelves) > 0)
-
{{ trans('entities.shelves_long') }}
+
{{ trans('entities.shelves') }}
@include('entities.list', ['entities' => $bookParentShelves, 'style' => 'compact'])
@endif diff --git a/resources/views/settings/roles/parts/form.blade.php b/resources/views/settings/roles/parts/form.blade.php index aeaa39a6d..73d6a03d0 100644 --- a/resources/views/settings/roles/parts/form.blade.php +++ b/resources/views/settings/roles/parts/form.blade.php @@ -68,7 +68,7 @@ -
{{ trans('entities.shelves_long') }}
+
{{ trans('entities.shelves') }}
{{ trans('common.toggle_all') }} From 27ac1225024fabb8497bb25a57d837ff61806c5d Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Thu, 1 Sep 2022 16:17:14 +0100 Subject: [PATCH 24/45] Started work on local_secure_restricted image option --- .../Controllers/Images/ImageController.php | 2 +- app/Uploads/AttachmentService.php | 2 +- app/Uploads/ImageService.php | 96 +++++++++++++++---- 3 files changed, 79 insertions(+), 21 deletions(-) diff --git a/app/Http/Controllers/Images/ImageController.php b/app/Http/Controllers/Images/ImageController.php index 21ed58553..b5bc840a1 100644 --- a/app/Http/Controllers/Images/ImageController.php +++ b/app/Http/Controllers/Images/ImageController.php @@ -33,7 +33,7 @@ class ImageController extends Controller */ public function showImage(string $path) { - if (!$this->imageService->pathExistsInLocalSecure($path)) { + if (!$this->imageService->pathAccessibleInLocalSecure($path)) { throw (new NotFoundException(trans('errors.image_not_found'))) ->setSubtitle(trans('errors.image_not_found_subtitle')) ->setDetails(trans('errors.image_not_found_details')); diff --git a/app/Uploads/AttachmentService.php b/app/Uploads/AttachmentService.php index 6a92cb5a5..e46c2be45 100644 --- a/app/Uploads/AttachmentService.php +++ b/app/Uploads/AttachmentService.php @@ -41,7 +41,7 @@ class AttachmentService // Change to our secure-attachment disk if any of the local options // are used to prevent escaping that location. - if ($storageType === 'local' || $storageType === 'local_secure') { + if ($storageType === 'local' || $storageType === 'local_secure' || $storageType === 'local_secure_with_permissions') { $storageType = 'local_secure_attachments'; } diff --git a/app/Uploads/ImageService.php b/app/Uploads/ImageService.php index ca0db997b..a82fecdd7 100644 --- a/app/Uploads/ImageService.php +++ b/app/Uploads/ImageService.php @@ -2,6 +2,9 @@ namespace BookStack\Uploads; +use BookStack\Entities\Models\Book; +use BookStack\Entities\Models\Bookshelf; +use BookStack\Entities\Models\Page; use BookStack\Exceptions\ImageUploadException; use ErrorException; use Exception; @@ -24,20 +27,15 @@ use Symfony\Component\HttpFoundation\StreamedResponse; class ImageService { - protected $imageTool; - protected $cache; + protected ImageManager $imageTool; + protected Cache $cache; protected $storageUrl; - protected $image; - protected $fileSystem; + protected FilesystemManager $fileSystem; protected static $supportedExtensions = ['jpg', 'jpeg', 'png', 'gif', 'webp']; - /** - * ImageService constructor. - */ - public function __construct(Image $image, ImageManager $imageTool, FilesystemManager $fileSystem, Cache $cache) + public function __construct(ImageManager $imageTool, FilesystemManager $fileSystem, Cache $cache) { - $this->image = $image; $this->imageTool = $imageTool; $this->fileSystem = $fileSystem; $this->cache = $cache; @@ -55,9 +53,18 @@ class ImageService * Check if local secure image storage (Fetched behind authentication) * is currently active in the instance. */ - protected function usingSecureImages(): bool + protected function usingSecureImages(string $imageType = 'gallery'): bool { - return $this->getStorageDiskName('gallery') === 'local_secure_images'; + return $this->getStorageDiskName($imageType) === 'local_secure_images'; + } + + /** + * Check if "local secure restricted" (Fetched behind auth, with permissions enforced) + * is currently active in the instance. + */ + protected function usingSecureRestrictedImages() + { + return config('filesystems.images') === 'local_secure_restricted'; } /** @@ -68,7 +75,7 @@ class ImageService { $path = Util::normalizePath(str_replace('uploads/images/', '', $path)); - if ($this->getStorageDiskName($imageType) === 'local_secure_images') { + if ($this->usingSecureImages($imageType)) { return $path; } @@ -87,7 +94,9 @@ class ImageService $storageType = 'local'; } - if ($storageType === 'local_secure') { + // Rename local_secure options to get our image specific storage driver which + // is scoped to the relevant image directories. + if ($storageType === 'local_secure' || $storageType === 'local_secure_restricted') { $storageType = 'local_secure_images'; } @@ -179,8 +188,8 @@ class ImageService $imageDetails['updated_by'] = $userId; } - $image = $this->image->newInstance(); - $image->forceFill($imageDetails)->save(); + $image = (new Image())->forceFill($imageDetails); + $image->save(); return $image; } @@ -451,7 +460,7 @@ class ImageService $types = ['gallery', 'drawio']; $deletedPaths = []; - $this->image->newQuery()->whereIn('type', $types) + Image::query()->whereIn('type', $types) ->chunk(1000, function ($images) use ($checkRevisions, &$deletedPaths, $dryRun) { foreach ($images as $image) { $searchQuery = '%' . basename($image->path) . '%'; @@ -511,14 +520,19 @@ class ImageService } /** - * Check if the given path exists in the local secure image system. - * Returns false if local_secure is not in use. + * Check if the given path exists and is accessible in the local secure image system. + * Returns false if local_secure is not in use, if the file does not exist, if the + * file is likely not a valid image, or if permission does not allow access. */ - public function pathExistsInLocalSecure(string $imagePath): bool + public function pathAccessibleInLocalSecure(string $imagePath): bool { /** @var FilesystemAdapter $disk */ $disk = $this->getStorageDisk('gallery'); + if ($this->usingSecureRestrictedImages() && !$this->checkUserHasAccessToRelationOfImageAtPath($imagePath)) { + return false; + } + // Check local_secure is active return $this->usingSecureImages() && $disk instanceof FilesystemAdapter @@ -528,6 +542,50 @@ class ImageService && strpos($disk->getMimetype($imagePath), 'image/') === 0; } + /** + * Check that the current user has access to the relation + * of the image at the given path. + */ + protected function checkUserHasAccessToRelationOfImageAtPath(string $path): bool + { + // Strip thumbnail element from path if existing + $originalPathSplit = array_filter(explode('/', $path), function(string $part) { + $resizedDir = (strpos($part, 'thumbs-') === 0 || strpos($part, 'scaled-') === 0); + $missingExtension = strpos($part, '.') === false; + return !($resizedDir && $missingExtension); + }); + + // Build a database-format image path and search for the image entry + $fullPath = '/uploads/images/' . ltrim(implode('/', $originalPathSplit), '/'); + $image = Image::query()->where('path', '=', $fullPath)->first(); + + if (is_null($image)) { + return false; + } + + $imageType = $image->type; + + // Allow user or system (logo) images + // (No specific relation control but may still have access controlled by auth) + if ($imageType === 'user' || $imageType === 'system') { + return true; + } + + if ($imageType === 'gallery' || $imageType === 'drawio') { + return Page::visible()->where('id', '=', $image->uploaded_to)->exists(); + } + + if ($imageType === 'cover_book') { + return Book::visible()->where('id', '=', $image->uploaded_to)->exists(); + } + + if ($imageType === 'cover_bookshelf') { + return Bookshelf::visible()->where('id', '=', $image->uploaded_to)->exists(); + } + + return false; + } + /** * For the given path, if existing, provide a response that will stream the image contents. */ From f28ed0ef0b219eece535a4d2a1261832bfc10f14 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Fri, 2 Sep 2022 12:54:54 +0100 Subject: [PATCH 25/45] Fixed shelf covers being stored as 'cover_book' Are now stored as 'cover_bookshelf' as expected. Added a migrate to alter existing shelf cover image types. --- app/Entities/Models/Bookshelf.php | 2 +- app/Entities/Repos/BaseRepo.php | 3 +- ..._02_082910_fix_shelf_cover_image_types.php | 42 +++++++++++++++++++ tests/Entity/BookShelfTest.php | 1 + 4 files changed, 46 insertions(+), 2 deletions(-) create mode 100644 database/migrations/2022_09_02_082910_fix_shelf_cover_image_types.php diff --git a/app/Entities/Models/Bookshelf.php b/app/Entities/Models/Bookshelf.php index b2dab252a..cdc6648f9 100644 --- a/app/Entities/Models/Bookshelf.php +++ b/app/Entities/Models/Bookshelf.php @@ -86,7 +86,7 @@ class Bookshelf extends Entity implements HasCoverImage */ public function coverImageTypeKey(): string { - return 'cover_shelf'; + return 'cover_bookshelf'; } /** diff --git a/app/Entities/Repos/BaseRepo.php b/app/Entities/Repos/BaseRepo.php index 747d1b176..da939e102 100644 --- a/app/Entities/Repos/BaseRepo.php +++ b/app/Entities/Repos/BaseRepo.php @@ -86,8 +86,9 @@ class BaseRepo public function updateCoverImage($entity, ?UploadedFile $coverImage, bool $removeImage = false) { if ($coverImage) { + $imageType = $entity->coverImageTypeKey(); $this->imageRepo->destroyImage($entity->cover); - $image = $this->imageRepo->saveNew($coverImage, 'cover_book', $entity->id, 512, 512, true); + $image = $this->imageRepo->saveNew($coverImage, $imageType, $entity->id, 512, 512, true); $entity->cover()->associate($image); $entity->save(); } diff --git a/database/migrations/2022_09_02_082910_fix_shelf_cover_image_types.php b/database/migrations/2022_09_02_082910_fix_shelf_cover_image_types.php new file mode 100644 index 000000000..837bdfe24 --- /dev/null +++ b/database/migrations/2022_09_02_082910_fix_shelf_cover_image_types.php @@ -0,0 +1,42 @@ +whereNotNull('image_id') + ->pluck('image_id') + ->values()->all(); + + DB::table('images') + ->where('type', '=', 'cover_book') + ->whereIn('id', $shelfImageIds) + ->update(['type' => 'cover_bookshelf']); + } + + /** + * Reverse the migrations. + * + * @return void + */ + public function down() + { + DB::table('images') + ->where('type', '=', 'cover_bookshelf') + ->update(['type' => 'cover_book']); + } +} diff --git a/tests/Entity/BookShelfTest.php b/tests/Entity/BookShelfTest.php index 5a7107ff0..44d30a548 100644 --- a/tests/Entity/BookShelfTest.php +++ b/tests/Entity/BookShelfTest.php @@ -125,6 +125,7 @@ class BookShelfTest extends TestCase 'image_id' => $lastImage->id, ]); $this->assertEquals($lastImage->id, $shelf->cover->id); + $this->assertEquals('cover_bookshelf', $lastImage->type); } public function test_shelf_view() From f88330202bd5ae9bca94e589ee14d13839745e71 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Fri, 2 Sep 2022 14:03:23 +0100 Subject: [PATCH 26/45] Added test to cover secure restricted functionality --- tests/Uploads/ImageTest.php | 50 +++++++++++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/tests/Uploads/ImageTest.php b/tests/Uploads/ImageTest.php index c006f9612..3beba2007 100644 --- a/tests/Uploads/ImageTest.php +++ b/tests/Uploads/ImageTest.php @@ -327,6 +327,56 @@ class ImageTest extends TestCase } } + public function test_secure_restricted_images_inaccessible_without_relation_permission() + { + config()->set('filesystems.images', 'local_secure_restricted'); + $this->asEditor(); + $galleryFile = $this->getTestImage('my-secure-restricted-test-upload.png'); + /** @var Page $page */ + $page = Page::query()->first(); + + $upload = $this->call('POST', '/images/gallery', ['uploaded_to' => $page->id], [], ['file' => $galleryFile], []); + $upload->assertStatus(200); + $expectedUrl = url('uploads/images/gallery/' . date('Y-m') . '/my-secure-restricted-test-upload.png'); + $expectedPath = storage_path('uploads/images/gallery/' . date('Y-m') . '/my-secure-restricted-test-upload.png'); + + $this->get($expectedUrl)->assertOk(); + + $this->setEntityRestrictions($page, [], []); + + $resp = $this->get($expectedUrl); + $resp->assertNotFound(); + + if (file_exists($expectedPath)) { + unlink($expectedPath); + } + } + + public function test_thumbnail_path_handled_by_secure_restricted_images() + { + config()->set('filesystems.images', 'local_secure_restricted'); + $this->asEditor(); + $galleryFile = $this->getTestImage('my-secure-restricted-thumb-test-test.png'); + /** @var Page $page */ + $page = Page::query()->first(); + + $upload = $this->call('POST', '/images/gallery', ['uploaded_to' => $page->id], [], ['file' => $galleryFile], []); + $upload->assertStatus(200); + $expectedUrl = url('uploads/images/gallery/' . date('Y-m') . '/thumbs-150-150/my-secure-restricted-thumb-test-test.png'); + $expectedPath = storage_path('uploads/images/gallery/' . date('Y-m') . '/my-secure-restricted-thumb-test-test.png'); + + $this->get($expectedUrl)->assertOk(); + + $this->setEntityRestrictions($page, [], []); + + $resp = $this->get($expectedUrl); + $resp->assertNotFound(); + + if (file_exists($expectedPath)) { + unlink($expectedPath); + } + } + public function test_image_delete() { $page = Page::query()->first(); From 092b6d6378175720debbcce14d026e8705b5d3cc Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Fri, 2 Sep 2022 14:21:43 +0100 Subject: [PATCH 27/45] Added test and handling for local_secure_restricted in exports --- app/Entities/Tools/ExportFormatter.php | 3 +-- app/Uploads/ImageService.php | 12 ++++++++++ tests/Uploads/ImageTest.php | 33 ++++++++++++++++++++++++++ 3 files changed, 46 insertions(+), 2 deletions(-) diff --git a/app/Entities/Tools/ExportFormatter.php b/app/Entities/Tools/ExportFormatter.php index 97902db82..9e4d63cf7 100644 --- a/app/Entities/Tools/ExportFormatter.php +++ b/app/Entities/Tools/ExportFormatter.php @@ -235,7 +235,7 @@ class ExportFormatter $linksOutput = []; preg_match_all("/\/i", $htmlContent, $linksOutput); - // Replace image src with base64 encoded image strings + // Update relative links to be absolute, with instance url if (isset($linksOutput[0]) && count($linksOutput[0]) > 0) { foreach ($linksOutput[0] as $index => $linkMatch) { $oldLinkString = $linkMatch; @@ -248,7 +248,6 @@ class ExportFormatter } } - // Replace any relative links with system domain return $htmlContent; } diff --git a/app/Uploads/ImageService.php b/app/Uploads/ImageService.php index a82fecdd7..ec2f6da54 100644 --- a/app/Uploads/ImageService.php +++ b/app/Uploads/ImageService.php @@ -501,6 +501,14 @@ class ImageService } $storagePath = $this->adjustPathForStorageDisk($storagePath); + + // Apply access control when local_secure_restricted images are active + if ($this->usingSecureRestrictedImages()) { + if (!$this->checkUserHasAccessToRelationOfImageAtPath($storagePath)) { + return null; + } + } + $storage = $this->getStorageDisk(); $imageData = null; if ($storage->exists($storagePath)) { @@ -548,6 +556,10 @@ class ImageService */ protected function checkUserHasAccessToRelationOfImageAtPath(string $path): bool { + if (strpos($path, '/uploads/images/') === 0) { + $path = substr($path, 15); + } + // Strip thumbnail element from path if existing $originalPathSplit = array_filter(explode('/', $path), function(string $part) { $resizedDir = (strpos($part, 'thumbs-') === 0 || strpos($part, 'scaled-') === 0); diff --git a/tests/Uploads/ImageTest.php b/tests/Uploads/ImageTest.php index 3beba2007..2a3023a9e 100644 --- a/tests/Uploads/ImageTest.php +++ b/tests/Uploads/ImageTest.php @@ -377,6 +377,39 @@ class ImageTest extends TestCase } } + public function test_secure_restricted_image_access_controlled_in_exports() + { + config()->set('filesystems.images', 'local_secure_restricted'); + $this->asEditor(); + $galleryFile = $this->getTestImage('my-secure-restricted-export-test.png'); + + /** @var Page $pageA */ + /** @var Page $pageB */ + $pageA = Page::query()->first(); + $pageB = Page::query()->where('id', '!=', $pageA->id)->first(); + $expectedPath = storage_path('uploads/images/gallery/' . date('Y-m') . '/my-secure-restricted-export-test.png'); + + $upload = $this->asEditor()->call('POST', '/images/gallery', ['uploaded_to' => $pageA->id], [], ['file' => $galleryFile], []); + $upload->assertOk(); + + $imageUrl = json_decode($upload->getContent(), true)['url']; + $pageB->html .= ""; + $pageB->save(); + + $encodedImageContent = base64_encode(file_get_contents($expectedPath)); + $export = $this->get($pageB->getUrl('/export/html')); + $this->assertStringContainsString($encodedImageContent, $export->getContent()); + + $this->setEntityRestrictions($pageA, [], []); + + $export = $this->get($pageB->getUrl('/export/html')); + $this->assertStringNotContainsString($encodedImageContent, $export->getContent()); + + if (file_exists($expectedPath)) { + unlink($expectedPath); + } + } + public function test_image_delete() { $page = Page::query()->first(); From c76b5e2ec45cb6847d8f950ae80001b263285bf6 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Fri, 2 Sep 2022 14:40:17 +0100 Subject: [PATCH 28/45] Fixed local_secure_restricted preventing attachment uploads Due to option name change and therefore lack of handling. Added test case to cover. --- app/Uploads/AttachmentService.php | 2 +- tests/Uploads/AttachmentTest.php | 15 +++++++++++++++ 2 files changed, 16 insertions(+), 1 deletion(-) diff --git a/app/Uploads/AttachmentService.php b/app/Uploads/AttachmentService.php index e46c2be45..88bb41efb 100644 --- a/app/Uploads/AttachmentService.php +++ b/app/Uploads/AttachmentService.php @@ -41,7 +41,7 @@ class AttachmentService // Change to our secure-attachment disk if any of the local options // are used to prevent escaping that location. - if ($storageType === 'local' || $storageType === 'local_secure' || $storageType === 'local_secure_with_permissions') { + if ($storageType === 'local' || $storageType === 'local_secure' || $storageType === 'local_secure_restricted') { $storageType = 'local_secure_attachments'; } diff --git a/tests/Uploads/AttachmentTest.php b/tests/Uploads/AttachmentTest.php index 27a23bcae..e71adf70b 100644 --- a/tests/Uploads/AttachmentTest.php +++ b/tests/Uploads/AttachmentTest.php @@ -341,4 +341,19 @@ class AttachmentTest extends TestCase $this->deleteUploads(); } + + public function test_file_upload_works_when_local_secure_restricted_is_in_use() + { + config()->set('filesystems.attachments', 'local_secure_restricted'); + + $page = Page::query()->first(); + $fileName = 'upload_test_file.txt'; + + $upload = $this->asAdmin()->uploadFile($fileName, $page->id); + $upload->assertStatus(200); + + $attachment = Attachment::query()->orderBy('id', 'desc')->where('uploaded_to', '=', $page->id)->first(); + $this->assertFileExists(storage_path($attachment->path)); + $this->deleteUploads(); + } } From 7f8b3eff5a82eee7f14f3799165b39431db83d93 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Fri, 2 Sep 2022 14:47:44 +0100 Subject: [PATCH 29/45] Fixed failing tests due to shelf text changes, applied styleci changes --- app/Uploads/ImageService.php | 3 ++- tests/Entity/BookShelfTest.php | 8 ++++---- tests/Entity/PageDraftTest.php | 4 ++-- tests/Permissions/EntityPermissionsTest.php | 12 ++++++------ 4 files changed, 14 insertions(+), 13 deletions(-) diff --git a/app/Uploads/ImageService.php b/app/Uploads/ImageService.php index ec2f6da54..7b8af3b84 100644 --- a/app/Uploads/ImageService.php +++ b/app/Uploads/ImageService.php @@ -561,9 +561,10 @@ class ImageService } // Strip thumbnail element from path if existing - $originalPathSplit = array_filter(explode('/', $path), function(string $part) { + $originalPathSplit = array_filter(explode('/', $path), function (string $part) { $resizedDir = (strpos($part, 'thumbs-') === 0 || strpos($part, 'scaled-') === 0); $missingExtension = strpos($part, '.') === false; + return !($resizedDir && $missingExtension); }); diff --git a/tests/Entity/BookShelfTest.php b/tests/Entity/BookShelfTest.php index 44d30a548..4461c0489 100644 --- a/tests/Entity/BookShelfTest.php +++ b/tests/Entity/BookShelfTest.php @@ -203,7 +203,7 @@ class BookShelfTest extends TestCase { $shelf = Bookshelf::first(); $resp = $this->asEditor()->get($shelf->getUrl('/edit')); - $resp->assertSeeText('Edit Bookshelf'); + $resp->assertSeeText('Edit Shelf'); $booksToInclude = Book::take(2)->get(); $shelfInfo = [ @@ -270,7 +270,7 @@ class BookShelfTest extends TestCase $bookCount = $shelf->books()->count(); $deleteViewReq = $this->asEditor()->get($shelf->getUrl('/delete')); - $deleteViewReq->assertSeeText('Are you sure you want to delete this bookshelf?'); + $deleteViewReq->assertSeeText('Are you sure you want to delete this shelf?'); $deleteReq = $this->delete($shelf->getUrl()); $deleteReq->assertRedirect(url('/shelves')); @@ -283,7 +283,7 @@ class BookShelfTest extends TestCase $this->assertTrue($shelf->deletions()->count() === 1); $redirectReq = $this->get($deleteReq->baseResponse->headers->get('location')); - $this->assertNotificationContains($redirectReq, 'Bookshelf Successfully Deleted'); + $this->assertNotificationContains($redirectReq, 'Shelf Successfully Deleted'); } public function test_shelf_copy_permissions() @@ -313,7 +313,7 @@ class BookShelfTest extends TestCase { $shelf = Bookshelf::first(); $resp = $this->asAdmin()->get($shelf->getUrl('/permissions')); - $resp->assertSeeText('Permissions on bookshelves do not automatically cascade to contained books.'); + $resp->assertSeeText('Permissions on shelves do not automatically cascade to contained books.'); } public function test_bookshelves_show_in_breadcrumbs_if_in_context() diff --git a/tests/Entity/PageDraftTest.php b/tests/Entity/PageDraftTest.php index 6fd9a7f70..8ca73847a 100644 --- a/tests/Entity/PageDraftTest.php +++ b/tests/Entity/PageDraftTest.php @@ -215,7 +215,7 @@ class PageDraftTest extends TestCase $this->put('/ajax/page/' . $draft->id . '/save-draft', [ 'name' => 'My page', - 'markdown' => "Update test", + 'markdown' => 'Update test', ])->assertOk(); $draft->refresh(); @@ -223,7 +223,7 @@ class PageDraftTest extends TestCase $this->post($draft->getUrl(), [ 'name' => 'My page', - 'markdown' => "# My markdown page" + 'markdown' => '# My markdown page', ]); $this->assertDatabaseHas('pages', [ diff --git a/tests/Permissions/EntityPermissionsTest.php b/tests/Permissions/EntityPermissionsTest.php index 94863cd5b..ed037d3ac 100644 --- a/tests/Permissions/EntityPermissionsTest.php +++ b/tests/Permissions/EntityPermissionsTest.php @@ -51,7 +51,7 @@ class EntityPermissionsTest extends TestCase $this->setRestrictionsForTestRoles($shelf, []); $this->followingRedirects()->get($shelf->getUrl()) - ->assertSee('Bookshelf not found'); + ->assertSee('Shelf not found'); $this->setRestrictionsForTestRoles($shelf, ['view']); @@ -66,7 +66,7 @@ class EntityPermissionsTest extends TestCase $this->actingAs($this->user) ->get($shelf->getUrl('/edit')) - ->assertSee('Edit Book'); + ->assertSee('Edit Shelf'); $this->setRestrictionsForTestRoles($shelf, ['view', 'delete']); @@ -87,7 +87,7 @@ class EntityPermissionsTest extends TestCase $this->actingAs($this->user) ->get($shelf->getUrl('/delete')) - ->assertSee('Delete Book'); + ->assertSee('Delete Shelf'); $this->setRestrictionsForTestRoles($shelf, ['view', 'update']); @@ -98,7 +98,7 @@ class EntityPermissionsTest extends TestCase $this->get($shelf->getUrl('/delete')) ->assertOk() - ->assertSee('Delete Book'); + ->assertSee('Delete Shelf'); } public function test_book_view_restriction() @@ -416,7 +416,7 @@ class EntityPermissionsTest extends TestCase public function test_bookshelf_restriction_form() { - $this->entityRestrictionFormTest(Bookshelf::class, 'Bookshelf Permissions', 'view', '2'); + $this->entityRestrictionFormTest(Bookshelf::class, 'Shelf Permissions', 'view', '2'); } public function test_book_restriction_form() @@ -524,7 +524,7 @@ class EntityPermissionsTest extends TestCase $this->setRestrictionsForTestRoles($shelf, ['view', 'delete']); - $this->get($shelf->getUrl('/delete'))->assertOk()->assertSee('Delete Book'); + $this->get($shelf->getUrl('/delete'))->assertOk()->assertSee('Delete Shelf'); } public function test_book_create_restriction_override() From 9158a66bff8fa50640eef7ac8830d47b7fb72c02 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Fri, 2 Sep 2022 19:19:01 +0100 Subject: [PATCH 30/45] Updated & improved language locale handling Extracted much of the language and locale work to a seperate, focused class. Updated php set_locale usage to prioritise UTF8 usage. Added locale options for windows. Clarified what's a locale and a bookstack language string. For #3590 and maybe #3650 --- app/Http/Middleware/Localization.php | 121 +++---------------------- app/Util/LanguageManager.php | 130 +++++++++++++++++++++++++++ 2 files changed, 144 insertions(+), 107 deletions(-) create mode 100644 app/Util/LanguageManager.php diff --git a/app/Http/Middleware/Localization.php b/app/Http/Middleware/Localization.php index 16aea8ec9..d8bb296fc 100644 --- a/app/Http/Middleware/Localization.php +++ b/app/Http/Middleware/Localization.php @@ -2,59 +2,18 @@ namespace BookStack\Http\Middleware; +use BookStack\Util\LanguageManager; use Carbon\Carbon; use Closure; -use Illuminate\Http\Request; class Localization { - /** - * Array of right-to-left locales. - */ - protected $rtlLocales = ['ar', 'fa', 'he']; + protected LanguageManager $languageManager; - /** - * Map of BookStack locale names to best-estimate system locale names. - * Locales can often be found by running `locale -a` on a linux system. - */ - protected $localeMap = [ - 'ar' => 'ar', - 'bg' => 'bg_BG', - 'bs' => 'bs_BA', - 'ca' => 'ca', - 'da' => 'da_DK', - 'de' => 'de_DE', - 'de_informal' => 'de_DE', - 'en' => 'en_GB', - 'es' => 'es_ES', - 'es_AR' => 'es_AR', - 'et' => 'et_EE', - 'eu' => 'eu_ES', - 'fa' => 'fa_IR', - 'fr' => 'fr_FR', - 'he' => 'he_IL', - 'hr' => 'hr_HR', - 'id' => 'id_ID', - 'it' => 'it_IT', - 'ja' => 'ja', - 'ko' => 'ko_KR', - 'lt' => 'lt_LT', - 'lv' => 'lv_LV', - 'nl' => 'nl_NL', - 'nb' => 'nb_NO', - 'pl' => 'pl_PL', - 'pt' => 'pt_PT', - 'pt_BR' => 'pt_BR', - 'ru' => 'ru', - 'sk' => 'sk_SK', - 'sl' => 'sl_SI', - 'sv' => 'sv_SE', - 'uk' => 'uk_UA', - 'vi' => 'vi_VN', - 'zh_CN' => 'zh_CN', - 'zh_TW' => 'zh_TW', - 'tr' => 'tr_TR', - ]; + public function __construct(LanguageManager $languageManager) + { + $this->languageManager = $languageManager; + } /** * Handle an incoming request. @@ -66,76 +25,24 @@ class Localization */ public function handle($request, Closure $next) { + // Get and record the default language in the config $defaultLang = config('app.locale'); config()->set('app.default_locale', $defaultLang); - $locale = $this->getUserLocale($request, $defaultLang); - config()->set('app.lang', str_replace('_', '-', $this->getLocaleIso($locale))); + // Get the user's language and record that in the config for use in views + $userLang = $this->languageManager->getUserLanguage($request, $defaultLang); + config()->set('app.lang', str_replace('_', '-', $this->languageManager->getIsoName($userLang))); // Set text direction - if (in_array($locale, $this->rtlLocales)) { + if ($this->languageManager->isRTL($userLang)) { config()->set('app.rtl', true); } - app()->setLocale($locale); - Carbon::setLocale($locale); - $this->setSystemDateLocale($locale); + app()->setLocale($userLang); + Carbon::setLocale($userLang); + $this->languageManager->setPhpDateTimeLocale($userLang); return $next($request); } - /** - * Get the locale specifically for the currently logged in user if available. - */ - protected function getUserLocale(Request $request, string $default): string - { - try { - $user = user(); - } catch (\Exception $exception) { - return $default; - } - - if ($user->isDefault() && config('app.auto_detect_locale')) { - return $this->autoDetectLocale($request, $default); - } - - return setting()->getUser($user, 'language', $default); - } - - /** - * Autodetect the visitors locale by matching locales in their headers - * against the locales supported by BookStack. - */ - protected function autoDetectLocale(Request $request, string $default): string - { - $availableLocales = config('app.locales'); - foreach ($request->getLanguages() as $lang) { - if (in_array($lang, $availableLocales)) { - return $lang; - } - } - - return $default; - } - - /** - * Get the ISO version of a BookStack language name. - */ - public function getLocaleIso(string $locale): string - { - return $this->localeMap[$locale] ?? $locale; - } - - /** - * Set the system date locale for localized date formatting. - * Will try both the standard locale name and the UTF8 variant. - */ - protected function setSystemDateLocale(string $locale) - { - $systemLocale = $this->getLocaleIso($locale); - $set = setlocale(LC_TIME, $systemLocale); - if ($set === false) { - setlocale(LC_TIME, $systemLocale . '.utf8'); - } - } } diff --git a/app/Util/LanguageManager.php b/app/Util/LanguageManager.php new file mode 100644 index 000000000..ff860c83d --- /dev/null +++ b/app/Util/LanguageManager.php @@ -0,0 +1,130 @@ + + */ + protected array $localeMap = [ + 'ar' => ['iso' => 'ar', 'windows' => 'Arabic'], + 'bg' => ['iso' => 'bg_BG', 'windows' => 'Bulgarian'], + 'bs' => ['iso' => 'bs_BA', 'windows' => 'Bosnian (Latin)'], + 'ca' => ['iso' => 'ca', 'windows' => 'Catalan'], + 'da' => ['iso' => 'da_DK', 'windows' => 'Danish'], + 'de' => ['iso' => 'de_DE', 'windows' => 'German'], + 'de_informal' => ['iso' => 'de_DE', 'windows' => 'German'], + 'en' => ['iso' => 'en_GB', 'windows' => 'English'], + 'es' => ['iso' => 'es_ES', 'windows' => 'Spanish'], + 'es_AR' => ['iso' => 'es_AR', 'windows' => 'Spanish'], + 'et' => ['iso' => 'et_EE', 'windows' => 'Estonian'], + 'eu' => ['iso' => 'eu_ES', 'windows' => 'Basque'], + 'fa' => ['iso' => 'fa_IR', 'windows' => 'Persian'], + 'fr' => ['iso' => 'fr_FR', 'windows' => 'French'], + 'he' => ['iso' => 'he_IL', 'windows' => 'Hebrew'], + 'hr' => ['iso' => 'hr_HR', 'windows' => 'Croatian'], + 'hu' => ['iso' => 'hu_HU', 'windows' => 'Hungarian'], + 'id' => ['iso' => 'id_ID', 'windows' => 'Indonesian'], + 'it' => ['iso' => 'it_IT', 'windows' => 'Italian'], + 'ja' => ['iso' => 'ja', 'windows' => 'Japanese'], + 'ko' => ['iso' => 'ko_KR', 'windows' => 'Korean'], + 'lt' => ['iso' => 'lt_LT', 'windows' => 'Lithuanian'], + 'lv' => ['iso' => 'lv_LV', 'windows' => 'Latvian'], + 'nl' => ['iso' => 'nl_NL', 'windows' => 'Dutch'], + 'nb' => ['iso' => 'nb_NO', 'windows' => 'Norwegian (Bokmal)'], + 'pl' => ['iso' => 'pl_PL', 'windows' => 'Polish'], + 'pt' => ['iso' => 'pt_PT', 'windows' => 'Portuguese'], + 'pt_BR' => ['iso' => 'pt_BR', 'windows' => 'Portuguese'], + 'ru' => ['iso' => 'ru', 'windows' => 'Russian'], + 'sk' => ['iso' => 'sk_SK', 'windows' => 'Slovak'], + 'sl' => ['iso' => 'sl_SI', 'windows' => 'Slovenian'], + 'sv' => ['iso' => 'sv_SE', 'windows' => 'Swedish'], + 'uk' => ['iso' => 'uk_UA', 'windows' => 'Ukrainian'], + 'vi' => ['iso' => 'vi_VN', 'windows' => 'Vietnamese'], + 'zh_CN' => ['iso' => 'zh_CN', 'windows' => 'Chinese (Simplified)'], + 'zh_TW' => ['iso' => 'zh_TW', 'windows' => 'Chinese (Traditional)'], + 'tr' => ['iso' => 'tr_TR', 'windows' => 'Turkish'], + ]; + + /** + * Get the language specifically for the currently logged-in user if available. + */ + public function getUserLanguage(Request $request, string $default): string + { + try { + $user = user(); + } catch (\Exception $exception) { + return $default; + } + + if ($user->isDefault() && config('app.auto_detect_locale')) { + return $this->autoDetectLocale($request, $default); + } + + return setting()->getUser($user, 'language', $default); + } + + /** + * Check if the given BookStack language value is a right-to-left language. + */ + public function isRTL(string $language): bool + { + return in_array($language, $this->rtlLanguages); + } + + /** + * Autodetect the visitors locale by matching locales in their headers + * against the locales supported by BookStack. + */ + protected function autoDetectLocale(Request $request, string $default): string + { + $availableLocales = config('app.locales'); + foreach ($request->getLanguages() as $lang) { + if (in_array($lang, $availableLocales)) { + return $lang; + } + } + + return $default; + } + + /** + * Get the ISO version of a BookStack language name. + */ + public function getIsoName(string $language): string + { + return $this->localeMap[$language]['iso'] ?? $language; + } + + /** + * Set the system date locale for localized date formatting. + * Will try both the standard locale name and the UTF8 variant. + */ + public function setPhpDateTimeLocale(string $language) + { + $isoLang = $this->localeMap[$language]['iso'] ?? false; + + $locales = array_filter([ + $isoLang ? $isoLang . '.utf8' : false, + $isoLang ?: false, + $isoLang ? str_replace('_', '-', $isoLang) : false, + $this->localeMap[$language]['windows'] ?? false, + $language, + ]); + + setlocale(LC_TIME, ...$locales); + } +} \ No newline at end of file From 2fe261e20729e005385f4fe31c375ee699d938b6 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Sat, 3 Sep 2022 12:32:21 +0100 Subject: [PATCH 31/45] Updated page revisions link visibility To match the actual visibilities of the revisions listing page and options. Related to #2946 --- resources/views/entities/meta.blade.php | 6 +++--- resources/views/pages/show.blade.php | 8 ++++---- tests/Entity/PageRevisionTest.php | 12 ++++++++++++ tests/TestCase.php | 8 ++++++++ 4 files changed, 27 insertions(+), 7 deletions(-) diff --git a/resources/views/entities/meta.blade.php b/resources/views/entities/meta.blade.php index ac91eeed3..7ad61f1b1 100644 --- a/resources/views/entities/meta.blade.php +++ b/resources/views/entities/meta.blade.php @@ -10,9 +10,9 @@ @endif @if ($entity->isA('page')) - @if (userCan('page-update', $entity)) @else @endif + + @icon('history'){{ trans('entities.meta_revision', ['revisionCount' => $entity->revision_count]) }} + @endif @if ($entity->ownedBy && $entity->owned_by !== $entity->created_by) diff --git a/resources/views/pages/show.blade.php b/resources/views/pages/show.blade.php index 45d2e2d7f..b2c57c319 100644 --- a/resources/views/pages/show.blade.php +++ b/resources/views/pages/show.blade.php @@ -163,11 +163,11 @@ {{ trans('common.move') }} @endif - - @icon('history') - {{ trans('entities.revisions') }} - @endif + + @icon('history') + {{ trans('entities.revisions') }} + @if(userCan('restrictions-manage', $page)) @icon('lock') diff --git a/tests/Entity/PageRevisionTest.php b/tests/Entity/PageRevisionTest.php index 78bf2dec2..01252eda9 100644 --- a/tests/Entity/PageRevisionTest.php +++ b/tests/Entity/PageRevisionTest.php @@ -9,6 +9,18 @@ use Tests\TestCase; class PageRevisionTest extends TestCase { + + public function test_revision_links_visible_to_viewer() + { + /** @var Page $page */ + $page = Page::query()->first(); + + $html = $this->withHtml($this->asViewer()->get($page->getUrl())); + $html->assertLinkExists($page->getUrl('/revisions')); + $html->assertElementContains('a', 'Revisions'); + $html->assertElementContains('a', 'Revision #1'); + } + public function test_page_revision_views_viewable() { $this->asEditor(); diff --git a/tests/TestCase.php b/tests/TestCase.php index 3ca7638c8..f17d27a1a 100644 --- a/tests/TestCase.php +++ b/tests/TestCase.php @@ -89,6 +89,14 @@ abstract class TestCase extends BaseTestCase return $this->editor; } + /** + * Set the current user context to be a viewer. + */ + public function asViewer() + { + return $this->actingAs($this->getViewer()); + } + /** * Get an instance of a user with 'viewer' permissions. */ From 50214d5fe6a439c13327723070113c09ff1e2d73 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Mon, 5 Sep 2022 13:17:10 +0100 Subject: [PATCH 32/45] New Crowdin updates (#3643) --- resources/lang/ar/activities.php | 14 +- resources/lang/ar/entities.php | 32 +- resources/lang/ar/errors.php | 2 +- resources/lang/ar/settings.php | 4 + resources/lang/bg/activities.php | 14 +- resources/lang/bg/entities.php | 32 +- resources/lang/bg/errors.php | 2 +- resources/lang/bg/settings.php | 4 + resources/lang/bs/activities.php | 14 +- resources/lang/bs/entities.php | 32 +- resources/lang/bs/errors.php | 2 +- resources/lang/bs/settings.php | 4 + resources/lang/ca/activities.php | 14 +- resources/lang/ca/entities.php | 32 +- resources/lang/ca/errors.php | 2 +- resources/lang/ca/settings.php | 4 + resources/lang/cs/activities.php | 14 +- resources/lang/cs/entities.php | 32 +- resources/lang/cs/errors.php | 2 +- resources/lang/cs/settings.php | 4 + resources/lang/cy/activities.php | 14 +- resources/lang/cy/entities.php | 32 +- resources/lang/cy/errors.php | 2 +- resources/lang/cy/settings.php | 4 + resources/lang/da/activities.php | 14 +- resources/lang/da/entities.php | 32 +- resources/lang/da/errors.php | 2 +- resources/lang/da/settings.php | 4 + resources/lang/de/activities.php | 14 +- resources/lang/de/auth.php | 10 +- resources/lang/de/common.php | 6 +- resources/lang/de/editor.php | 2 +- resources/lang/de/entities.php | 38 ++- resources/lang/de/errors.php | 2 +- resources/lang/de/settings.php | 4 + resources/lang/de_informal/activities.php | 42 +-- resources/lang/de_informal/common.php | 2 +- resources/lang/de_informal/editor.php | 32 +- resources/lang/de_informal/entities.php | 58 ++-- resources/lang/de_informal/errors.php | 6 +- resources/lang/de_informal/settings.php | 10 +- resources/lang/es/activities.php | 2 +- resources/lang/es/entities.php | 20 +- resources/lang/es/settings.php | 4 + resources/lang/es_AR/activities.php | 6 +- resources/lang/es_AR/entities.php | 30 +- resources/lang/es_AR/settings.php | 4 + resources/lang/et/activities.php | 14 +- resources/lang/et/entities.php | 32 +- resources/lang/et/errors.php | 2 +- resources/lang/et/settings.php | 4 + resources/lang/eu/activities.php | 14 +- resources/lang/eu/entities.php | 32 +- resources/lang/eu/errors.php | 2 +- resources/lang/eu/settings.php | 4 + resources/lang/fa/activities.php | 14 +- resources/lang/fa/entities.php | 32 +- resources/lang/fa/errors.php | 2 +- resources/lang/fa/settings.php | 4 + resources/lang/fa/validation.php | 2 +- resources/lang/fr/activities.php | 14 +- resources/lang/fr/entities.php | 36 ++- resources/lang/fr/errors.php | 2 +- resources/lang/fr/settings.php | 4 + resources/lang/he/activities.php | 14 +- resources/lang/he/entities.php | 32 +- resources/lang/he/errors.php | 2 +- resources/lang/he/settings.php | 4 + resources/lang/hr/activities.php | 14 +- resources/lang/hr/entities.php | 32 +- resources/lang/hr/errors.php | 2 +- resources/lang/hr/settings.php | 4 + resources/lang/hu/activities.php | 14 +- resources/lang/hu/entities.php | 32 +- resources/lang/hu/errors.php | 2 +- resources/lang/hu/settings.php | 4 + resources/lang/id/activities.php | 14 +- resources/lang/id/entities.php | 32 +- resources/lang/id/errors.php | 2 +- resources/lang/id/settings.php | 4 + resources/lang/it/activities.php | 6 +- resources/lang/it/entities.php | 16 +- resources/lang/it/settings.php | 4 + resources/lang/ja/activities.php | 14 +- resources/lang/ja/entities.php | 32 +- resources/lang/ja/errors.php | 2 +- resources/lang/ja/settings.php | 4 + resources/lang/ko/activities.php | 14 +- resources/lang/ko/entities.php | 32 +- resources/lang/ko/errors.php | 2 +- resources/lang/ko/settings.php | 4 + resources/lang/lt/activities.php | 14 +- resources/lang/lt/entities.php | 32 +- resources/lang/lt/errors.php | 2 +- resources/lang/lt/settings.php | 4 + resources/lang/lv/activities.php | 14 +- resources/lang/lv/entities.php | 32 +- resources/lang/lv/errors.php | 2 +- resources/lang/lv/settings.php | 4 + resources/lang/nb/activities.php | 14 +- resources/lang/nb/entities.php | 32 +- resources/lang/nb/errors.php | 2 +- resources/lang/nb/settings.php | 4 + resources/lang/nl/activities.php | 14 +- resources/lang/nl/entities.php | 24 +- resources/lang/nl/settings.php | 4 + resources/lang/pl/activities.php | 14 +- resources/lang/pl/entities.php | 32 +- resources/lang/pl/errors.php | 2 +- resources/lang/pl/settings.php | 4 + resources/lang/pt/activities.php | 14 +- resources/lang/pt/editor.php | 2 +- resources/lang/pt/entities.php | 46 +-- resources/lang/pt/errors.php | 2 +- resources/lang/pt/settings.php | 4 + resources/lang/pt_BR/activities.php | 14 +- resources/lang/pt_BR/entities.php | 32 +- resources/lang/pt_BR/errors.php | 2 +- resources/lang/pt_BR/settings.php | 4 + resources/lang/ro/activities.php | 73 +++++ resources/lang/ro/auth.php | 115 +++++++ resources/lang/ro/common.php | 104 ++++++ resources/lang/ro/components.php | 34 ++ resources/lang/ro/editor.php | 171 ++++++++++ resources/lang/ro/entities.php | 378 ++++++++++++++++++++++ resources/lang/ro/errors.php | 109 +++++++ resources/lang/ro/pagination.php | 12 + resources/lang/ro/passwords.php | 15 + resources/lang/ro/settings.php | 313 ++++++++++++++++++ resources/lang/ro/validation.php | 117 +++++++ resources/lang/ru/activities.php | 14 +- resources/lang/ru/entities.php | 32 +- resources/lang/ru/errors.php | 2 +- resources/lang/ru/settings.php | 4 + resources/lang/sk/activities.php | 14 +- resources/lang/sk/entities.php | 32 +- resources/lang/sk/errors.php | 2 +- resources/lang/sk/settings.php | 4 + resources/lang/sl/activities.php | 14 +- resources/lang/sl/entities.php | 32 +- resources/lang/sl/errors.php | 2 +- resources/lang/sl/settings.php | 4 + resources/lang/sv/activities.php | 14 +- resources/lang/sv/entities.php | 32 +- resources/lang/sv/errors.php | 2 +- resources/lang/sv/settings.php | 4 + resources/lang/tr/activities.php | 14 +- resources/lang/tr/entities.php | 32 +- resources/lang/tr/errors.php | 2 +- resources/lang/tr/settings.php | 4 + resources/lang/uk/activities.php | 14 +- resources/lang/uk/entities.php | 32 +- resources/lang/uk/errors.php | 2 +- resources/lang/uk/settings.php | 4 + resources/lang/uz/activities.php | 14 +- resources/lang/uz/entities.php | 32 +- resources/lang/uz/errors.php | 2 +- resources/lang/uz/settings.php | 4 + resources/lang/vi/activities.php | 14 +- resources/lang/vi/entities.php | 32 +- resources/lang/vi/errors.php | 2 +- resources/lang/vi/settings.php | 4 + resources/lang/zh_CN/activities.php | 74 ++--- resources/lang/zh_CN/entities.php | 36 ++- resources/lang/zh_CN/errors.php | 4 +- resources/lang/zh_CN/settings.php | 14 +- resources/lang/zh_TW/activities.php | 14 +- resources/lang/zh_TW/entities.php | 34 +- resources/lang/zh_TW/errors.php | 2 +- resources/lang/zh_TW/settings.php | 4 + 170 files changed, 2724 insertions(+), 893 deletions(-) create mode 100644 resources/lang/ro/activities.php create mode 100644 resources/lang/ro/auth.php create mode 100644 resources/lang/ro/common.php create mode 100644 resources/lang/ro/components.php create mode 100644 resources/lang/ro/editor.php create mode 100644 resources/lang/ro/entities.php create mode 100644 resources/lang/ro/errors.php create mode 100644 resources/lang/ro/pagination.php create mode 100644 resources/lang/ro/passwords.php create mode 100644 resources/lang/ro/settings.php create mode 100644 resources/lang/ro/validation.php diff --git a/resources/lang/ar/activities.php b/resources/lang/ar/activities.php index 1cda8b829..5a41718ed 100644 --- a/resources/lang/ar/activities.php +++ b/resources/lang/ar/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'تم إعادة فرز الكتاب بنجاح', // Bookshelves - 'bookshelf_create' => 'تم إنشاء رف كتب', - 'bookshelf_create_notification' => 'تم إنشاء الرف بنجاح', - 'bookshelf_create_from_book' => 'converted book to bookshelf', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf', - 'bookshelf_update' => 'تم تحديث الرف', - 'bookshelf_update_notification' => 'تم تحديث الرف بنجاح', - 'bookshelf_delete' => 'تم تحديث الرف', - 'bookshelf_delete_notification' => 'تم حذف الرف بنجاح', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => 'تم إضافة ":name" إلى المفضلة لديك', diff --git a/resources/lang/ar/entities.php b/resources/lang/ar/entities.php index 770e21ad2..3285b0ad6 100644 --- a/resources/lang/ar/entities.php +++ b/resources/lang/ar/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'مُحدث :timeLength', 'meta_updated_name' => 'مُحدث :timeLength بواسطة :user', 'meta_owned_name' => 'Owned by :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'اختيار الكيان', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'صور', @@ -77,7 +78,6 @@ return [ 'shelf' => 'رف', 'shelves' => 'الأرفف', 'x_shelves' => ':count رف|:count أرفف', - 'shelves_long' => 'أرفف الكتب', 'shelves_empty' => 'لم ينشأ أي رف', 'shelves_create' => 'إنشاء رف جديد', 'shelves_popular' => 'أرفف رائجة', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'لا توجد كتب مخصصة لهذا الرف', 'shelves_edit_and_assign' => 'تحرير الرف لإدراج كتب', - 'shelves_edit_named' => 'تحرير رف الكتب :name', - 'shelves_edit' => 'تحرير رف الكتب', - 'shelves_delete' => 'حذف رف الكتب', - 'shelves_delete_named' => 'حذف رف الكتب :name', - 'shelves_delete_explain' => "سيؤدي هذا إلى حذف رف الكتب المسمى ':name'، ولن تحذف الكتب المتضمنة فيه.", - 'shelves_delete_confirmation' => 'هل أنت متأكد من أنك تريد حذف هذا الرف؟', - 'shelves_permissions' => 'أذونات رف الكتب', - 'shelves_permissions_updated' => 'تم تحديث أذونات رف الكتب', - 'shelves_permissions_active' => 'أذونات رف الكتب نشطة', - 'shelves_permissions_cascade_warning' => 'Permissions on bookshelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'نسخ أذونات الوصول إلى الكتب', 'shelves_copy_permissions' => 'نسخ الأذونات', - 'shelves_copy_permissions_explain' => 'سيؤدي هذا إلى تطبيق إعدادات الأذونات الحالية لهذا الرف على جميع الكتب المتضمنة فيه. قبل التفعيل، تأكد من حفظ أي تغييرات في أذونات هذا الرف.', - 'shelves_copy_permission_success' => 'تم نسخ أذونات رف الكتب إلى :count books', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'كتاب', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'تعديل المحتوى', 'pages_permissions_active' => 'أذونات الصفحة مفعلة', 'pages_initial_revision' => 'نشر مبدئي', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'صفحة جديدة', 'pages_editing_draft_notification' => 'جارٍ تعديل مسودة لم يتم حفظها من :timeDiff.', 'pages_draft_edited_notification' => 'تم تحديث هذه الصفحة منذ ذلك الوقت. من الأفضل التخلص من هذه المسودة.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/ar/errors.php b/resources/lang/ar/errors.php index c9851588b..dc0ef2f0f 100644 --- a/resources/lang/ar/errors.php +++ b/resources/lang/ar/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'الكيان غير موجود', - 'bookshelf_not_found' => 'رف الكتب غير موجود', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'لم يتم العثور على الكتاب', 'page_not_found' => 'لم يتم العثور على الصفحة', 'chapter_not_found' => 'لم يتم العثور على الفصل', diff --git a/resources/lang/ar/settings.php b/resources/lang/ar/settings.php index 093e875bf..a0477bdac 100755 --- a/resources/lang/ar/settings.php +++ b/resources/lang/ar/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'تهانينا! كما تلقيت إشعار هذا البريد الإلكتروني، يبدو أن إعدادات البريد الإلكتروني الخاص بك قد تم تكوينها بشكل صحيح.', 'maint_recycle_bin_desc' => 'تُرسل الأرفف والكتب والفصول والصفحات المحذوفة إلى سلة المحذوفات حتى يمكن استعادتها أو حذفها نهائيًا. قد يتم إزالة العناصر الأقدم في سلة المحذوفات تلقائيًا بعد فترة اعتمادًا على تكوين النظام.', 'maint_recycle_bin_open' => 'افتح سلة المحذوفات', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'سلة المحذوفات', diff --git a/resources/lang/bg/activities.php b/resources/lang/bg/activities.php index 52a6c78aa..854663bff 100644 --- a/resources/lang/bg/activities.php +++ b/resources/lang/bg/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Книгата е преподредена успешно', // Bookshelves - 'bookshelf_create' => 'създаден рафт', - 'bookshelf_create_notification' => 'Рафтът е създаден успешно', - 'bookshelf_create_from_book' => 'converted book to bookshelf', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf', - 'bookshelf_update' => 'обновен рафт', - 'bookshelf_update_notification' => 'Рафтът е обновен успешно', - 'bookshelf_delete' => 'изтрит рафт', - 'bookshelf_delete_notification' => 'Рафтът е изтрит успешно', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" е добавен към любими успешно', diff --git a/resources/lang/bg/entities.php b/resources/lang/bg/entities.php index 17baaa655..cbb78dc9e 100644 --- a/resources/lang/bg/entities.php +++ b/resources/lang/bg/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Актуализирано :timeLength', 'meta_updated_name' => 'Актуализирано преди :timeLength от :user', 'meta_owned_name' => 'Притежавано от :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Избор на обект', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Изображения', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Рафт', 'shelves' => 'Рафтове', 'x_shelves' => ':count Рафт|:count Рафтове', - 'shelves_long' => 'Рафтове с книги', 'shelves_empty' => 'Няма създадени рафтове', 'shelves_create' => 'Създай нов рафт', 'shelves_popular' => 'Популярни рафтове', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'Този рафт няма добавени книги', 'shelves_edit_and_assign' => 'Редактирай рафта за да добавиш книги', - 'shelves_edit_named' => 'Редактирай рафт с книги :name', - 'shelves_edit' => 'Редактирай рафт с книги', - 'shelves_delete' => 'Изтрий рафт с книги', - 'shelves_delete_named' => 'Изтрий рафт с книги :name', - 'shelves_delete_explain' => "Ще бъде изтрит рафта с книги със следното име ':name'. Съдържащите се книги няма да бъдат изтрити.", - 'shelves_delete_confirmation' => 'Сигурни ли сте, че искате да изтриете този рафт с книги?', - 'shelves_permissions' => 'Настройки за достъп до рафта с книги', - 'shelves_permissions_updated' => 'Настройките за достъп до рафта с книги е обновен', - 'shelves_permissions_active' => 'Настройките за достъп до рафта с книги е активен', - 'shelves_permissions_cascade_warning' => 'Привилегиите на рафтовете не се разпространяват автоматично към съдържаните в тях книги. Това е така, защото една книга може да съществува на няколко различни рафта. Въпреки това, привилегиите могат да бъдат копирани до книгите вътре чрез опцията отдолу.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Копирай настойките за достъп към книгите', 'shelves_copy_permissions' => 'Копирай настройките за достъп', - 'shelves_copy_permissions_explain' => 'Това ще приложи настоящите настройки за достъп на този рафт с книги за всички книги, съдържащи се в него. Преди да активирате, уверете се, че всички промени в настройките за достъп на този рафт са запазени.', - 'shelves_copy_permission_success' => 'Настройките за достъп на рафта с книги бяха копирани върху :count books', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Книга', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Редактиране на съдържанието', 'pages_permissions_active' => 'Настройките за достъп до страницата са активни', 'pages_initial_revision' => 'Първо публикуване', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Нова страница', 'pages_editing_draft_notification' => 'В момента редактирате чернова, която беше последно обновена :timeDiff.', 'pages_draft_edited_notification' => 'Тази страница беше актуализирана от тогава. Препоръчително е да изтриете настоящата чернова.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/bg/errors.php b/resources/lang/bg/errors.php index fe4892e94..27779a483 100644 --- a/resources/lang/bg/errors.php +++ b/resources/lang/bg/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Обектът не е намерен', - 'bookshelf_not_found' => 'Рафтът не е намерен', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Книгата не е намерена', 'page_not_found' => 'Страницата не е намерена', 'chapter_not_found' => 'Главата не е намерена', diff --git a/resources/lang/bg/settings.php b/resources/lang/bg/settings.php index 7b467fe45..294451c0f 100644 --- a/resources/lang/bg/settings.php +++ b/resources/lang/bg/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Поздравления! След като получихте този имейл, Вашите имейл настройки са конфигурирани правилно.', 'maint_recycle_bin_desc' => 'Изтрити рафти, книги, глави и страници се преместват в кошчето, откъдето можете да ги възстановите или изтриете завинаги. Стари съдържания в кошчето ще бъдат изтрити автоматично след време, в зависимост от настройките на системата.', 'maint_recycle_bin_open' => 'Отвори Кошчето', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Кошче', diff --git a/resources/lang/bs/activities.php b/resources/lang/bs/activities.php index 16fefbe63..f2c004043 100644 --- a/resources/lang/bs/activities.php +++ b/resources/lang/bs/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Book successfully re-sorted', // Bookshelves - 'bookshelf_create' => 'created bookshelf', - 'bookshelf_create_notification' => 'Bookshelf successfully created', - 'bookshelf_create_from_book' => 'converted book to bookshelf', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf', - 'bookshelf_update' => 'je ažurirao/la policu za knjige', - 'bookshelf_update_notification' => 'Bookshelf successfully updated', - 'bookshelf_delete' => 'je izbrisao/la policu za knjige', - 'bookshelf_delete_notification' => 'Bookshelf successfully deleted', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" je dodan u tvoje favorite', diff --git a/resources/lang/bs/entities.php b/resources/lang/bs/entities.php index d699bd03f..f8805effe 100644 --- a/resources/lang/bs/entities.php +++ b/resources/lang/bs/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Ažurirana :timeLength', 'meta_updated_name' => 'Ažurirana :timeLength od :user', 'meta_owned_name' => 'Vlasnik je :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Odaberi entitet', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Slike', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Polica', 'shelves' => 'Police', 'x_shelves' => ':count Polica|:count Police', - 'shelves_long' => 'Police za knjige', 'shelves_empty' => 'Niti jedna polica nije kreirana', 'shelves_create' => 'Kreiraj novu policu', 'shelves_popular' => 'Popularne police', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'Ova polica nema knjiga koje su postavljene na nju', 'shelves_edit_and_assign' => 'Uredi policu da bi dodao/la knjige', - 'shelves_edit_named' => 'Uredi :name police za knjige', - 'shelves_edit' => 'Uredi policu za knjige', - 'shelves_delete' => 'Izbriši policu za knjige', - 'shelves_delete_named' => 'Izbriši policu za knjige :name', - 'shelves_delete_explain' => "This will delete the bookshelf with the name ':name'. Contained books will not be deleted.", - 'shelves_delete_confirmation' => 'Are you sure you want to delete this bookshelf?', - 'shelves_permissions' => 'Bookshelf Permissions', - 'shelves_permissions_updated' => 'Bookshelf Permissions Updated', - 'shelves_permissions_active' => 'Bookshelf Permissions Active', - 'shelves_permissions_cascade_warning' => 'Permissions on bookshelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Copy Permissions to Books', 'shelves_copy_permissions' => 'Copy Permissions', - '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_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Book', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Uredi sadržaj', 'pages_permissions_active' => 'Dozvole za stranicu su aktivne', 'pages_initial_revision' => 'Prvo izdavanje', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Nova stranica', 'pages_editing_draft_notification' => 'Trenutno uređujete skicu koja je posljednji put snimljena :timeDiff.', 'pages_draft_edited_notification' => 'Ova stranica je ažurirana nakon tog vremena. Preporučujemo da odbacite ovu skicu.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/bs/errors.php b/resources/lang/bs/errors.php index 5c3855853..0928d7985 100644 --- a/resources/lang/bs/errors.php +++ b/resources/lang/bs/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Entitet nije pronađen', - 'bookshelf_not_found' => 'Polica za knjige nije pronađena', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Knjiga nije pronađena', 'page_not_found' => 'Stranica nije pronađena', 'chapter_not_found' => 'Poglavlje nije pronađeno', diff --git a/resources/lang/bs/settings.php b/resources/lang/bs/settings.php index 3bfe70bc4..9dbd96c5a 100644 --- a/resources/lang/bs/settings.php +++ b/resources/lang/bs/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Congratulations! As you received this email notification, your email settings seem to be configured properly.', 'maint_recycle_bin_desc' => 'Deleted shelves, books, chapters & pages are sent to the recycle bin so they can be restored or permanently deleted. Older items in the recycle bin may be automatically removed after a while depending on system configuration.', 'maint_recycle_bin_open' => 'Open Recycle Bin', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Recycle Bin', diff --git a/resources/lang/ca/activities.php b/resources/lang/ca/activities.php index 083f45656..e579dbed0 100644 --- a/resources/lang/ca/activities.php +++ b/resources/lang/ca/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Book successfully re-sorted', // Bookshelves - 'bookshelf_create' => 'created bookshelf', - 'bookshelf_create_notification' => 'Bookshelf successfully created', - 'bookshelf_create_from_book' => 'converted book to bookshelf', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf', - 'bookshelf_update' => 'ha actualitzat el prestatge', - 'bookshelf_update_notification' => 'Bookshelf successfully updated', - 'bookshelf_delete' => 'ha suprimit un prestatge', - 'bookshelf_delete_notification' => 'Bookshelf successfully deleted', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" has been added to your favourites', diff --git a/resources/lang/ca/entities.php b/resources/lang/ca/entities.php index 828ac0938..b31cbaa93 100644 --- a/resources/lang/ca/entities.php +++ b/resources/lang/ca/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Actualitzat :timeLength', 'meta_updated_name' => 'Actualitzat :timeLength per :user', 'meta_owned_name' => 'Propietat de :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Selecciona una entitat', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Imatges', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Prestatge', 'shelves' => 'Prestatges', 'x_shelves' => ':count prestatge|:count prestatges', - 'shelves_long' => 'Prestatges', 'shelves_empty' => 'No hi ha cap prestatge creat', 'shelves_create' => 'Crea un prestatge nou', 'shelves_popular' => 'Prestatges populars', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'Aquest prestatge no té cap llibre assignat', 'shelves_edit_and_assign' => 'Editeu el prestatge per a assignar-hi llibres', - 'shelves_edit_named' => 'Edita el prestatge :name', - 'shelves_edit' => 'Edita el prestatge', - 'shelves_delete' => 'Suprimeix el prestatge', - 'shelves_delete_named' => 'Suprimeix el prestatge :name', - 'shelves_delete_explain' => "Se suprimirà el prestatge amb el nom ':name'. Els llibres que contingui no se suprimiran.", - 'shelves_delete_confirmation' => 'Segur que voleu suprimir aquest prestatge?', - 'shelves_permissions' => 'Permisos del prestatge', - 'shelves_permissions_updated' => 'S\'han actualitzat els permisos del prestatge', - 'shelves_permissions_active' => 'S\'han activat els permisos del prestatge', - 'shelves_permissions_cascade_warning' => 'Permissions on bookshelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Copia els permisos als llibres', 'shelves_copy_permissions' => 'Copia els permisos', - 'shelves_copy_permissions_explain' => 'Això aplicarà la configuració de permisos actual d\'aquest prestatge a tots els llibres que contingui. Abans d\'activar-ho, assegureu-vos que hàgiu desat qualsevol canvi als permisos d\'aquest prestatge.', - 'shelves_copy_permission_success' => 'S\'han copiat els permisos del prestatge a :count llibres', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Llibre', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Edita el contingut', 'pages_permissions_active' => 'S\'han activat els permisos de la pàgina', 'pages_initial_revision' => 'Publicació inicial', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Pàgina nova', 'pages_editing_draft_notification' => 'Esteu editant un esborrany que es va desar per darrer cop :timeDiff.', 'pages_draft_edited_notification' => 'Aquesta pàgina s\'ha actualitzat d\'ençà d\'aleshores. Us recomanem que descarteu aquest esborrany.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/ca/errors.php b/resources/lang/ca/errors.php index 477b59e26..5b9fe4dc0 100644 --- a/resources/lang/ca/errors.php +++ b/resources/lang/ca/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'No s\'ha trobat l\'entitat', - 'bookshelf_not_found' => 'No s\'ha trobat el prestatge', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'No s\'ha trobat el llibre', 'page_not_found' => 'No s\'ha trobat la pàgina', 'chapter_not_found' => 'No s\'ha trobat el capítol', diff --git a/resources/lang/ca/settings.php b/resources/lang/ca/settings.php index d5185a4db..694005cde 100755 --- a/resources/lang/ca/settings.php +++ b/resources/lang/ca/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Enhorabona! Com que heu rebut aquesta notificació per correu electrònic, la vostra configuració del correu electrònic sembla que està ben configurada.', 'maint_recycle_bin_desc' => 'Els prestatges, llibres, capítols i pàgines eliminats s\'envien a la paperera de reciclatge perquè es puguin restaurar o suprimir de manera permanent. Pot ser que els elements més antics de la paperera de reciclatge se suprimeixin automàticament després d\'un temps, depenent de la configuració del sistema.', 'maint_recycle_bin_open' => 'Obre la paperera de reciclatge', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Paperera de reciclatge', diff --git a/resources/lang/cs/activities.php b/resources/lang/cs/activities.php index 2de8532d4..97ef00d41 100644 --- a/resources/lang/cs/activities.php +++ b/resources/lang/cs/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Kniha byla úspěšně seřazena', // Bookshelves - 'bookshelf_create' => 'vytvořil/a knihovnu', - 'bookshelf_create_notification' => 'Knihovna byla úspěšně vytvořena', - 'bookshelf_create_from_book' => 'converted book to bookshelf', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf', - 'bookshelf_update' => 'aktualizoval/a knihovnu', - 'bookshelf_update_notification' => 'Knihovna byla úspěšně aktualizována', - 'bookshelf_delete' => 'odstranil/a knihovnu', - 'bookshelf_delete_notification' => 'Knihovna byla úspěšně smazána', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" byla přidána do Vašich oblíbených', diff --git a/resources/lang/cs/entities.php b/resources/lang/cs/entities.php index d567d80cd..34515fd77 100644 --- a/resources/lang/cs/entities.php +++ b/resources/lang/cs/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Aktualizováno :timeLength', 'meta_updated_name' => 'Aktualizováno :timeLength uživatelem :user', 'meta_owned_name' => 'Vlastník :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Výběr entity', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Obrázky', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Knihovna', 'shelves' => 'Knihovny', 'x_shelves' => '{0}:count knihoven|{1}:count knihovna|[2,4]:count knihovny|[5,*]:count knihoven', - 'shelves_long' => 'Knihovny', 'shelves_empty' => 'Nebyly vytvořeny žádné knihovny', 'shelves_create' => 'Vytvořit novou knihovnu', 'shelves_popular' => 'Populární knihovny', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'Tato knihovna neobsahuje žádné knihy', 'shelves_edit_and_assign' => 'Upravit knihovnu a přiřadit knihy', - 'shelves_edit_named' => 'Upravit knihovnu :name', - 'shelves_edit' => 'Upravit knihovnu', - 'shelves_delete' => 'Odstranit knihovnu', - 'shelves_delete_named' => 'Odstranit knihovnu :name', - 'shelves_delete_explain' => "Toto odstraní knihovnu ‚:name‘. Vložené knihy nebudou odstraněny.", - 'shelves_delete_confirmation' => 'Opravdu chcete odstranit tuto knihovnu?', - 'shelves_permissions' => 'Oprávnění knihovny', - 'shelves_permissions_updated' => 'Oprávnění knihovny byla aktualizována', - 'shelves_permissions_active' => 'Oprávnění knihovny byla aktivována', - 'shelves_permissions_cascade_warning' => 'Oprávnění v Knihovnách nejsou automaticky kaskádována do obsažených knih. To proto, že kniha může existovat ve více Knihovnách. Oprávnění však lze zkopírovat do podřízených knih pomocí níže uvedené možnosti.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Kopírovat oprávnění na knihy', 'shelves_copy_permissions' => 'Kopírovat oprávnění', - 'shelves_copy_permissions_explain' => 'Toto použije aktuální nastavení oprávnění knihovny na všechny knihy v ní obsažené. Před aktivací se ujistěte, že byly uloženy všechny změny oprávnění této knihovny.', - 'shelves_copy_permission_success' => 'Oprávnění knihovny byla zkopírována na :count knih', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Kniha', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Upravit obsah', 'pages_permissions_active' => 'Oprávnění stránky byla aktivována', 'pages_initial_revision' => 'První vydání', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Nová stránka', 'pages_editing_draft_notification' => 'Právě upravujete koncept, který byl uložen :timeDiff.', 'pages_draft_edited_notification' => 'Tato stránka se od té doby změnila. Je doporučeno aktuální koncept zahodit.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/cs/errors.php b/resources/lang/cs/errors.php index 54b18766c..942894c94 100644 --- a/resources/lang/cs/errors.php +++ b/resources/lang/cs/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Prvek nenalezen', - 'bookshelf_not_found' => 'Knihovna nenalezena', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Kniha nenalezena', 'page_not_found' => 'Stránka nenalezena', 'chapter_not_found' => 'Kapitola nenalezena', diff --git a/resources/lang/cs/settings.php b/resources/lang/cs/settings.php index cf1e0029a..68328ce53 100644 --- a/resources/lang/cs/settings.php +++ b/resources/lang/cs/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Gratulujeme! Protože jste dostali tento e-mail, zdá se, že nastavení e-mailů je v pořádku.', 'maint_recycle_bin_desc' => 'Odstraněné knihovny, knihy, kapitoly a stránky se přesouvají do Koše, aby je bylo možné obnovit nebo trvale smazat. Starší položky v koši mohou být po čase automaticky odstraněny v závislosti na konfiguraci systému.', 'maint_recycle_bin_open' => 'Otevřít Koš', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Koš', diff --git a/resources/lang/cy/activities.php b/resources/lang/cy/activities.php index b1a643d34..e890a7853 100644 --- a/resources/lang/cy/activities.php +++ b/resources/lang/cy/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Ail-archebwyd y llyfr yn llwyddiannus', // Bookshelves - 'bookshelf_create' => 'creu silff lyfrau', - 'bookshelf_create_notification' => 'Silff lyfrau wedi\'i chreu\'n llwyddiannus', - 'bookshelf_create_from_book' => 'converted book to bookshelf', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf', - 'bookshelf_update' => 'silff lyfrau wedi\'i diweddaru', - 'bookshelf_update_notification' => 'Diweddarwyd y silff lyfrau yn llwyddiannus', - 'bookshelf_delete' => 'silff lyfrau wedi\'i dileu', - 'bookshelf_delete_notification' => 'Silff lyfrau wedi\'i dileu\'n llwyddiannus', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => 'Mae ":name" wedi\'i ychwanegu at eich ffefrynnau', diff --git a/resources/lang/cy/entities.php b/resources/lang/cy/entities.php index db1e8027b..1720801d2 100644 --- a/resources/lang/cy/entities.php +++ b/resources/lang/cy/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Updated :timeLength', 'meta_updated_name' => 'Updated :timeLength by :user', 'meta_owned_name' => 'Owned by :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Entity Select', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Images', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Shelf', 'shelves' => 'Shelves', 'x_shelves' => ':count Shelf|:count Shelves', - 'shelves_long' => 'Bookshelves', 'shelves_empty' => 'No shelves have been created', 'shelves_create' => 'Create New Shelf', 'shelves_popular' => 'Popular Shelves', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'This shelf has no books assigned to it', 'shelves_edit_and_assign' => 'Edit shelf to assign books', - 'shelves_edit_named' => 'Edit Bookshelf :name', - 'shelves_edit' => 'Edit Bookshelf', - 'shelves_delete' => 'Delete Bookshelf', - 'shelves_delete_named' => 'Delete Bookshelf :name', - 'shelves_delete_explain' => "This will delete the bookshelf with the name ':name'. Contained books will not be deleted.", - 'shelves_delete_confirmation' => 'Are you sure you want to delete this bookshelf?', - 'shelves_permissions' => 'Bookshelf Permissions', - 'shelves_permissions_updated' => 'Bookshelf Permissions Updated', - 'shelves_permissions_active' => 'Bookshelf Permissions Active', - 'shelves_permissions_cascade_warning' => 'Permissions on bookshelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Copy Permissions to Books', 'shelves_copy_permissions' => 'Copy Permissions', - '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_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Book', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Edit Content', 'pages_permissions_active' => 'Page Permissions Active', 'pages_initial_revision' => 'Initial publish', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'New Page', 'pages_editing_draft_notification' => 'You are currently editing a draft that was last saved :timeDiff.', 'pages_draft_edited_notification' => 'This page has been updated by since that time. It is recommended that you discard this draft.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/cy/errors.php b/resources/lang/cy/errors.php index d540baeac..f681de1c9 100644 --- a/resources/lang/cy/errors.php +++ b/resources/lang/cy/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Endid heb ei ganfod', - 'bookshelf_not_found' => 'Heb ddod o hyd i\'r silff lyfrau', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Ni chanfuwyd y llyfr', 'page_not_found' => 'Heb ganfod y dudalen', 'chapter_not_found' => 'Pennod heb ei chanfod', diff --git a/resources/lang/cy/settings.php b/resources/lang/cy/settings.php index 3bfe70bc4..9dbd96c5a 100644 --- a/resources/lang/cy/settings.php +++ b/resources/lang/cy/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Congratulations! As you received this email notification, your email settings seem to be configured properly.', 'maint_recycle_bin_desc' => 'Deleted shelves, books, chapters & pages are sent to the recycle bin so they can be restored or permanently deleted. Older items in the recycle bin may be automatically removed after a while depending on system configuration.', 'maint_recycle_bin_open' => 'Open Recycle Bin', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Recycle Bin', diff --git a/resources/lang/da/activities.php b/resources/lang/da/activities.php index adfba7d00..72ad44a79 100644 --- a/resources/lang/da/activities.php +++ b/resources/lang/da/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Bogen blev re-sorteret', // Bookshelves - 'bookshelf_create' => 'oprettede bogreol', - 'bookshelf_create_notification' => 'Bogreolen blev oprettet', - 'bookshelf_create_from_book' => 'omdannede bog til bogreol', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Bogen blev omdannet til en bogreal', - 'bookshelf_update' => 'opdaterede bogreolen', - 'bookshelf_update_notification' => 'Bogreolen blev opdateret', - 'bookshelf_delete' => 'slettede bogreol', - 'bookshelf_delete_notification' => 'Bogreolen blev slettet', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" er blevet tilføjet til dine favoritter', diff --git a/resources/lang/da/entities.php b/resources/lang/da/entities.php index 0c9c13235..365f3e529 100644 --- a/resources/lang/da/entities.php +++ b/resources/lang/da/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Opdateret :timeLength', 'meta_updated_name' => 'Opdateret :timeLength af :user', 'meta_owned_name' => 'Ejet af :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Vælg emne', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Billeder', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Reol', 'shelves' => 'Reoler', 'x_shelves' => ':count reol|:count reoler', - 'shelves_long' => 'Bogreoler', 'shelves_empty' => 'Ingen reoler er blevet oprettet', 'shelves_create' => 'Opret ny reol', 'shelves_popular' => 'Populære reoler', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'Denne reol har ingen bøger tilknyttet til den', 'shelves_edit_and_assign' => 'Rediger reol for at tilføje bøger', - 'shelves_edit_named' => 'Rediger reol :name', - 'shelves_edit' => 'Rediger reol', - 'shelves_delete' => 'Slet reol', - 'shelves_delete_named' => 'Slet bogreol :name', - 'shelves_delete_explain' => "Dette vil slette bogreolen med navn ':name'. Bøger heri vil ikke blive slettet.", - 'shelves_delete_confirmation' => 'Er du sikker på at du vil slette denne bogreol?', - 'shelves_permissions' => 'Reoltilladelser', - 'shelves_permissions_updated' => 'Reoltilladelser opdateret', - 'shelves_permissions_active' => 'Aktive reoltilladelser', - 'shelves_permissions_cascade_warning' => 'Tilladelser på reoler nedarves ikke automatisk til indeholdte bøger. Dette skyldes, at en bog kan eksistere på flere hylder. Tilladelser kan dog kopieres ned til underliggende bøger ved hjælp af muligheden, der findes nedenfor.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Kopier tilladelser til bøger', 'shelves_copy_permissions' => 'Kopier tilladelser', - 'shelves_copy_permissions_explain' => 'Dette vil anvende de aktuelle tilladelsesindstillinger på denne boghylde på alle bøger indeholdt i. Før aktivering skal du sikre dig, at ændringer i tilladelserne til denne boghylde er blevet gemt.', - 'shelves_copy_permission_success' => 'Reolstilladelser kopieret til :count bøger', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Bog', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Redigér indhold', 'pages_permissions_active' => 'Aktive sidetilladelser', 'pages_initial_revision' => 'Første udgivelse', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Ny side', 'pages_editing_draft_notification' => 'Du redigerer en kladde der sidst var gemt :timeDiff.', 'pages_draft_edited_notification' => 'Siden har været opdateret siden da. Det er anbefalet at du kasserer denne kladde.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Omdan Kapitel', 'convert_chapter_confirm' => 'Er du sikker på at du vil omdanne dette kapitel?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/da/errors.php b/resources/lang/da/errors.php index 9e9cb808b..a1aa1201c 100644 --- a/resources/lang/da/errors.php +++ b/resources/lang/da/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Emne ikke fundet', - 'bookshelf_not_found' => 'Bogreol ikke fundet', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Bog ikke fundet', 'page_not_found' => 'Side ikke fundet', 'chapter_not_found' => 'Kapitel ikke fundet', diff --git a/resources/lang/da/settings.php b/resources/lang/da/settings.php index a6920ce64..2296e3e1c 100644 --- a/resources/lang/da/settings.php +++ b/resources/lang/da/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Tillykke! Da du har modtaget denne mailnotifikation, ser det ud som om, at dine mailindstillinger er opsat korrekt.', 'maint_recycle_bin_desc' => 'Slettede hylder, bøger, kapitler og sider overføres til papirkurven, så de kan gendannes eller slettes permanent. Ældre elementer i papirkurven fjernes automatisk efter et stykke tid afhængigt af systemets konfiguration.', 'maint_recycle_bin_open' => 'Åbn papirkurven', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Papirkurv', diff --git a/resources/lang/de/activities.php b/resources/lang/de/activities.php index b21788161..abc391425 100644 --- a/resources/lang/de/activities.php +++ b/resources/lang/de/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Das Buch wurde erfolgreich umsortiert', // Bookshelves - 'bookshelf_create' => 'erstelltes Bücherregal', - 'bookshelf_create_notification' => 'Das Bücherregal wurde erfolgreich erstellt', - 'bookshelf_create_from_book' => 'umgewandeltes Buch zum Regal', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Buch erfolgreich in ein Regal konvertiert', - 'bookshelf_update' => 'hat das Bücherregal geändert', - 'bookshelf_update_notification' => 'Das Bücherregal wurde erfolgreich geändert', - 'bookshelf_delete' => 'hat das Bücherregal gelöscht', - 'bookshelf_delete_notification' => 'Das Bücherregal wurde erfolgreich gelöscht', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" wurde zu deinen Favoriten hinzugefügt', diff --git a/resources/lang/de/auth.php b/resources/lang/de/auth.php index df047f914..a2ea42086 100644 --- a/resources/lang/de/auth.php +++ b/resources/lang/de/auth.php @@ -25,12 +25,12 @@ return [ 'forgot_password' => 'Passwort vergessen?', 'remember_me' => 'Angemeldet bleiben', 'ldap_email_hint' => 'Bitte geben Sie eine E-Mail-Adresse ein, um diese mit dem Account zu nutzen.', - 'create_account' => 'Account registrieren', - 'already_have_account' => 'Bereits ein Konto erstellt?', - 'dont_have_account' => 'Noch kein Konto erstellt?', + 'create_account' => 'Account erstellen', + 'already_have_account' => 'Sie haben bereits einen Account?', + 'dont_have_account' => 'Sie haben noch keinen Account?', 'social_login' => 'Mit Sozialem Netzwerk anmelden', 'social_registration' => 'Mit Sozialem Netzwerk registrieren', - 'social_registration_text' => 'Mit einer dieser Dienste registrieren oder anmelden', + 'social_registration_text' => 'Mit einem anderen Dienst registrieren oder anmelden.', 'register_thanks' => 'Vielen Dank für Ihre Registrierung!', 'register_confirm' => 'Bitte prüfen Sie Ihren Posteingang und bestätigen Sie die Registrierung.', @@ -75,7 +75,7 @@ return [ 'user_invite_email_action' => 'Account-Passwort festlegen', 'user_invite_page_welcome' => 'Willkommen bei :appName!', 'user_invite_page_text' => 'Um die Anmeldung abzuschließen und Zugriff auf :appName zu bekommen muss noch ein Passwort festgelegt werden. Dieses wird in Zukunft zum Einloggen benötigt.', - 'user_invite_page_confirm_button' => 'Passwort wiederholen', + 'user_invite_page_confirm_button' => 'Passwort bestätigen', 'user_invite_success_login' => 'Passwort gesetzt, Sie sollten nun in der Lage sein, sich mit Ihrem Passwort an :appName anzumelden!', // Multi-factor Authentication diff --git a/resources/lang/de/common.php b/resources/lang/de/common.php index 24f655339..645c4ad58 100644 --- a/resources/lang/de/common.php +++ b/resources/lang/de/common.php @@ -9,7 +9,7 @@ return [ 'confirm' => 'Bestätigen', 'back' => 'Zurück', 'save' => 'Speichern', - 'continue' => 'Weiter', + 'continue' => 'Fortfahren', 'select' => 'Auswählen', 'toggle_all' => 'Alle umschalten', 'more' => 'Mehr', @@ -25,7 +25,7 @@ return [ 'actions' => 'Aktionen', 'view' => 'Anzeigen', 'view_all' => 'Alle anzeigen', - 'create' => 'Anlegen', + 'create' => 'Erstellen', 'update' => 'Aktualisieren', 'edit' => 'Bearbeiten', 'sort' => 'Sortieren', @@ -48,7 +48,7 @@ return [ 'filter_active' => 'Gesetzte Filter:', 'filter_clear' => 'Filter löschen', 'download' => 'Herunterladen', - 'open_in_tab' => 'In Neuem Tab öffnen', + 'open_in_tab' => 'In neuem Tab öffnen', // Sort Options 'sort_options' => 'Sortieroptionen', diff --git a/resources/lang/de/editor.php b/resources/lang/de/editor.php index 2d96d0365..2fff8c7ea 100644 --- a/resources/lang/de/editor.php +++ b/resources/lang/de/editor.php @@ -157,7 +157,7 @@ return [ 'about' => 'Über den Editor', 'about_title' => 'Über den WYSIWYG-Editor', 'editor_license' => 'Editorlizenz & Copyright', - 'editor_tiny_license' => 'This editor is built using :tinyLink which is provided under the MIT license.', + 'editor_tiny_license' => 'Dieser Editor wurde mithilfe von :tinyLink erstellt, der unter der MIT-Lizenz bereitgestellt wird.', 'editor_tiny_license_link' => 'Die Copyright- und Lizenzdetails von TinyMCE finden Sie hier.', 'save_continue' => 'Speichern & Fortfahren', 'callouts_cycle' => '(Drücken Sie weiter, um durch Typen umzuschalten)', diff --git a/resources/lang/de/entities.php b/resources/lang/de/entities.php index 093e09b66..cabd3b770 100644 --- a/resources/lang/de/entities.php +++ b/resources/lang/de/entities.php @@ -23,8 +23,9 @@ return [ 'meta_updated' => 'Zuletzt aktualisiert: :timeLength', 'meta_updated_name' => 'Zuletzt aktualisiert: :timeLength von :user', 'meta_owned_name' => 'Im Besitz von :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Eintrag auswählen', - 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', + 'entity_select_lack_permission' => 'Sie haben nicht die benötigte Berechtigung, um dieses Element auszuwählen', 'images' => 'Bilder', 'my_recent_drafts' => 'Meine kürzlichen Entwürfe', 'my_recently_viewed' => 'Kürzlich von mir angesehen', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Regal', 'shelves' => 'Regale', 'x_shelves' => ':count Regal|:count Regale', - 'shelves_long' => 'Bücherregal', 'shelves_empty' => 'Es wurden noch keine Regale angelegt', 'shelves_create' => 'Erzeuge ein Regal', 'shelves_popular' => 'Beliebte Regale', @@ -88,23 +88,23 @@ return [ 'shelves_save' => 'Regal speichern', 'shelves_books' => 'Bücher in diesem Regal', 'shelves_add_books' => 'Buch zu diesem Regal hinzufügen', - 'shelves_drag_books' => 'Drag books below to add them to this shelf', + 'shelves_drag_books' => 'Ziehen Sie Bücher nach unten, um sie diesem Regal hinzuzufügen', 'shelves_empty_contents' => 'Diesem Regal sind keine Bücher zugewiesen', 'shelves_edit_and_assign' => 'Regal bearbeiten um Bücher hinzuzufügen', - 'shelves_edit_named' => 'Bücherregal :name bearbeiten', - 'shelves_edit' => 'Bücherregal bearbeiten', - 'shelves_delete' => 'Bücherregal löschen', - 'shelves_delete_named' => 'Bücherregal :name löschen', - 'shelves_delete_explain' => "Sie sind im Begriff das Bücherregal mit dem Namen ':name' zu löschen. Enthaltene Bücher werden nicht gelöscht.", - 'shelves_delete_confirmation' => 'Sind Sie sicher, dass Sie dieses Bücherregal löschen wollen?', - 'shelves_permissions' => 'Regal-Berechtigungen', - 'shelves_permissions_updated' => 'Regal-Berechtigungen aktualisiert', - 'shelves_permissions_active' => 'Regal-Berechtigungen aktiv', - 'shelves_permissions_cascade_warning' => 'Die Berechtigungen in Bücherregalen werden nicht automatisch auf enthaltene Bücher kaskadiert, weil ein Buch in mehreren Regalen existieren kann. Berechtigungen können jedoch mit der unten stehenden Option in untergeordnete Bücher kopiert werden.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Kopiere die Berechtigungen zum Buch', 'shelves_copy_permissions' => 'Berechtigungen kopieren', - 'shelves_copy_permissions_explain' => 'Hiermit werden die Berechtigungen des aktuellen Regals auf alle enthaltenen Bücher übertragen. Überprüfen Sie vor der Aktivierung, ob alle Berechtigungsänderungen am aktuellen Regal gespeichert wurden.', - 'shelves_copy_permission_success' => 'Regal-Berechtigungen wurden zu :count Büchern kopiert', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Buch', @@ -171,7 +171,7 @@ return [ 'chapters_permissions_active' => 'Kapitel-Berechtigungen aktiv', 'chapters_permissions_success' => 'Kapitel-Berechtigungenen aktualisisert', 'chapters_search_this' => 'Dieses Kapitel durchsuchen', - 'chapter_sort_book' => 'Sort Book', + 'chapter_sort_book' => 'Buch sortieren', // Pages 'page' => 'Seite', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Inhalt bearbeiten', 'pages_permissions_active' => 'Seiten-Berechtigungen aktiv', 'pages_initial_revision' => 'Erste Veröffentlichung', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Neue Seite', 'pages_editing_draft_notification' => 'Sie bearbeiten momenten einen Entwurf, der zuletzt :timeDiff gespeichert wurde.', 'pages_draft_edited_notification' => 'Diese Seite wurde seit diesem Zeitpunkt verändert. Wir empfehlen Ihnen, diesen Entwurf zu verwerfen.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'Sie können dieses Kapitel zu einem neuen Buch mit dem gleichen Inhalt umwandeln. Alle Berechtigungen für dieses Kapitel werden in das neue Buch übernommen, aber alle vom ursprünglichen Buch vererbten Berechtigungen werden nicht übernommen, daher kann es zu Änderungen im Zugriff kommen.', 'convert_chapter' => 'Kapitel umwandeln', 'convert_chapter_confirm' => 'Sind Sie sicher, dass Sie dieses Kapitel umwandeln möchten?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/de/errors.php b/resources/lang/de/errors.php index cedd85ad7..acf8bfcdb 100644 --- a/resources/lang/de/errors.php +++ b/resources/lang/de/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Eintrag nicht gefunden', - 'bookshelf_not_found' => 'Regal nicht gefunden', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Buch nicht gefunden', 'page_not_found' => 'Seite nicht gefunden', 'chapter_not_found' => 'Kapitel nicht gefunden', diff --git a/resources/lang/de/settings.php b/resources/lang/de/settings.php index e69f72917..95ee06021 100644 --- a/resources/lang/de/settings.php +++ b/resources/lang/de/settings.php @@ -92,6 +92,10 @@ Hinweis: Benutzer können ihre E-Mail Adresse nach erfolgreicher Registrierung 'maint_send_test_email_mail_text' => 'Glückwunsch! Da Sie diese E-Mail Benachrichtigung erhalten haben, scheinen Ihre E-Mail-Einstellungen korrekt konfiguriert zu sein.', 'maint_recycle_bin_desc' => 'Gelöschte Regale, Bücher, Kapitel & Seiten werden in den Papierkorb verschoben, so dass sie wiederhergestellt oder dauerhaft gelöscht werden können. Ältere Gegenstände im Papierkorb können, in Abhängigkeit von der Systemkonfiguration, nach einer Weile automatisch entfernt werden.', 'maint_recycle_bin_open' => 'Papierkorb öffnen', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Papierkorb', diff --git a/resources/lang/de_informal/activities.php b/resources/lang/de_informal/activities.php index cea04ecd7..26f7c53a3 100644 --- a/resources/lang/de_informal/activities.php +++ b/resources/lang/de_informal/activities.php @@ -7,45 +7,45 @@ return [ // Pages 'page_create' => 'erstellt Seite', - 'page_create_notification' => 'Die Seite wurde erfolgreich erstellt', + 'page_create_notification' => 'Seite erfolgreich erstellt', 'page_update' => 'aktualisiert Seite', - 'page_update_notification' => 'Die Seite wurde erfolgreich aktualisiert', + 'page_update_notification' => 'Seite erfolgreich aktualisiert', 'page_delete' => 'löscht Seite', - 'page_delete_notification' => 'Die Seite wurde erfolgreich gelöscht', + 'page_delete_notification' => 'Seite erfolgreich gelöscht', 'page_restore' => 'stellt Seite wieder her', - 'page_restore_notification' => 'Die Seite wurde erfolgreich wiederhergestellt', + 'page_restore_notification' => 'Seite erfolgreich wiederhergestellt', 'page_move' => 'verschiebt Seite', // Chapters 'chapter_create' => 'erstellt Kapitel', - 'chapter_create_notification' => 'Das Kapitel wurde erfolgreich erstellt', + 'chapter_create_notification' => 'Kapitel erfolgreich erstellt', 'chapter_update' => 'aktualisiert Kapitel', - 'chapter_update_notification' => 'Das Kapitel wurde erfolgreich aktualisiert', + 'chapter_update_notification' => 'Kapitel erfolgreich aktualisiert', 'chapter_delete' => 'löscht Kapitel', - 'chapter_delete_notification' => 'Das Kapitel wurde erfolgreich gelöscht', + 'chapter_delete_notification' => 'Kapitel erfolgreich gelöscht', 'chapter_move' => 'verschiebt Kapitel', // Books 'book_create' => 'erstellt Buch', - 'book_create_notification' => 'Das Buch wurde erfolgreich erstellt', + 'book_create_notification' => 'Buch erfolgreich erstellt', 'book_create_from_chapter' => 'umgewandeltes Kapitel zum Buch', 'book_create_from_chapter_notification' => 'Kapitel erfolgreich in ein Buch konvertiert', 'book_update' => 'aktualisiert Buch', - 'book_update_notification' => 'Das Buch wurde erfolgreich aktualisiert', + 'book_update_notification' => 'Buch erfolgreich aktualisiert', 'book_delete' => 'löscht Buch', - 'book_delete_notification' => 'Das Buch wurde erfolgreich gelöscht', + 'book_delete_notification' => 'Buch erfolgreich gelöscht', 'book_sort' => 'sortiert Buch', - 'book_sort_notification' => 'Das Buch wurde erfolgreich umsortiert', + 'book_sort_notification' => 'Buch erfolgreich umsortiert', // Bookshelves - 'bookshelf_create' => 'erstelltes Bücherregal', - 'bookshelf_create_notification' => 'Das Bücherregal wurde erfolgreich erstellt', - 'bookshelf_create_from_book' => 'umgewandeltes Buch zum Regal', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Buch erfolgreich in ein Regal konvertiert', - 'bookshelf_update' => 'aktualisiert Bücherregal', - 'bookshelf_update_notification' => 'Das Bücherregal wurde erfolgreich geändert', - 'bookshelf_delete' => 'löscht Bücherregal', - 'bookshelf_delete_notification' => 'Das Bücherregal wurde erfolgreich gelöscht', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" wurde zu deinen Favoriten hinzugefügt', @@ -57,11 +57,11 @@ return [ // Webhooks 'webhook_create' => 'erstellter Webhook', - 'webhook_create_notification' => 'Webhook wurde erfolgreich eingerichtet', + 'webhook_create_notification' => 'Webhook erfolgreich eingerichtet', 'webhook_update' => 'aktualisierter Webhook', - 'webhook_update_notification' => 'Webhook wurde erfolgreich aktualisiert', + 'webhook_update_notification' => 'Webhook erfolgreich aktualisiert', 'webhook_delete' => 'gelöschter Webhook', - 'webhook_delete_notification' => 'Webhook wurde erfolgreich gelöscht', + 'webhook_delete_notification' => 'Webhook erfolgreich gelöscht', // Users 'user_update_notification' => 'Benutzer erfolgreich aktualisiert', diff --git a/resources/lang/de_informal/common.php b/resources/lang/de_informal/common.php index 1d92bda7c..bb4c28be2 100644 --- a/resources/lang/de_informal/common.php +++ b/resources/lang/de_informal/common.php @@ -48,7 +48,7 @@ return [ 'filter_active' => 'Gesetzte Filter:', 'filter_clear' => 'Filter löschen', 'download' => 'Herunterladen', - 'open_in_tab' => 'In Neuem Tab öffnen', + 'open_in_tab' => 'In Tab öffnen', // Sort Options 'sort_options' => 'Sortieroptionen', diff --git a/resources/lang/de_informal/editor.php b/resources/lang/de_informal/editor.php index 2d96d0365..e449b73ec 100644 --- a/resources/lang/de_informal/editor.php +++ b/resources/lang/de_informal/editor.php @@ -13,7 +13,7 @@ return [ 'cancel' => 'Abbrechen', 'save' => 'Speichern', 'close' => 'Schließen', - 'undo' => 'Rückgängig', + 'undo' => 'Rückgängig machen', 'redo' => 'Wiederholen', 'left' => 'Links', 'center' => 'Zentriert', @@ -32,14 +32,14 @@ return [ 'header_medium' => 'Mittlere Überschrift', 'header_small' => 'Kleine Überschrift', 'header_tiny' => 'Sehr kleine Überschrift', - 'paragraph' => 'Paragraph', + 'paragraph' => 'Absatz', 'blockquote' => 'Blockzitat', 'inline_code' => 'Inline-Code', 'callouts' => 'Anmerkungen', - 'callout_information' => 'Info', - 'callout_success' => 'Erfolgreich', + 'callout_information' => 'Information', + 'callout_success' => 'Erfolg', 'callout_warning' => 'Warnung', - 'callout_danger' => 'Achtung', + 'callout_danger' => 'Gefahr', 'bold' => 'Fett', 'italic' => 'Kursiv', 'underline' => 'Unterstrichen', @@ -87,29 +87,29 @@ return [ 'insert_column_after' => 'Spalte danach einfügen', 'delete_column' => 'Spalte löschen', 'table_cell' => 'Zelle', - 'table_row' => 'Reihe', + 'table_row' => 'Zeile', 'table_column' => 'Spalte', 'cell_properties' => 'Zelleneigenschaften', 'cell_properties_title' => 'Zelleneigenschaften', 'cell_type' => 'Zellentyp', 'cell_type_cell' => 'Zelle', - 'cell_scope' => 'Zellbereich', - 'cell_type_header' => 'Tabellen-Kopfzelle', + 'cell_scope' => 'Bereich', + 'cell_type_header' => 'Überschriftszelle', 'merge_cells' => 'Zellen verbinden', 'split_cell' => 'Zellen teilen', 'table_row_group' => 'Zeilengruppe', 'table_column_group' => 'Spaltengruppe', 'horizontal_align' => 'Horizontal ausrichten', 'vertical_align' => 'Vertikal ausrichten', - 'border_width' => 'Randbreite', - 'border_style' => 'Randstil', - 'border_color' => 'Randfarbe', + 'border_width' => 'Rahmenbreite', + 'border_style' => 'Rahmenstil', + 'border_color' => 'Rahmenfarbe', 'row_properties' => 'Zeileneigenschaften', 'row_properties_title' => 'Zeileneigenschaften', 'cut_row' => 'Zeile ausschneiden', 'copy_row' => 'Zeile kopieren', - 'paste_row_before' => 'Vor der Zeile einfügen', - 'paste_row_after' => 'Nach der Zeile einfügen', + 'paste_row_before' => 'Zeile davor einfügen', + 'paste_row_after' => 'Zeile danach einfügen', 'row_type' => 'Zeilentyp', 'row_type_header' => 'Kopfzeile', 'row_type_body' => 'Hauptteil', @@ -117,8 +117,8 @@ return [ 'alignment' => 'Ausrichtung', 'cut_column' => 'Spalte ausschneiden', 'copy_column' => 'Spalte kopieren', - 'paste_column_before' => 'Vor der Spalte einfügen', - 'paste_column_after' => 'Nach der Spalte einfügen', + 'paste_column_before' => 'Spalte davor einfügen', + 'paste_column_after' => 'Spalte danach einfügen', 'cell_padding' => 'Zellenabstand', 'cell_spacing' => 'Zellen-Außenabstand', 'caption' => 'Beschriftung', @@ -157,7 +157,7 @@ return [ 'about' => 'Über den Editor', 'about_title' => 'Über den WYSIWYG-Editor', 'editor_license' => 'Editorlizenz & Copyright', - 'editor_tiny_license' => 'This editor is built using :tinyLink which is provided under the MIT license.', + 'editor_tiny_license' => 'Dieser Editor wurde mithilfe von :tinyLink erstellt, der unter der MIT-Lizenz bereitgestellt wird.', 'editor_tiny_license_link' => 'Die Copyright- und Lizenzdetails von TinyMCE finden Sie hier.', 'save_continue' => 'Speichern & Fortfahren', 'callouts_cycle' => '(Drücken Sie weiter, um durch Typen umzuschalten)', diff --git a/resources/lang/de_informal/entities.php b/resources/lang/de_informal/entities.php index 991e2b071..40d46a181 100644 --- a/resources/lang/de_informal/entities.php +++ b/resources/lang/de_informal/entities.php @@ -23,8 +23,9 @@ return [ 'meta_updated' => 'Zuletzt aktualisiert: :timeLength', 'meta_updated_name' => 'Zuletzt aktualisiert: :timeLength von :user', 'meta_owned_name' => 'Im Besitz von :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Eintrag auswählen', - 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', + 'entity_select_lack_permission' => 'Du hast nicht die benötigte Berechtigung, um dieses Element auszuwählen', 'images' => 'Bilder', 'my_recent_drafts' => 'Meine kürzlichen Entwürfe', 'my_recently_viewed' => 'Kürzlich von mir angesehen', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Regal', 'shelves' => 'Regale', 'x_shelves' => ':count Regal|:count Regale', - 'shelves_long' => 'Bücherregal', 'shelves_empty' => 'Es wurden noch keine Regale angelegt', 'shelves_create' => 'Erzeuge ein Regal', 'shelves_popular' => 'Beliebte Regale', @@ -88,23 +88,23 @@ return [ 'shelves_save' => 'Regal speichern', 'shelves_books' => 'Bücher in diesem Regal', 'shelves_add_books' => 'Buch zu diesem Regal hinzufügen', - 'shelves_drag_books' => 'Drag books below to add them to this shelf', + 'shelves_drag_books' => 'Ziehen Sie Bücher nach unten, um sie diesem Regal hinzuzufügen', 'shelves_empty_contents' => 'Diesem Regal sind keine Bücher zugewiesen', 'shelves_edit_and_assign' => 'Regal bearbeiten um Bücher hinzuzufügen', - 'shelves_edit_named' => 'Bücherregal :name bearbeiten', - 'shelves_edit' => 'Bücherregal bearbeiten', - 'shelves_delete' => 'Bücherregal löschen', - 'shelves_delete_named' => 'Bücherregal :name löschen', - 'shelves_delete_explain' => "Du bist im Begriff das Bücherregal mit dem Namen ':name' zu löschen. Enthaltene Bücher werden nicht gelöscht.", - 'shelves_delete_confirmation' => 'Bist du sicher, dass du dieses Bücherregal löschen willst?', - 'shelves_permissions' => 'Regal-Berechtigungen', - 'shelves_permissions_updated' => 'Regal-Berechtigungen aktualisiert', - 'shelves_permissions_active' => 'Regal-Berechtigungen aktiv', - 'shelves_permissions_cascade_warning' => 'Die Berechtigungen in Bücherregalen werden nicht automatisch auf enthaltene Bücher kaskadiert, weil ein Buch in mehreren Regalen existieren kann. Berechtigungen können jedoch mit der unten stehenden Option in untergeordnete Bücher kopiert werden.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Kopiere die Berechtigungen zum Buch', 'shelves_copy_permissions' => 'Berechtigungen kopieren', - 'shelves_copy_permissions_explain' => 'Hiermit werden die Berechtigungen des aktuellen Regals auf alle enthaltenen Bücher übertragen. Überprüfe vor der Aktivierung, ob alle Berechtigungsänderungen am aktuellen Regal gespeichert wurden.', - 'shelves_copy_permission_success' => 'Regal-Berechtigungen wurden zu :count Büchern kopiert', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Buch', @@ -145,7 +145,7 @@ return [ 'books_sort_show_other' => 'Andere Bücher anzeigen', 'books_sort_save' => 'Neue Reihenfolge speichern', 'books_copy' => 'Buch kopieren', - 'books_copy_success' => 'Das Buch wurde erfolgreich kopiert', + 'books_copy_success' => 'Buch erfolgreich kopiert', // Chapters 'chapter' => 'Kapitel', @@ -171,7 +171,7 @@ return [ 'chapters_permissions_active' => 'Kapitel-Berechtigungen aktiv', 'chapters_permissions_success' => 'Kapitel-Berechtigungenen aktualisisert', 'chapters_search_this' => 'Dieses Kapitel durchsuchen', - 'chapter_sort_book' => 'Sort Book', + 'chapter_sort_book' => 'Buch sortieren', // Pages 'page' => 'Seite', @@ -201,16 +201,16 @@ return [ 'pages_edit_switch_to_markdown' => 'Zum Markdown Editor wechseln', 'pages_edit_switch_to_markdown_clean' => '(gesäuberter Output)', 'pages_edit_switch_to_markdown_stable' => '(html beibehalten)', - 'pages_edit_switch_to_wysiwyg' => 'Wechseln Sie zum WYSIWYG-Editor', + 'pages_edit_switch_to_wysiwyg' => 'Zum WYSIWYG Editor wechseln', 'pages_edit_set_changelog' => 'Änderungsprotokoll hinzufügen', 'pages_edit_enter_changelog_desc' => 'Bitte gib eine kurze Zusammenfassung Deiner Änderungen ein', 'pages_edit_enter_changelog' => 'Änderungsprotokoll eingeben', 'pages_editor_switch_title' => 'Editor wechseln', - 'pages_editor_switch_are_you_sure' => 'Sind Sie sicher, dass Sie den Editor für diese Seite ändern möchten?', - 'pages_editor_switch_consider_following' => 'Betrachten Sie folgendes beim Ändern von Editoren:', - 'pages_editor_switch_consideration_a' => 'Einmal gespeichert, wird die neue Editoroption von zukünftigen Editoren verwendet, einschließlich derjenigen, die nicht in der Lage sind, den Editortyp selbst zu ändern.', - 'pages_editor_switch_consideration_b' => 'Dies kann unter bestimmten Umständen zu einem Verlust von Details und Quellcode führen.', - 'pages_editor_switch_consideration_c' => 'Änderungen des Tags oder Änderungsprotokolls, die seit dem letzten Speichern vorgenommen wurden, werden bei dieser Änderung nicht fortgesetzt.', + 'pages_editor_switch_are_you_sure' => 'Bist du dir sicher, dass du den Editor für diese Seite ändern willst?', + 'pages_editor_switch_consider_following' => 'Beachte beim Wechsel des Editors Folgendes:', + 'pages_editor_switch_consideration_a' => 'Nach dem Speichern wird der neue Editor von allen zukünftigen Bearbeitern verwendet, auch von denen, die den Editortyp nicht selbst ändern können.', + 'pages_editor_switch_consideration_b' => 'Dies kann unter Umständen zu einem Verlust von Details und Syntax führen.', + 'pages_editor_switch_consideration_c' => 'Tag- oder Changelog-Änderungen, die seit dem letzten Speichern vorgenommen wurden, bleiben bei dieser Änderung nicht erhalten.', 'pages_save' => 'Seite speichern', 'pages_title' => 'Seitentitel', 'pages_name' => 'Seitenname', @@ -237,7 +237,7 @@ return [ 'pages_revisions_number' => '#', 'pages_revisions_numbered' => 'Revision #:id', 'pages_revisions_numbered_changes' => 'Revision #:id Änderungen', - 'pages_revisions_editor' => 'Editor-Typ', + 'pages_revisions_editor' => 'Editortyp', 'pages_revisions_changelog' => 'Änderungsprotokoll', 'pages_revisions_changes' => 'Änderungen', 'pages_revisions_current' => 'Aktuelle Version', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Inhalt bearbeiten', 'pages_permissions_active' => 'Seiten-Berechtigungen aktiv', 'pages_initial_revision' => 'Erste Veröffentlichung', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Neue Seite', 'pages_editing_draft_notification' => 'Du bearbeitest momenten einen Entwurf, der zuletzt :timeDiff gespeichert wurde.', 'pages_draft_edited_notification' => 'Diese Seite wurde seit diesem Zeitpunkt verändert. Wir empfehlen Ihnen, diesen Entwurf zu verwerfen.', @@ -367,6 +368,11 @@ return [ 'convert_undo_warning' => 'Dies kann nicht so einfach rückgängig gemacht werden.', 'convert_to_book' => 'In Buch umwandeln', 'convert_to_book_desc' => 'Sie können dieses Kapitel zu einem neuen Buch mit dem gleichen Inhalt umwandeln. Alle Berechtigungen für dieses Kapitel werden in das neue Buch übernommen, aber alle vom ursprünglichen Buch vererbten Berechtigungen werden nicht übernommen, daher kann es zu Änderungen im Zugriff kommen.', - 'convert_chapter' => 'Kapitel umwandeln', - 'convert_chapter_confirm' => 'Sind Sie sicher, dass Sie dieses Kapitel umwandeln möchten?', + 'convert_chapter' => 'Kapital konvertieren', + 'convert_chapter_confirm' => 'Bist du dir sicher, dass du dieses Kapitel konvertieren möchtest?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/de_informal/errors.php b/resources/lang/de_informal/errors.php index d44b9a65b..b3430b919 100644 --- a/resources/lang/de_informal/errors.php +++ b/resources/lang/de_informal/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Eintrag nicht gefunden', - 'bookshelf_not_found' => 'Regal nicht gefunden', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Buch nicht gefunden', 'page_not_found' => 'Seite nicht gefunden', 'chapter_not_found' => 'Kapitel nicht gefunden', @@ -88,8 +88,8 @@ return [ 'sorry_page_not_found' => 'Entschuldigung. Die Seite, die Du angefordert hast, wurde nicht gefunden.', 'sorry_page_not_found_permission_warning' => 'Wenn du erwartet hast, dass diese Seite existiert, hast du möglicherweise nicht die Berechtigung, sie anzuzeigen.', 'image_not_found' => 'Bild nicht gefunden', - 'image_not_found_subtitle' => 'Entschuldigung. Das angeforderte Bild wurde nicht gefunden.', - 'image_not_found_details' => 'Wenn Sie erwartet haben, dass dieses Bild existiert, könnte es gelöscht worden sein.', + 'image_not_found_subtitle' => 'Sorry. Die Bilddatei, nach der du suchst, konnte nicht gefunden werden.', + 'image_not_found_details' => 'Wenn du erwartet hast, dass dieses Bild existiert, wurde es möglicherweise gelöscht.', 'return_home' => 'Zurück zur Startseite', 'error_occurred' => 'Es ist ein Fehler aufgetreten', 'app_down' => ':appName befindet sich aktuell im Wartungsmodus.', diff --git a/resources/lang/de_informal/settings.php b/resources/lang/de_informal/settings.php index 6cdeaea19..84ae4b0ee 100644 --- a/resources/lang/de_informal/settings.php +++ b/resources/lang/de_informal/settings.php @@ -27,8 +27,8 @@ return [ 'app_secure_images' => 'Erhöhte Sicherheit für hochgeladene Bilder aktivieren?', 'app_secure_images_toggle' => 'Aktiviere Bild-Upload mit höherer Sicherheit', 'app_secure_images_desc' => 'Aus Leistungsgründen sind alle Bilder öffentlich sichtbar. Diese Option fügt zufällige, schwer zu eratene, Zeichenketten zu Bild-URLs hinzu. Stellen sie sicher, dass Verzeichnisindizes deaktiviert sind, um einen einfachen Zugriff zu verhindern.', - 'app_default_editor' => 'Standard-Seiten-Editor', - 'app_default_editor_desc' => 'Wählen Sie aus, welcher Editor standardmäßig beim Bearbeiten neuer Seiten verwendet wird. Dies kann auf einer Seitenebene überschrieben werden, wenn es die Berechtigungen erlauben.', + 'app_default_editor' => 'Standard Seiteneditor', + 'app_default_editor_desc' => 'Wähle aus, welcher Editor bei der Bearbeitung neuer Seiten standardmäßig verwendet werden soll. Dies kann auf Seitenebene außer Kraft gesetzt werden, sofern die Berechtigungen dies zulassen.', 'app_custom_html' => 'Benutzerdefinierter HTML Inhalt', 'app_custom_html_desc' => 'Jeder Inhalt, der hier hinzugefügt wird, wird am Ende der Sektion jeder Seite eingefügt. Diese kann praktisch sein, um CSS Styles anzupassen oder Analytics-Code hinzuzufügen.', 'app_custom_html_disabled_notice' => 'Benutzerdefinierte HTML-Kopfzeileninhalte sind auf dieser Einstellungsseite deaktiviert, um sicherzustellen, dass alle Änderungen rückgängig gemacht werden können.', @@ -92,6 +92,10 @@ Hinweis: Benutzer können ihre E-Mail Adresse nach erfolgreicher Registrierung 'maint_send_test_email_mail_text' => 'Glückwunsch! Da du diese E-Mail Benachrichtigung erhalten hast, scheinen deine E-Mail-Einstellungen korrekt konfiguriert zu sein.', 'maint_recycle_bin_desc' => 'Gelöschte Regale, Bücher, Kapitel & Seiten werden in den Papierkorb verschoben, so dass sie wiederhergestellt oder dauerhaft gelöscht werden können. Ältere Einträge im Papierkorb können, in Abhängigkeit von der Systemkonfiguration, nach einer Weile automatisch entfernt werden.', 'maint_recycle_bin_open' => 'Papierkorb öffnen', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Papierkorb', @@ -155,7 +159,7 @@ Hinweis: Benutzer können ihre E-Mail Adresse nach erfolgreicher Registrierung 'role_access_api' => 'Systemzugriffs-API', 'role_manage_settings' => 'Globaleinstellungen verwalten', 'role_export_content' => 'Inhalt exportieren', - 'role_editor_change' => 'Seiten-Editor ändern', + 'role_editor_change' => 'Seiteneditor ändern', 'role_asset' => 'Berechtigungen', 'roles_system_warning' => 'Beachten Sie, dass der Zugriff auf eine der oben genannten drei Berechtigungen einem Benutzer erlauben kann, seine eigenen Berechtigungen oder die Rechte anderer im System zu ändern. Weisen Sie nur Rollen, mit diesen Berechtigungen, vertrauenswürdigen Benutzern zu.', 'role_asset_desc' => 'Diese Berechtigungen gelten für den Standard-Zugriff innerhalb des Systems. Berechtigungen für Bücher, Kapitel und Seiten überschreiben diese Berechtigungenen.', diff --git a/resources/lang/es/activities.php b/resources/lang/es/activities.php index 8ef584ed2..45dcca97e 100644 --- a/resources/lang/es/activities.php +++ b/resources/lang/es/activities.php @@ -40,7 +40,7 @@ return [ // Bookshelves 'bookshelf_create' => 'estante creado', 'bookshelf_create_notification' => 'Estante creado correctamente', - 'bookshelf_create_from_book' => 'convertido libro a estante', + 'bookshelf_create_from_book' => 'libro convertido a estante', 'bookshelf_create_from_book_notification' => 'Libro convertido a estante con éxito', 'bookshelf_update' => 'estante actualizado', 'bookshelf_update_notification' => 'Estante actualizado correctamente', diff --git a/resources/lang/es/entities.php b/resources/lang/es/entities.php index aec1f331a..d7f9e5c4f 100644 --- a/resources/lang/es/entities.php +++ b/resources/lang/es/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Actualizado :timeLength', 'meta_updated_name' => 'Actualizado :timeLength por :user', 'meta_owned_name' => 'Propiedad de :user', + 'meta_reference_page_count' => 'Referenciado en 1 página|Referenciado en :count páginas', 'entity_select' => 'Seleccione entidad', 'entity_select_lack_permission' => 'No tiene los permisos necesarios para seleccionar este elemento', 'images' => 'Imágenes', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Estante', 'shelves' => 'Estantes', 'x_shelves' => ':count estante|:count estantes', - 'shelves_long' => 'Estantes', 'shelves_empty' => 'No hay estantes creados', 'shelves_create' => 'Crear estante', 'shelves_popular' => 'Estantes populares', @@ -93,17 +93,17 @@ return [ 'shelves_edit_and_assign' => 'Editar el estante para asignar libros', 'shelves_edit_named' => 'Editar estante :name', 'shelves_edit' => 'Editar estante', - 'shelves_delete' => 'Borrar estante', - 'shelves_delete_named' => 'Borrar estante :name', - 'shelves_delete_explain' => "Esto borrará el estante con el nombre ':name'. Los libros que contenga no se borrarán.", + 'shelves_delete' => 'Eliminar estante', + 'shelves_delete_named' => 'Eliminar estante :name', + 'shelves_delete_explain' => "Esto eliminará el estante con el nombre ':name'. Los libros que contenga no se eliminarán.", 'shelves_delete_confirmation' => '¿Está seguro de que desea borrar este estante?', - 'shelves_permissions' => 'Permisos del estante', + 'shelves_permissions' => 'Permisos del Estante', 'shelves_permissions_updated' => 'Permisos del estante actualizados', 'shelves_permissions_active' => 'Permisos del estante activos', - 'shelves_permissions_cascade_warning' => 'Los permisos en los estantes no se aplican automáticamente a los libros contenidos. Esto se debe a que un libro puede existir en múltiples estantes. Sin embargo, los permisos pueden ser aplicados a los libros del estante utilizando la opción a continuación.', + 'shelves_permissions_cascade_warning' => 'Los permisos en los estantes no se aplican automáticamente a los libros que contengan. Esto se debe a que un libro puede existir en múltiples estantes. Sin embargo, los permisos pueden ser aplicados a los libros del estante utilizando la opción a continuación.', 'shelves_copy_permissions_to_books' => 'Copiar permisos a los libros', 'shelves_copy_permissions' => 'Copiar permisos', - '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 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', // Books @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Contenido editado', 'pages_permissions_active' => 'Permisos de página activos', 'pages_initial_revision' => 'Publicación inicial', + 'pages_references_update_revision' => 'Actualización automática de enlaces internos', 'pages_initial_name' => 'Página nueva', 'pages_editing_draft_notification' => 'Está actualmente editando un borrador que fue guardado por última vez el :timeDiff.', 'pages_draft_edited_notification' => 'Esta página ha sido actualizada desde ese momento. Se recomienda que cancele este borrador.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'Puede convertir este capítulo en un nuevo libro con el mismo contenido. Cualquier permiso establecido en este capítulo será copiado al nuevo libro pero cualquier permiso heredado, del libro padre, no se copiará lo que podría conducir a un cambio de control de acceso.', 'convert_chapter' => 'Convertir Capítulo', 'convert_chapter_confirm' => '¿Estás seguro de que quieres convertir este capítulo?', + + // References + 'references' => 'Referencias', + 'references_none' => 'No hay referencias a este elemento.', + 'references_to_desc' => 'A continuación se muestran todas las páginas en el sistema que enlazan a este elemento.', ]; diff --git a/resources/lang/es/settings.php b/resources/lang/es/settings.php index e81e2a1f6..4c12e9636 100644 --- a/resources/lang/es/settings.php +++ b/resources/lang/es/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => '¡Enhorabuena! Al recibir esta notificación de correo electrónico, tu configuración de correo electrónico parece estar ajustada correctamente.', 'maint_recycle_bin_desc' => 'Los estantes, libros, capítulos y páginas eliminados se envían a la papelera de reciclaje para que puedan ser restauradas o eliminadas permanentemente. Los elementos más antiguos en la papelera de reciclaje pueden ser eliminados automáticamente después de un tiempo dependiendo de la configuración del sistema.', 'maint_recycle_bin_open' => 'Abrir papelera de reciclaje', + 'maint_regen_references' => 'Regenerar Referencias', + 'maint_regen_references_desc' => 'Esta acción reconstruirá el índice de referencia de elementos cruzados dentro de la base de datos. Normalmente se gestiona automáticamente, pero esta acción puede ser útil para indexar el contenido antiguo o añadido mediante métodos no oficiales.', + 'maint_regen_references_success' => '¡El índice de referencias ha sido regenerado!', + 'maint_timeout_command_note' => 'Nota: Esta acción puede tardar en ejecutarse, lo que puede llevar a problemas de tiempo de espera en algunos entornos web. Como alternativa, esta acción se puede realizar desde una terminal.', // Recycle Bin 'recycle_bin' => 'Papelera de Reciclaje', diff --git a/resources/lang/es_AR/activities.php b/resources/lang/es_AR/activities.php index 9dd06f7c2..34ea2abbc 100644 --- a/resources/lang/es_AR/activities.php +++ b/resources/lang/es_AR/activities.php @@ -40,11 +40,11 @@ return [ // Bookshelves 'bookshelf_create' => 'estante creado', 'bookshelf_create_notification' => 'Estante creado correctamente', - 'bookshelf_create_from_book' => 'libro convertido en estante', + 'bookshelf_create_from_book' => 'libro convertido a estante', 'bookshelf_create_from_book_notification' => 'Libro convertido en estante con éxito', - 'bookshelf_update' => 'Estante actualizado', + 'bookshelf_update' => 'estante actualizado', 'bookshelf_update_notification' => 'Estante actualizado correctamente', - 'bookshelf_delete' => 'Estante borrado', + 'bookshelf_delete' => 'estante eliminado', 'bookshelf_delete_notification' => 'Estante eliminado correctamente', // Favourites diff --git a/resources/lang/es_AR/entities.php b/resources/lang/es_AR/entities.php index 07149e4b9..d6a1c847e 100644 --- a/resources/lang/es_AR/entities.php +++ b/resources/lang/es_AR/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Actualizado el :timeLength', 'meta_updated_name' => 'Actualizado el :timeLength por :user', 'meta_owned_name' => 'Propiedad de :user', + 'meta_reference_page_count' => 'Referenciado en 1 página|Referenciado en :count páginas', 'entity_select' => 'Seleccione entidad', 'entity_select_lack_permission' => 'No tiene los permisos necesarios para seleccionar este elemento', 'images' => 'Imágenes', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Estante', 'shelves' => 'Estantes', 'x_shelves' => ':count Estante|:count Estantes', - 'shelves_long' => 'Estantes de libros', 'shelves_empty' => 'No se crearon estantes', 'shelves_create' => 'Crear un estante nuevo', 'shelves_popular' => 'Estantes Populares', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Arrastra los libros a continuación para añadirlos a este estante', 'shelves_empty_contents' => 'Este estante no tiene libros asignados a él', 'shelves_edit_and_assign' => 'Editar el estante para asignar libros', - 'shelves_edit_named' => 'Editar Estante :name', - 'shelves_edit' => 'Editar Estante', - 'shelves_delete' => 'Eliminar Estante', - 'shelves_delete_named' => 'Eliminar Estante :name', - 'shelves_delete_explain' => "Esta acción eliminará el estante con el nombre ':name'. Los libros contenidos en él no se eliminarán.", - 'shelves_delete_confirmation' => '¿Está seguro que quiere eliminar este estante?', + 'shelves_edit_named' => 'Editar estante :name', + 'shelves_edit' => 'Editar estante', + 'shelves_delete' => 'Eliminar estante', + 'shelves_delete_named' => 'Eliminar estante :name', + 'shelves_delete_explain' => "Esto eliminará el estante con el nombre ':name'. Los libros que contenga no se eliminarán.", + 'shelves_delete_confirmation' => '¿Está seguro de que desea borrar este estante?', 'shelves_permissions' => 'Permisos del Estante', - 'shelves_permissions_updated' => 'Permisos del Estante actualizados', - 'shelves_permissions_active' => 'Permisos Activos del Estante', - 'shelves_permissions_cascade_warning' => 'Los permisos en los estantes no se aplican automáticamente a los libros contenidos. Esto se debe a que un libro puede existir en múltiples estantes. Sin embargo, los permisos pueden ser aplicados a los libros del estante utilizando la opción a continuación.', + 'shelves_permissions_updated' => 'Permisos del estante actualizados', + 'shelves_permissions_active' => 'Permisos del estante activos', + 'shelves_permissions_cascade_warning' => 'Los permisos en los estantes no se aplican automáticamente a los libros que contengan. Esto se debe a que un libro puede existir en múltiples estantes. Sin embargo, los permisos pueden ser aplicados a los libros del estante utilizando la opción a continuación.', 'shelves_copy_permissions_to_books' => 'Copiar Permisos a los Libros', 'shelves_copy_permissions' => 'Copiar Permisos', - 'shelves_copy_permissions_explain' => 'Esta acción aplicará los permisos de este estante a todos los libros contenidos en él. Antes de activarlos, asegúrese que los cambios a los permisos de este estante estén guardados.', - 'shelves_copy_permission_success' => 'Se copiaron los permisos del estante a :count libros', + 'shelves_copy_permissions_explain' => 'Esto aplicará los 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', // Books 'book' => 'Libro', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Contenido editado', 'pages_permissions_active' => 'Permisos de página activos', 'pages_initial_revision' => 'Publicación inicial', + 'pages_references_update_revision' => 'Actualización automática de enlaces internos', 'pages_initial_name' => 'Página nueva', 'pages_editing_draft_notification' => 'Usted está actualmente editando un borrador que fue guardado por última vez el :timeDiff.', 'pages_draft_edited_notification' => 'Esta página ha sido actualizada desde aquel momento. Se recomienda que cancele este borrador.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'Puede convertir este capítulo en un nuevo libro con el mismo contenido. Cualquier permiso establecido en este capítulo será copiado al nuevo libro pero cualquier permiso heredado, del libro padre, no se copiará lo que podría derivar en un cambio en el control de acceso.', 'convert_chapter' => 'Convertir Capítulo', 'convert_chapter_confirm' => '¿Está seguro de que quiere convertir este capítulo?', + + // References + 'references' => 'Referencias', + 'references_none' => 'No hay referencias a este elemento.', + 'references_to_desc' => 'A continuación se muestran todas las páginas en el sistema que enlazan a este elemento.', ]; diff --git a/resources/lang/es_AR/settings.php b/resources/lang/es_AR/settings.php index 43c080543..6794affe7 100644 --- a/resources/lang/es_AR/settings.php +++ b/resources/lang/es_AR/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => '¡Enhorabuena! Al recibir esta notificación de correo electrónico, tu configuración de correo electrónico parece estar ajustada correctamente.', 'maint_recycle_bin_desc' => 'Los estantes, libros, capítulos y páginas eliminados se envían a la papelera de reciclaje para que puedan ser restauradas o eliminadas permanentemente. Los elementos más antiguos en la papelera de reciclaje pueden ser eliminados automáticamente después de un tiempo dependiendo de la configuración del sistema.', 'maint_recycle_bin_open' => 'Abrir papelera de reciclaje', + 'maint_regen_references' => 'Regenerar Referencias', + 'maint_regen_references_desc' => 'Esta acción reconstruirá el índice de referencia de elementos cruzados dentro de la base de datos. Normalmente se gestiona automáticamente, pero esta acción puede ser útil para indexar el contenido antiguo o añadido mediante métodos no oficiales.', + 'maint_regen_references_success' => '¡El índice de referencias ha sido regenerado!', + 'maint_timeout_command_note' => 'Nota: Esta acción puede tardar en ejecutarse, lo que puede llevar a problemas de tiempo de espera en algunos entornos web. Como alternativa, esta acción se puede realizar desde una terminal.', // Recycle Bin 'recycle_bin' => 'Papelera de Reciclaje', diff --git a/resources/lang/et/activities.php b/resources/lang/et/activities.php index 26e4e5ac0..4523051e6 100644 --- a/resources/lang/et/activities.php +++ b/resources/lang/et/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Raamat on sorteeritud', // Bookshelves - 'bookshelf_create' => 'lisas riiuli', - 'bookshelf_create_notification' => 'Riiul on lisatud', - 'bookshelf_create_from_book' => 'muutis raamatu riiuliks', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Raamat on muudetud riiuliks', - 'bookshelf_update' => 'muutis riiulit', - 'bookshelf_update_notification' => 'Riiul on muudetud', - 'bookshelf_delete' => 'kustutas riiuli', - 'bookshelf_delete_notification' => 'Riiul on kustutatud', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" lisati su lemmikute hulka', diff --git a/resources/lang/et/entities.php b/resources/lang/et/entities.php index 7f74992b3..3ad82f915 100644 --- a/resources/lang/et/entities.php +++ b/resources/lang/et/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Muudetud :timeLength', 'meta_updated_name' => 'Muudetud :timeLength kasutaja :user poolt', 'meta_owned_name' => 'Kuulub kasutajale :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Objekti valik', 'entity_select_lack_permission' => 'Sul pole õiguseid selle objekti valimiseks', 'images' => 'Pildid', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Riiul', 'shelves' => 'Riiulid', 'x_shelves' => ':count riiul|:count riiulit', - 'shelves_long' => 'Raamaturiiulid', 'shelves_empty' => 'Ühtegi riiulit pole lisatud', 'shelves_create' => 'Lisa uus riiul', 'shelves_popular' => 'Populaarsed riiulid', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Lohista raamatuid siia, et neid sellele riiulile lisada', 'shelves_empty_contents' => 'Sellel riiulil ei ole ühtegi raamatut', 'shelves_edit_and_assign' => 'Muuda riiulit, et siia raamatuid lisada', - 'shelves_edit_named' => 'Muuda riiulit :name', - 'shelves_edit' => 'Muuda riiulit', - 'shelves_delete' => 'Kustuta riiul', - 'shelves_delete_named' => 'Kustuta riiul :name', - 'shelves_delete_explain' => "See kustutab riiuli nimega ':name'. Raamatuid, mis on sellel riiulil, ei kustutata.", - 'shelves_delete_confirmation' => 'Kas oled kindel, et soovid selle raamaturiiuli kustutada?', - 'shelves_permissions' => 'Riiuli õigused', - 'shelves_permissions_updated' => 'Riiuli õigused muudetud', - 'shelves_permissions_active' => 'Riiuli õigused on aktiivsed', - 'shelves_permissions_cascade_warning' => 'Raamaturiiuli õigused ei rakendu automaatselt sellel olevatele raamatutele, kuna raamat võib olla korraga mitmel riiulil. Alloleva valiku abil saab aga riiuli õigused kopeerida raamatutele.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Kopeeri õigused raamatutele', 'shelves_copy_permissions' => 'Kopeeri õigused', - 'shelves_copy_permissions_explain' => 'See rakendab raamaturiiuli praegused õigused kõigile sellel olevatele raamatutele. Enne jätkamist veendu, et raamaturiiuli õiguste muudatused oleks salvestatud.', - 'shelves_copy_permission_success' => 'Raamaturiiuli õigused kopeeritud :count raamatule', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Raamat', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Muuda sisu', 'pages_permissions_active' => 'Lehe õigused on aktiivsed', 'pages_initial_revision' => 'Esimene redaktsioon', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Uus leht', 'pages_editing_draft_notification' => 'Sa muudad mustandit, mis salvestati viimati :timeDiff.', 'pages_draft_edited_notification' => 'Seda lehte on sellest ajast saadid uuendatud. Soovitame mustandist loobuda.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'Saad muuta selle peatüki uueks, sama sisuga raamatuks. Peatükile määratud õigused kopeeritakse uuele raamatule, aga olemasolevalt raamatult pärit õiguseid ei kopeerita, mis võib põhjustada muudatusi ligipääsudes.', 'convert_chapter' => 'Muud peatükk', 'convert_chapter_confirm' => 'Kas oled kindel, et soovid selle peatüki muuta?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/et/errors.php b/resources/lang/et/errors.php index b61dbb16c..42d23e783 100644 --- a/resources/lang/et/errors.php +++ b/resources/lang/et/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Objekti ei leitud', - 'bookshelf_not_found' => 'Riiulit ei leitud', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Raamatut ei leitud', 'page_not_found' => 'Lehte ei leitud', 'chapter_not_found' => 'Peatükki ei leitud', diff --git a/resources/lang/et/settings.php b/resources/lang/et/settings.php index 7014ef145..e74f1e35a 100644 --- a/resources/lang/et/settings.php +++ b/resources/lang/et/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Hea töö! Kui sa selle e-kirja kätte said, on su e-posti seaded õigesti määratud.', 'maint_recycle_bin_desc' => 'Kustutatud riiulid, raamatud, peatükid ja lehed saadetakse prügikasti, et neid saaks taastada või lõplikult kustutada. Vanemad objektid võidakse teatud aja järel automaatselt prügikastist kustutada.', 'maint_recycle_bin_open' => 'Ava prügikast', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Prügikast', diff --git a/resources/lang/eu/activities.php b/resources/lang/eu/activities.php index 3f1676a9e..716fe63e3 100644 --- a/resources/lang/eu/activities.php +++ b/resources/lang/eu/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Liburua ongi bersailaktu da', // Bookshelves - 'bookshelf_create' => 'apalategia sortuta', - 'bookshelf_create_notification' => 'Apalategia egoki sortuta', - 'bookshelf_create_from_book' => 'converted book to bookshelf', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf', - 'bookshelf_update' => 'apalategia eguneratuta', - 'bookshelf_update_notification' => 'Apalategia egoki eguneratuta', - 'bookshelf_delete' => 'apalategia ezabatua', - 'bookshelf_delete_notification' => 'Apalategia egoki ezabatua', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" zure gogoetara gehitua izan da', diff --git a/resources/lang/eu/entities.php b/resources/lang/eu/entities.php index 5000050ee..0ec16d947 100644 --- a/resources/lang/eu/entities.php +++ b/resources/lang/eu/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Aldatua :timeLength', 'meta_updated_name' => ':timeLength aldatuta. Erabiltzailea :user', 'meta_owned_name' => ':user da jabea', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Aukeratutako entitatea', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Irudiak', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Apalategia', 'shelves' => 'Apalategiak', 'x_shelves' => ':count Apalategi|:count Apalategi', - 'shelves_long' => 'Liburu-Apalategi', 'shelves_empty' => 'Ez da inolako apalategirik sortu', 'shelves_create' => 'Apalategi berria sortu', 'shelves_popular' => 'Apalategi esanguratsuak', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'Apalategi honek ez dauka libururik', 'shelves_edit_and_assign' => 'Apalategia editatu liburuak gehitzeko', - 'shelves_edit_named' => ':name liburu-apalategia editatu', - 'shelves_edit' => 'Liburu-apalategia editatu', - 'shelves_delete' => 'Apalategia ezabatu', - 'shelves_delete_named' => ':name apalategia ezabatu', - 'shelves_delete_explain' => "':name' apalategia ezabatuko du ekintza honek. bertan dauden liburuak ez dira ezabatuko.", - 'shelves_delete_confirmation' => 'Ziur zaude apalategi hau ezabatu nahi duzula?', - 'shelves_permissions' => 'Apalategi baimenak', - 'shelves_permissions_updated' => 'Apalategi baimenak eguneratuta', - 'shelves_permissions_active' => 'Apalategi baimenak aktibatuta', - 'shelves_permissions_cascade_warning' => 'Permissions on bookshelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Kopiatu baimenak liburura', 'shelves_copy_permissions' => 'Gorde baimenak', - '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' => 'Apalategi baimenak :count liburutan kopiatuta', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Liburua', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Editatu edukia', 'pages_permissions_active' => 'Page Permissions Active', 'pages_initial_revision' => 'Initial publish', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Orrialde berria', 'pages_editing_draft_notification' => 'You are currently editing a draft that was last saved :timeDiff.', 'pages_draft_edited_notification' => 'This page has been updated by since that time. It is recommended that you discard this draft.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/eu/errors.php b/resources/lang/eu/errors.php index bd25e49d5..fd6807b07 100644 --- a/resources/lang/eu/errors.php +++ b/resources/lang/eu/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Entity not found', - 'bookshelf_not_found' => 'Bookshelf not found', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Book not found', 'page_not_found' => 'Page not found', 'chapter_not_found' => 'Chapter not found', diff --git a/resources/lang/eu/settings.php b/resources/lang/eu/settings.php index 8ac7b0e86..0c6c93b4e 100644 --- a/resources/lang/eu/settings.php +++ b/resources/lang/eu/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Congratulations! As you received this email notification, your email settings seem to be configured properly.', 'maint_recycle_bin_desc' => 'Deleted shelves, books, chapters & pages are sent to the recycle bin so they can be restored or permanently deleted. Older items in the recycle bin may be automatically removed after a while depending on system configuration.', 'maint_recycle_bin_open' => 'Ireki zakarrontzia', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Zakarrontzia', diff --git a/resources/lang/fa/activities.php b/resources/lang/fa/activities.php index 4ddf92b28..0626eb903 100644 --- a/resources/lang/fa/activities.php +++ b/resources/lang/fa/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'کتاب با موفقیت مرتب سازی شد', // Bookshelves - 'bookshelf_create' => 'ایجاد قفسه کتاب', - 'bookshelf_create_notification' => 'قفسه کتاب با موفقیت ایجاد شد', - 'bookshelf_create_from_book' => 'تبدیل کتاب به قفسه', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'کتاب با موفقیت به یک قفسه تبدیل شد', - 'bookshelf_update' => 'به روزرسانی قفسه کتاب', - 'bookshelf_update_notification' => 'قفسه کتاب با موفقیت به روزرسانی شد', - 'bookshelf_delete' => 'حذف قفسه کتاب', - 'bookshelf_delete_notification' => 'قفسه کتاب با موفقیت حذف شد', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" به علاقه مندی های شما اضافه شد', diff --git a/resources/lang/fa/entities.php b/resources/lang/fa/entities.php index 058c02eff..91de561b4 100644 --- a/resources/lang/fa/entities.php +++ b/resources/lang/fa/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'به روزرسانی شده :timeLength', 'meta_updated_name' => 'به روزرسانی شده :timeLength توسط :user', 'meta_owned_name' => 'توسط :user ایجاد شده‌است', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'انتخاب موجودیت', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'عکس ها', @@ -77,7 +78,6 @@ return [ 'shelf' => 'تاقچه', 'shelves' => 'قفسه ها', 'x_shelves' => ':count تاقچه|:count تاقچه', - 'shelves_long' => 'قفسه کتاب', 'shelves_empty' => 'هیچ قفسه ای ایجاد نشده است', 'shelves_create' => 'ایجاد قفسه جدید', 'shelves_popular' => 'قفسه های محبوب', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'این قفسه هیچ کتابی به آن اختصاص داده نشده است', 'shelves_edit_and_assign' => 'برای اختصاص کتاب‌ها، قفسه را ویرایش کنید', - 'shelves_edit_named' => 'ویرایش قفسه کتاب :name', - 'shelves_edit' => 'ویرایش قفسه کتاب', - 'shelves_delete' => 'حذف قفسه کتاب', - 'shelves_delete_named' => 'حذف قفسه کتاب :name', - 'shelves_delete_explain' => "با این کار قفسه کتاب با نام ':name' حذف می شود. کتاب های موجود حذف نمی شوند.", - 'shelves_delete_confirmation' => 'آیا مطمئنید که می خواهید این قفسه کتاب را حذف کنید؟', - 'shelves_permissions' => 'مجوزهای قفسه کتاب', - 'shelves_permissions_updated' => 'مجوزهای قفسه کتاب به روز شد', - 'shelves_permissions_active' => 'مجوزهای قفسه کتاب فعال است', - 'shelves_permissions_cascade_warning' => 'مجوزهای موجود در قفسه‌های کتاب به طور خودکار به کتاب‌های حاوی آبشار نمی‌شوند. این به این دلیل است که یک کتاب می تواند در چندین قفسه وجود داشته باشد. با این حال، مجوزها را می‌توان با استفاده از گزینه زیر در کتاب‌های کودک کپی کرد.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'کپی مجوزها در کتابها', 'shelves_copy_permissions' => 'مجوزهای کپی', - 'shelves_copy_permissions_explain' => 'با این کار تنظیمات مجوز فعلی این قفسه کتاب برای همه کتاب‌های موجود در آن اعمال می‌شود. قبل از فعال کردن، مطمئن شوید که هر گونه تغییر در مجوزهای این قفسه کتاب ذخیره شده است.', - 'shelves_copy_permission_success' => 'مجوزهای قفسه کتاب در :count کتاب کپی شد', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'کتاب', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'ویرایش محتوا', 'pages_permissions_active' => 'مجوزهای صفحه فعال است', 'pages_initial_revision' => 'انتشار اولیه', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'برگهٔ تازه', 'pages_editing_draft_notification' => 'شما در حال ویرایش پیش نویسی هستید که آخرین بار در :timeDiff ذخیره شده است.', 'pages_draft_edited_notification' => 'این صفحه از همان زمان به روز شده است. توصیه می شود از این پیش نویس صرف نظر کنید.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'می توانید این فصل را به یک کتاب جدید با همین مطالب تبدیل کنید. هر مجوزی که در این فصل تنظیم شده است در کتاب جدید کپی می شود، اما هر گونه مجوز ارثی، از کتاب والد، کپی نمی شود که می تواند منجر به تغییر کنترل دسترسی شود.', 'convert_chapter' => 'تبدیل فصل', 'convert_chapter_confirm' => 'آیا از تبدیل این فصل مطمئن هستید؟', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/fa/errors.php b/resources/lang/fa/errors.php index 9f3b14b9a..21f8d2c12 100644 --- a/resources/lang/fa/errors.php +++ b/resources/lang/fa/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'موجودیت یافت نشد', - 'bookshelf_not_found' => 'قفسه کتاب پیدا نشد', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'کتاب پیدا نشد', 'page_not_found' => 'صفحه یافت نشد', 'chapter_not_found' => 'فصل پیدا نشد', diff --git a/resources/lang/fa/settings.php b/resources/lang/fa/settings.php index a74e8ab0f..36079ab72 100644 --- a/resources/lang/fa/settings.php +++ b/resources/lang/fa/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'تبریک می گویم! با دریافت این اعلان ایمیل، به نظر می رسد تنظیمات ایمیل شما به درستی پیکربندی شده است.', 'maint_recycle_bin_desc' => 'قفسه‌ها، کتاب‌ها، فصل‌ها و صفحات حذف‌شده به سطل بازیافت فرستاده می‌شوند تا بتوان آن‌ها را بازیابی کرد یا برای همیشه حذف کرد. بسته به پیکربندی سیستم، اقلام قدیمی در سطل بازیافت ممکن است پس از مدتی به طور خودکار حذف شوند.', 'maint_recycle_bin_open' => 'سطل بازیافت را باز کنید', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'سطل زباله', diff --git a/resources/lang/fa/validation.php b/resources/lang/fa/validation.php index f1ca7d0c1..467c68702 100644 --- a/resources/lang/fa/validation.php +++ b/resources/lang/fa/validation.php @@ -31,7 +31,7 @@ return [ 'digits' => ':attribute باید :digits رقم باشد.', 'digits_between' => ':attribute باید بین :min و :max رقم باشد.', 'email' => ':attribute باید یک ایمیل معتبر باشد.', - 'ends_with' => ':attribute باید با یکی از مقادیر زیر خاتمه یابد: :values', + 'ends_with' => ':attribute باید با یکی از مقادیر زیر خاتمه یابد: :values', 'file' => ':attribute باید به عنوان یک فایل معتبر شناخته شود.', 'filled' => ':attribute باید مقدار داشته باشد.', 'gt' => [ diff --git a/resources/lang/fr/activities.php b/resources/lang/fr/activities.php index dee646054..ab115bc8d 100644 --- a/resources/lang/fr/activities.php +++ b/resources/lang/fr/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Livre restauré avec succès', // Bookshelves - 'bookshelf_create' => 'a créé l\'étagère', - 'bookshelf_create_notification' => 'Étagère créée avec succès', - 'bookshelf_create_from_book' => 'livre converti en étagère', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Livre converti en étagère avec succès', - 'bookshelf_update' => 'a modifié l\'étagère', - 'bookshelf_update_notification' => 'Étagère modifiée avec succès', - 'bookshelf_delete' => 'a supprimé l\'étagère', - 'bookshelf_delete_notification' => 'Étagère supprimée avec succès', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" a été ajouté dans vos favoris', diff --git a/resources/lang/fr/entities.php b/resources/lang/fr/entities.php index e3df5e533..6afd0e458 100644 --- a/resources/lang/fr/entities.php +++ b/resources/lang/fr/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Mis à jour :timeLength', 'meta_updated_name' => 'Mis à jour :timeLength par :user', 'meta_owned_name' => 'Appartient à :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Sélectionner l\'entité', 'entity_select_lack_permission' => 'Vous n\'avez pas les permissions requises pour sélectionner cet élément', 'images' => 'Images', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Étagère', 'shelves' => 'Étagères', 'x_shelves' => ':count Étagère|:count Étagères', - 'shelves_long' => 'Étagères', 'shelves_empty' => 'Aucune étagère n\'a été créée', 'shelves_create' => 'Créer une nouvelle étagère', 'shelves_popular' => 'Étagères populaires', @@ -88,23 +88,23 @@ return [ 'shelves_save' => 'Enregistrer l\'étagère', 'shelves_books' => 'Livres sur cette étagère', 'shelves_add_books' => 'Ajouter des livres sur cette étagère', - 'shelves_drag_books' => 'Drag books below to add them to this shelf', + 'shelves_drag_books' => 'Déposez des livres ici pour les ajouter a cette étagère', 'shelves_empty_contents' => 'Aucun livre n\'a été assigné à cette étagère', 'shelves_edit_and_assign' => 'Modifier cette étagère pour y ajouter des livres', - 'shelves_edit_named' => 'Modifier l\'étagère :name', - 'shelves_edit' => 'Modifier l\'étagère', - 'shelves_delete' => 'Supprimer l\'étagère', - 'shelves_delete_named' => 'Supprimer l\'étagère :name', - 'shelves_delete_explain' => "Ceci va supprimer l'étagère nommée ':name'. Les livres contenus dans cette étagère ne seront pas supprimés.", - 'shelves_delete_confirmation' => 'Êtes-vous sûr(e) de vouloir supprimer cette étagère ?', - 'shelves_permissions' => 'Permissions de l\'étagère', - 'shelves_permissions_updated' => 'Permissions de l\'étagère mises à jour', - 'shelves_permissions_active' => 'Permissions de l\'étagère activées', - 'shelves_permissions_cascade_warning' => 'Les permissions sur les étagères ne sont pas automatiquement recopiées aux livres qu\'elles contiennent, car un livre peut exister dans plusieurs étagères. Les permissions peuvent cependant être recopiées vers les livres contenus en utilisant l\'option ci-dessous.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Copier les permissions vers les livres', 'shelves_copy_permissions' => 'Copier les permissions', - 'shelves_copy_permissions_explain' => 'Ceci va appliquer les permissions actuelles de cette étagère à tous les livres qu\'elle contient. Avant de continuer, assurez-vous que toutes les permissions de cette étagère ont été sauvegardées.', - 'shelves_copy_permission_success' => 'Permissions de l\'étagère transférées à :count livres', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Livre', @@ -171,7 +171,7 @@ return [ 'chapters_permissions_active' => 'Permissions du chapitre activées', 'chapters_permissions_success' => 'Permissions du chapitre mises à jour', 'chapters_search_this' => 'Rechercher dans ce chapitre', - 'chapter_sort_book' => 'Sort Book', + 'chapter_sort_book' => 'Trier le livre', // Pages 'page' => 'Page', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Modifier le contenu', 'pages_permissions_active' => 'Permissions de page actives', 'pages_initial_revision' => 'Publication initiale', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Nouvelle page', 'pages_editing_draft_notification' => 'Vous éditez actuellement un brouillon qui a été enregistré :timeDiff.', 'pages_draft_edited_notification' => 'La page a été mise à jour depuis votre dernière visite. Vous devriez jeter ce brouillon.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'Vous pouvez convertir ce chapitre en un nouveau livre avec le même contenu. Toutes les permissions définies dans ce chapitre seront copiées dans le nouveau livre mais toutes les permissions héritées du livre parent ne seront pas copiés, ce qui pourrait conduire à un changement de contrôle d\'accès.', 'convert_chapter' => 'Convertir le chapitre', 'convert_chapter_confirm' => 'Êtes-vous sûr(e) de vouloir convertir ce chapitre ?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/fr/errors.php b/resources/lang/fr/errors.php index 41cf1e148..392ba3305 100644 --- a/resources/lang/fr/errors.php +++ b/resources/lang/fr/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Entité non trouvée', - 'bookshelf_not_found' => 'Étagère non trouvée', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Livre non trouvé', 'page_not_found' => 'Page non trouvée', 'chapter_not_found' => 'Chapitre non trouvé', diff --git a/resources/lang/fr/settings.php b/resources/lang/fr/settings.php index ffa577c1e..2afae373e 100644 --- a/resources/lang/fr/settings.php +++ b/resources/lang/fr/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Félicitations ! Comme vous avez bien reçu cette notification, vos paramètres d\'e-mail semblent être configurés correctement.', 'maint_recycle_bin_desc' => 'Les étagères, livres, chapitres et pages supprimés sont envoyés dans la corbeille afin qu\'ils puissent être restaurés ou supprimés définitivement. Les éléments plus anciens de la corbeille peuvent être supprimés automatiquement après un certain temps selon la configuration du système.', 'maint_recycle_bin_open' => 'Ouvrir la corbeille', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Corbeille', diff --git a/resources/lang/he/activities.php b/resources/lang/he/activities.php index 4df8a9817..45f65aec5 100644 --- a/resources/lang/he/activities.php +++ b/resources/lang/he/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Book successfully re-sorted', // Bookshelves - 'bookshelf_create' => 'created bookshelf', - 'bookshelf_create_notification' => 'Bookshelf successfully created', - 'bookshelf_create_from_book' => 'converted book to bookshelf', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf', - 'bookshelf_update' => 'updated bookshelf', - 'bookshelf_update_notification' => 'Bookshelf successfully updated', - 'bookshelf_delete' => 'deleted bookshelf', - 'bookshelf_delete_notification' => 'Bookshelf successfully deleted', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" has been added to your favourites', diff --git a/resources/lang/he/entities.php b/resources/lang/he/entities.php index 768bff504..1e073b1e4 100644 --- a/resources/lang/he/entities.php +++ b/resources/lang/he/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'עודכן :timeLength', 'meta_updated_name' => 'עודכן :timeLength על ידי :user', 'meta_owned_name' => 'Owned by :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'בחר יישות', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'תמונות', @@ -77,7 +78,6 @@ return [ 'shelf' => 'מדף', 'shelves' => 'מדפים', 'x_shelves' => ':count מדף|:count מדפים', - 'shelves_long' => 'מדפים', 'shelves_empty' => 'לא נוצרו מדפים', 'shelves_create' => 'צור מדף חדש', 'shelves_popular' => 'מדפים פופולרים', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'במדף זה לא קיימים ספרים', 'shelves_edit_and_assign' => 'עריכת מדף להוספת ספרים', - 'shelves_edit_named' => 'עריכת מדף :name', - 'shelves_edit' => 'ערוך מדף', - 'shelves_delete' => 'מחק מדף', - 'shelves_delete_named' => 'מחיקת דף :name', - 'shelves_delete_explain' => "פעולה זו תמחק את המדף :name - הספרים שמופיעים בו ימחקו גם כן!", - 'shelves_delete_confirmation' => 'האם ברצונך למחוק את המדף?', - 'shelves_permissions' => 'הרשאות מדף', - 'shelves_permissions_updated' => 'הרשאות מדף עודכנו', - 'shelves_permissions_active' => 'הרשאות מדף פעילות', - 'shelves_permissions_cascade_warning' => 'Permissions on bookshelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'העתק הרשאות מדף אל הספרים', 'shelves_copy_permissions' => 'העתק הרשאות', - 'shelves_copy_permissions_explain' => 'פעולה זו תעתיק את כל הרשאות המדף לכל הספרים המשוייכים למדף זה. לפני הביצוע, יש לוודא שכל הרשאות המדף אכן נשמרו.', - 'shelves_copy_permission_success' => 'הרשאות המדף הועתקו אל :count ספרים', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'ספר', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'ערוך תוכן', 'pages_permissions_active' => 'הרשאות דף פעילות', 'pages_initial_revision' => 'פרסום ראשוני', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'דף חדש', 'pages_editing_draft_notification' => 'הינך עורך טיוטה אשר נשמרה לאחרונה ב :timeDiff', 'pages_draft_edited_notification' => 'דף זה עודכן מאז, מומלץ להתעלם מהטיוטה הזו.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/he/errors.php b/resources/lang/he/errors.php index b736c83cd..2294052bc 100644 --- a/resources/lang/he/errors.php +++ b/resources/lang/he/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'פריט לא נמצא', - 'bookshelf_not_found' => 'מדף הספרים לא נמצא', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'ספר לא נמצא', 'page_not_found' => 'דף לא נמצא', 'chapter_not_found' => 'פרק לא נמצא', diff --git a/resources/lang/he/settings.php b/resources/lang/he/settings.php index 6dddc5a00..ddf087bdc 100755 --- a/resources/lang/he/settings.php +++ b/resources/lang/he/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'ברכות! מאחר וקיבלת התראת דוא"ל זו, נראה שהגדרות הדוא"ל שלך הוגדרו כמו שצריך.', 'maint_recycle_bin_desc' => 'מדפים, ספרים, פרקים חדשים שנמחקו נשלחים לסל המיחזור, כדי שתוכלו לאחזר אותם או למחוק אותם לצמיתות. ייתכן שפריטים ישנים יותר בסל המיחזור יימחקו באופן אוטומטי לאחר זמן-מה, בהסתמך על הגדרות המערכת.', 'maint_recycle_bin_open' => 'פתח את סל המיחזור', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'סל המיחזור', diff --git a/resources/lang/hr/activities.php b/resources/lang/hr/activities.php index b8dd50a13..3af21813e 100644 --- a/resources/lang/hr/activities.php +++ b/resources/lang/hr/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Knjiga je uspješno razvrstana', // Bookshelves - 'bookshelf_create' => 'stvorena polica za knjige', - 'bookshelf_create_notification' => 'Polica za knjige je uspješno stvorena', - 'bookshelf_create_from_book' => 'prebaci knjigu na policu', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Poglavlje je uspješno pretvoreno u knjigu', - 'bookshelf_update' => 'ažurirana polica za knjige', - 'bookshelf_update_notification' => 'Polica za knjige je uspješno ažurirana', - 'bookshelf_delete' => 'izbrisana polica za knjige', - 'bookshelf_delete_notification' => 'Polica za knjige je uspješno izbrisana', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '".ime" će biti dodano u tvoje favorite', diff --git a/resources/lang/hr/entities.php b/resources/lang/hr/entities.php index 5f49200aa..db7eb45d3 100644 --- a/resources/lang/hr/entities.php +++ b/resources/lang/hr/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Ažurirano :timeLength', 'meta_updated_name' => 'Ažurirano :timeLength od :user', 'meta_owned_name' => 'Vlasništvo :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Odaberi subjekt', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Slike', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Polica', 'shelves' => 'Police', 'x_shelves' => ':count polica|:count polica', - 'shelves_long' => 'Police za knjige', 'shelves_empty' => 'Nijedna polica nije stvorena', 'shelves_create' => 'Stvori novu policu', 'shelves_popular' => 'Popularne police', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'Ova polica još nema dodijeljene knjige', 'shelves_edit_and_assign' => 'Uredi policu za dodavanje knjiga', - 'shelves_edit_named' => 'Uredi policu :name', - 'shelves_edit' => 'Uredi policu', - 'shelves_delete' => 'Izbriši policu', - 'shelves_delete_named' => 'Izbriši policu :name', - 'shelves_delete_explain' => "This will delete the bookshelf with the name ':name'. Contained books will not be deleted.", - 'shelves_delete_confirmation' => 'Jeste li sigurni da želite obrisati policu?', - 'shelves_permissions' => 'Dopuštenja za policu', - 'shelves_permissions_updated' => 'Ažurirana dopuštenja za policu', - 'shelves_permissions_active' => 'Aktivirana dopuštenja za policu', - 'shelves_permissions_cascade_warning' => 'Permissions on bookshelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Kopiraj dopuštenja za knjige', 'shelves_copy_permissions' => 'Kopiraj dopuštenja', - 'shelves_copy_permissions_explain' => 'Ovo će promijeniti trenutna dopuštenja za policu i knjige u njoj. Prije aktivacije provjerite jesu li sve dopuštenja za ovu policu spremljena.', - 'shelves_copy_permission_success' => 'Dopuštenja za policu kopirana za :count knjiga', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Knjiga', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Uredi sadržaj', 'pages_permissions_active' => 'Aktivna dopuštenja stranice', 'pages_initial_revision' => 'Početno objavljivanje', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Nova stranica', 'pages_editing_draft_notification' => 'Uređujete nacrt stranice posljednji put spremljen :timeDiff.', 'pages_draft_edited_notification' => 'Ova je stranica u međuvremenu ažurirana. Preporučujemo da odbacite ovaj nacrt.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/hr/errors.php b/resources/lang/hr/errors.php index 1022ca495..81fadbb50 100644 --- a/resources/lang/hr/errors.php +++ b/resources/lang/hr/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Nije pronađeno', - 'bookshelf_not_found' => 'Polica nije pronađena', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Knjiga nije pronađena', 'page_not_found' => 'Stranica nije pronađena', 'chapter_not_found' => 'Poglavlje nije pronađeno', diff --git a/resources/lang/hr/settings.php b/resources/lang/hr/settings.php index db5ad5404..d865488e8 100644 --- a/resources/lang/hr/settings.php +++ b/resources/lang/hr/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Čestitamo! Ako ste primili ovaj e mail znači da ćete ga moći koristiti.', 'maint_recycle_bin_desc' => 'Izbrisane police, knjige, poglavlja i stranice poslane su u Recycle bin i mogu biti vraćene ili trajno izbrisane. Starije stavke bit će automatski izbrisane nakon nekog vremena što ovisi o konfiguraciji sustava.', 'maint_recycle_bin_open' => 'Otvori Recycle Bin', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Recycle Bin', diff --git a/resources/lang/hu/activities.php b/resources/lang/hu/activities.php index 72e9ad078..2968fb92f 100644 --- a/resources/lang/hu/activities.php +++ b/resources/lang/hu/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Könyv sikeresen újrarendezve', // Bookshelves - 'bookshelf_create' => 'created bookshelf', - 'bookshelf_create_notification' => 'Könyvespolc sikeresen létrehozva', - 'bookshelf_create_from_book' => 'converted book to bookshelf', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf', - 'bookshelf_update' => 'frissítette a könyvespolcot:', - 'bookshelf_update_notification' => 'Könyvespolc sikeresen frissítve', - 'bookshelf_delete' => 'törölte a könyvespolcot:', - 'bookshelf_delete_notification' => 'Könyvespolc sikeresen törölve', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" has been added to your favourites', diff --git a/resources/lang/hu/entities.php b/resources/lang/hu/entities.php index 66f963aa1..22e4e54c8 100644 --- a/resources/lang/hu/entities.php +++ b/resources/lang/hu/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Frissítve :timeLength', 'meta_updated_name' => ':user frissítette :timeLength', 'meta_owned_name' => ':user tulajdona', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Entitás kiválasztása', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Képek', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Polc', 'shelves' => 'Polcok', 'x_shelves' => ':count polc|:count polcok', - 'shelves_long' => 'Könyvespolcok', 'shelves_empty' => 'Nincsenek könyvespolcok létrehozva', 'shelves_create' => 'Új polc létrehozása', 'shelves_popular' => 'Népszerű polcok', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'Ehhez a polchoz nincsenek könyvek rendelve', 'shelves_edit_and_assign' => 'Polc szerkesztése könyvek hozzárendeléséhez', - 'shelves_edit_named' => ':name könyvespolc szerkesztése', - 'shelves_edit' => 'Könyvespolc szerkesztése', - 'shelves_delete' => 'Könyvespolc törlése', - 'shelves_delete_named' => ':name könyvespolc törlése', - 'shelves_delete_explain' => "':name'. nevű könyvespolc ezzel le lesz törölve. A benne található könyvek nem lesznek törölve.", - 'shelves_delete_confirmation' => 'Biztosan törölhető ez a könyvespolc?', - 'shelves_permissions' => 'Könyvespolc jogosultság', - 'shelves_permissions_updated' => 'Könyvespolc jogosultságok frissítve', - 'shelves_permissions_active' => 'Könyvespolc jogosultságok aktívak', - 'shelves_permissions_cascade_warning' => 'Permissions on bookshelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Jogosultság másolása könyvekre', 'shelves_copy_permissions' => 'Jogosultság másolása', - 'shelves_copy_permissions_explain' => 'Ez alkalmazni fogja ennek a könyvespolcnak az aktuális jogosultság beállításait az összes benne található könyvön. Aktiválás előtt ellenőrizni kell, hogy a könyvespolc jogosultságain végzett összes módosítás el lett mentve.', - 'shelves_copy_permission_success' => 'Könyvespolc jogosultságok átmásolva :count könyvre', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Könyv', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Tartalom szerkesztése', 'pages_permissions_active' => 'Oldal jogosultságok aktívak', 'pages_initial_revision' => 'Kezdeti közzététel', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Új oldal', 'pages_editing_draft_notification' => 'A jelenleg szerkesztett vázlat legutóbb ekkor volt elmentve: :timeDiff.', 'pages_draft_edited_notification' => 'Ezt az oldalt azóta már frissítették. Javasolt ennek a vázlatnak az elvetése.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/hu/errors.php b/resources/lang/hu/errors.php index 922f465d1..ec84daefd 100644 --- a/resources/lang/hu/errors.php +++ b/resources/lang/hu/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Entitás nem található', - 'bookshelf_not_found' => 'Könyvespolc nem található', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Könyv nem található', 'page_not_found' => 'Oldal nem található', 'chapter_not_found' => 'Fejezet nem található', diff --git a/resources/lang/hu/settings.php b/resources/lang/hu/settings.php index e52fe17c4..876cfdc23 100644 --- a/resources/lang/hu/settings.php +++ b/resources/lang/hu/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Gratulálunk! Mivel ez az email figyelmeztetés megérkezett az email beállítások megfelelőek.', 'maint_recycle_bin_desc' => 'Deleted shelves, books, chapters & pages are sent to the recycle bin so they can be restored or permanently deleted. Older items in the recycle bin may be automatically removed after a while depending on system configuration.', 'maint_recycle_bin_open' => 'Lomtár megnyitása', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Lomtár', diff --git a/resources/lang/id/activities.php b/resources/lang/id/activities.php index 3ea6da17c..253824eb4 100644 --- a/resources/lang/id/activities.php +++ b/resources/lang/id/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Book successfully re-sorted', // Bookshelves - 'bookshelf_create' => 'created bookshelf', - 'bookshelf_create_notification' => 'Bookshelf successfully created', - 'bookshelf_create_from_book' => 'converted book to bookshelf', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf', - 'bookshelf_update' => 'update rak', - 'bookshelf_update_notification' => 'Bookshelf successfully updated', - 'bookshelf_delete' => 'hapus rak buku', - 'bookshelf_delete_notification' => 'Bookshelf successfully deleted', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" telah ditambahkan ke favorit Anda', diff --git a/resources/lang/id/entities.php b/resources/lang/id/entities.php index e3bfbd9de..9c52ddcd8 100644 --- a/resources/lang/id/entities.php +++ b/resources/lang/id/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Diperbaharui :timeLength', 'meta_updated_name' => 'Diperbaharui :timeLength oleh :user', 'meta_owned_name' => 'Dimiliki oleh :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Pilihan Entitas', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Gambar-gambar', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Rak', 'shelves' => 'Rak', 'x_shelves' => ':count Rak|:count Rak', - 'shelves_long' => 'Rak Buku', 'shelves_empty' => 'Tidak ada rak yang dibuat', 'shelves_create' => 'Buat Rak baru', 'shelves_popular' => 'Rak Terpopuler', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'Rak ini tidak memiliki buku yang ditugaskan padanya', 'shelves_edit_and_assign' => 'Edit rak untuk menetapkan buku', - 'shelves_edit_named' => 'Edit Rak Buku :name', - 'shelves_edit' => 'Edit Rak Buku', - 'shelves_delete' => 'Hapus rak buku', - 'shelves_delete_named' => 'Hapus rak buku :name', - 'shelves_delete_explain' => "Ini akan menghapus rak buku dengan nama ':name'. Buku yang berisi tidak akan dihapus.", - 'shelves_delete_confirmation' => 'Apakah Anda yakin ingin menghapus rak buku ini?', - 'shelves_permissions' => 'Izin Rak Buku', - 'shelves_permissions_updated' => 'Izin Rak Buku Diperbarui', - 'shelves_permissions_active' => 'Izin Rak Buku Aktif', - 'shelves_permissions_cascade_warning' => 'Permissions on bookshelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Salin Izin ke Buku', 'shelves_copy_permissions' => 'Salin Izin', - 'shelves_copy_permissions_explain' => 'Ini akan menerapkan setelan izin rak buku ini saat ini ke semua buku yang ada di dalamnya. Sebelum mengaktifkan, pastikan setiap perubahan pada izin rak buku ini telah disimpan.', - 'shelves_copy_permission_success' => 'Izin rak buku disalin ke :count buku', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Buku', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Sunting Konten', 'pages_permissions_active' => 'Izin Halaman Aktif', 'pages_initial_revision' => 'Penerbitan awal', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Halaman Baru', 'pages_editing_draft_notification' => 'Anda sedang menyunting konsep yang terakhir disimpan :timeDiff.', 'pages_draft_edited_notification' => 'Halaman ini telah diperbarui sejak saat itu. Anda disarankan untuk membuang draf ini.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/id/errors.php b/resources/lang/id/errors.php index 4f71eeb00..fe3fb6dec 100644 --- a/resources/lang/id/errors.php +++ b/resources/lang/id/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Entitas tidak ditemukan', - 'bookshelf_not_found' => 'Rak buku tidak ditemukan', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Buku tidak ditemukan', 'page_not_found' => 'Halaman tidak ditemukan', 'chapter_not_found' => 'Bab tidak ditemukan', diff --git a/resources/lang/id/settings.php b/resources/lang/id/settings.php index 4b931b54f..5015f863f 100644 --- a/resources/lang/id/settings.php +++ b/resources/lang/id/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Selamat! Saat Anda menerima pemberitahuan email ini, pengaturan email Anda tampaknya telah dikonfigurasi dengan benar.', 'maint_recycle_bin_desc' => 'Rak, buku, bab & halaman yang dihapus dikirim ke recycle bin sehingga dapat dipulihkan atau dihapus secara permanen. Item lama di recycle bin dapat dihapus secara otomatis setelah beberapa saat tergantung pada konfigurasi sistem.', 'maint_recycle_bin_open' => 'Buka Tempat Sampah', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Tempat Sampah', diff --git a/resources/lang/it/activities.php b/resources/lang/it/activities.php index eb369e4ec..975b747b9 100755 --- a/resources/lang/it/activities.php +++ b/resources/lang/it/activities.php @@ -42,10 +42,10 @@ return [ 'bookshelf_create_notification' => 'Libreria creata con successo', 'bookshelf_create_from_book' => 'libro convertito in libreria', 'bookshelf_create_from_book_notification' => 'Libro convertito con successo in libreria', - 'bookshelf_update' => 'ha aggiornato la libreria', + 'bookshelf_update' => 'libreria aggiornata', 'bookshelf_update_notification' => 'Libreria aggiornata con successo', - 'bookshelf_delete' => 'ha eliminato la libreria', - 'bookshelf_delete_notification' => 'Libreria cancellata con successo', + 'bookshelf_delete' => 'Iibreria eliminata', + 'bookshelf_delete_notification' => 'Libreria eliminata con successo', // Favourites 'favourite_add_notification' => '":name" è stato aggiunto ai tuoi preferiti', diff --git a/resources/lang/it/entities.php b/resources/lang/it/entities.php index 99f903c22..7c31412ad 100755 --- a/resources/lang/it/entities.php +++ b/resources/lang/it/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Aggiornato :timeLength', 'meta_updated_name' => 'Aggiornato :timeLength da :user', 'meta_owned_name' => 'Creati da :user', + 'meta_reference_page_count' => 'Referenziato su 1 pagina|Referenziato su :count pagine', 'entity_select' => 'Selezione Entità', 'entity_select_lack_permission' => 'Non hai i permessi necessari per selezionare questo elemento', 'images' => 'Immagini', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Libreria', 'shelves' => 'Librerie', 'x_shelves' => ':count Libreria|:count Librerie', - 'shelves_long' => 'Librerie', 'shelves_empty' => 'Nessuna libreria è stata creata', 'shelves_create' => 'Crea Nuova Libreria', 'shelves_popular' => 'Librerie Popolari', @@ -95,15 +95,15 @@ return [ 'shelves_edit' => 'Modifica Libreria', 'shelves_delete' => 'Elimina Libreria', 'shelves_delete_named' => 'Elimina Libreria :name', - 'shelves_delete_explain' => "La libreria ':name' verrà eliminata. I libri contenuti non verranno eliminati.", + 'shelves_delete_explain' => "La libreria ':name' verrà eliminata. I libri al suo interno non verranno eliminati.", 'shelves_delete_confirmation' => 'Sei sicuro di voler eliminare questa libreria?', 'shelves_permissions' => 'Permessi Libreria', 'shelves_permissions_updated' => 'Permessi Libreria Aggiornati', - 'shelves_permissions_active' => 'Permessi Attivi Libreria', - 'shelves_permissions_cascade_warning' => 'I permessi sugli scaffali non si estendono automaticamente ai libri contenuti. Questo avviene in quanto un libro può essere presente su più scaffali. I permessi possono comunque essere copiati ai libri contenuti usando l\'opzione qui sotto.', + 'shelves_permissions_active' => 'Permessi Libreria Attivi', + 'shelves_permissions_cascade_warning' => 'I permessi delle librerie non si estendono automaticamente ai libri contenuti. Questo perché un libro può essere presente su più scaffali. I permessi possono comunque essere copiati ai libri al suo interno usando l\'opzione sottostante.', 'shelves_copy_permissions_to_books' => 'Copia Permessi ai Libri', 'shelves_copy_permissions' => 'Copia Permessi', - 'shelves_copy_permissions_explain' => 'Verranno applicati tutti i permessi della libreria ai libri contenuti. Prima di attivarlo, assicurati che ogni permesso di questa libreria sia salvato.', + 'shelves_copy_permissions_explain' => 'Verranno applicati tutti i permessi della libreria ai libri al suo interno. Prima dell\'attivazione, assicurati che ogni permesso di questa libreria sia salvato.', 'shelves_copy_permission_success' => 'Permessi della libreria copiati in :count libri', // Books @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Modifica contenuto', 'pages_permissions_active' => 'Permessi Pagina Attivi', 'pages_initial_revision' => 'Pubblicazione iniziale', + 'pages_references_update_revision' => 'Aggiornamento automatico di sistema dei collegamenti interni', 'pages_initial_name' => 'Nuova Pagina', 'pages_editing_draft_notification' => 'Stai modificando una bozza che è stata salvata il :timeDiff.', 'pages_draft_edited_notification' => 'Questa pagina è stata aggiornata. È consigliabile scartare questa bozza.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'È possibile convertire questo capitolo in un nuovo libro con gli stessi contenuti. Tutti i permessi impostati su questo capitolo saranno copiati nel nuovo libro, ma i permessi ereditati dal libro principale non saranno copiati, il che potrebbe portare a una modifica del controllo degli accessi.', 'convert_chapter' => 'Converti Capitolo', 'convert_chapter_confirm' => 'Sei sicuro di voler convertire questo capitolo?', + + // References + 'references' => 'Riferimenti', + 'references_none' => 'Non ci sono riferimenti tracciati a questa voce.', + 'references_to_desc' => 'Di seguito sono riportate tutte le pagine conosciute nel sistema che collegano a questo elemento.', ]; diff --git a/resources/lang/it/settings.php b/resources/lang/it/settings.php index c3425bcf5..7f5c10df1 100755 --- a/resources/lang/it/settings.php +++ b/resources/lang/it/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Congratulazioni! Siccome hai ricevuto questa notifica email, le tue impostazioni sembrano essere configurate correttamente.', 'maint_recycle_bin_desc' => 'Le librerie, i libri, i capitoli e le pagine cancellati vengono inviati al cestino in modo che possano essere ripristinati o eliminati definitivamente. Gli elementi più vecchi nel cestino possono essere automaticamente rimossi dopo un certo periodo, a seconda della configurazione del sistema.', 'maint_recycle_bin_open' => 'Apri il Cestino', + 'maint_regen_references' => 'Rigenera Riferimenti', + 'maint_regen_references_desc' => 'Questa azione ricostruirà l\'indice di dei riferimenti incrociati all\'interno del database. Di solito questa operazione è gestita automaticamente, ma può essere utile per indicizzare contenuti vecchi o aggiunti con metodi non ufficiali.', + 'maint_regen_references_success' => 'L\'indice di riferimento è stato rigenerato!', + 'maint_timeout_command_note' => 'Nota: Questa azione può richiedere del tempo per essere eseguita e può causare problemi di timeout in alcuni ambienti Web. In alternativa, questa azione può essere eseguita usando un comando da terminale.', // Recycle Bin 'recycle_bin' => 'Cestino', diff --git a/resources/lang/ja/activities.php b/resources/lang/ja/activities.php index d9a73fe6a..2b4affcf3 100644 --- a/resources/lang/ja/activities.php +++ b/resources/lang/ja/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'ブックが再度並び変えられました', // Bookshelves - 'bookshelf_create' => 'が本棚を作成:', - 'bookshelf_create_notification' => '本棚を作成しました', - 'bookshelf_create_from_book' => 'がブックを本棚に変換:', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'ブックが本棚へ正常に変換されました', - 'bookshelf_update' => 'が本棚を更新:', - 'bookshelf_update_notification' => '本棚を更新しました', - 'bookshelf_delete' => 'が本棚を削除:', - 'bookshelf_delete_notification' => '本棚を削除しました', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name"がお気に入りに追加されました', diff --git a/resources/lang/ja/entities.php b/resources/lang/ja/entities.php index 4f8b9a730..1d75b57e1 100644 --- a/resources/lang/ja/entities.php +++ b/resources/lang/ja/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => '更新: :timeLength', 'meta_updated_name' => '更新: :timeLength (:user)', 'meta_owned_name' => '所有者: :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'エンティティ選択', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => '画像', @@ -77,7 +78,6 @@ return [ 'shelf' => '本棚', 'shelves' => '本棚', 'x_shelves' => ':count 本棚|:count 本棚', - 'shelves_long' => '本棚', 'shelves_empty' => '本棚が作成されていません', 'shelves_create' => '新しい本棚を作成', 'shelves_popular' => '人気の本棚', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'この本棚にはブックが割り当てられていません。', 'shelves_edit_and_assign' => '本棚を編集してブックを割り当てる', - 'shelves_edit_named' => '本棚「:name」を編集', - 'shelves_edit' => '本棚を編集', - 'shelves_delete' => '本棚を削除', - 'shelves_delete_named' => '本棚「:name」を削除', - 'shelves_delete_explain' => "これにより、この本棚「:name」が削除されます。含まれているブックは削除されません。", - 'shelves_delete_confirmation' => '本当にこの本棚を削除してよろしいですか?', - 'shelves_permissions' => '本棚の権限', - 'shelves_permissions_updated' => '本棚の権限を更新しました', - 'shelves_permissions_active' => '本棚の権限は有効です', - 'shelves_permissions_cascade_warning' => '本棚の権限は含まれる本には自動的に継承されません。これは、1つのブックが複数の本棚に存在する可能性があるためです。ただし、以下のオプションを使用すると権限を子ブックにコピーできます。', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'ブックに権限をコピー', 'shelves_copy_permissions' => '権限をコピー', - 'shelves_copy_permissions_explain' => 'これにより、この本棚の現在の権限設定を本棚に含まれるすべてのブックに適用します。有効にする前に、この本棚の権限への変更が保存されていることを確認してください。', - 'shelves_copy_permission_success' => '本棚の権限が:count個のブックにコピーされました', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'ブック', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'コンテンツの編集', 'pages_permissions_active' => 'ページの権限は有効です', 'pages_initial_revision' => '初回の公開', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => '新規ページ', 'pages_editing_draft_notification' => ':timeDiffに保存された下書きを編集しています。', 'pages_draft_edited_notification' => 'このページは更新されています。下書きを破棄することを推奨します。', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'このチャプターを同じ内容の新しいブックに変換できます。このチャプターで設定された権限は新しいブックにコピーされますが、親ブックから継承された権限はコピーされないため、アクセス制御が変更される可能性があります。', 'convert_chapter' => 'チャプターを変換', 'convert_chapter_confirm' => 'このチャプターを変換してもよろしいですか?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/ja/errors.php b/resources/lang/ja/errors.php index d63e9bf36..1537a33e8 100644 --- a/resources/lang/ja/errors.php +++ b/resources/lang/ja/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'エンティティが見つかりません', - 'bookshelf_not_found' => '本棚が見つかりません', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'ブックが見つかりません', 'page_not_found' => 'ページが見つかりません', 'chapter_not_found' => 'チャプターが見つかりません', diff --git a/resources/lang/ja/settings.php b/resources/lang/ja/settings.php index 427d9eb71..f68f5f7c4 100644 --- a/resources/lang/ja/settings.php +++ b/resources/lang/ja/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'おめでとうございます!この通知メールが届いたということは、あなたのメール設定は適切であると思われます。', 'maint_recycle_bin_desc' => '削除された本棚・ブック・チャプター・ページはごみ箱に送られるため、復元したり完全に削除したりできます。システムの設定によっては、ごみ箱の古いアイテムがしばらくすると自動的に削除される場合があります。', 'maint_recycle_bin_open' => 'ごみ箱を開く', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'ごみ箱', diff --git a/resources/lang/ko/activities.php b/resources/lang/ko/activities.php index d8811e44d..debd373af 100644 --- a/resources/lang/ko/activities.php +++ b/resources/lang/ko/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => '책 정렬 바꿈', // Bookshelves - 'bookshelf_create' => '책꽂이 만들기', - 'bookshelf_create_notification' => '책꽂이 생성함', - 'bookshelf_create_from_book' => '책을 책꽂이로 변환', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => '책을 책꽂이로 변환했습니다.', - 'bookshelf_update' => '책꽂이 수정', - 'bookshelf_update_notification' => '책꽂이 수정함', - 'bookshelf_delete' => '책꽂이 지우기', - 'bookshelf_delete_notification' => '책꽂이 삭제함', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" 북마크에 추가함', diff --git a/resources/lang/ko/entities.php b/resources/lang/ko/entities.php index 6a059a949..48d043c7e 100644 --- a/resources/lang/ko/entities.php +++ b/resources/lang/ko/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => '수정함 :timeLength', 'meta_updated_name' => '수정함 :timeLength, :user', 'meta_owned_name' => '소유함 :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => '항목 선택', 'entity_select_lack_permission' => '이 항목을 선택하기 위해 필요한 권한이 없습니다', 'images' => '이미지', @@ -77,7 +78,6 @@ return [ 'shelf' => '책꽂이', 'shelves' => '책꽂이', 'x_shelves' => '책꽂이 :count개|총 :count개', - 'shelves_long' => '책꽂이', 'shelves_empty' => '만든 책꽂이가 없습니다.', 'shelves_create' => '책꽂이 만들기', 'shelves_popular' => '많이 읽은 책꽂이', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => '책을 이 책장에 추가하려면 아래로 드래그하세요', 'shelves_empty_contents' => '이 책꽂이에 책이 없습니다.', 'shelves_edit_and_assign' => '책꽂이 바꾸기로 책을 추가하세요.', - 'shelves_edit_named' => ':name 바꾸기', - 'shelves_edit' => '책꽂이 바꾸기', - 'shelves_delete' => '책꽂이 삭제하기', - 'shelves_delete_named' => ':name 삭제하기', - 'shelves_delete_explain' => ":name을 지웁니다. 책는 지우지 않습니다.", - 'shelves_delete_confirmation' => '이 책꽂이를 지울 건가요?', - 'shelves_permissions' => '책꽂이 권한', - 'shelves_permissions_updated' => '책꽂이 권한 바꿈', - 'shelves_permissions_active' => '책꽂이 권한 허용함', - 'shelves_permissions_cascade_warning' => '책을 여러 책꽂이에 들일 수 있고 책 권한과 책꽂이 권한은 별개입니다. 책꽂이 권한을 책 권한에 복사합니다.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => '권한 맞춤', 'shelves_copy_permissions' => '실행', - 'shelves_copy_permissions_explain' => '책꽂이의 모든 책에 이 권한을 적용합니다. 책꽂이의 권한을 저장했는지 확인하세요.', - 'shelves_copy_permission_success' => '책 :count개 권한 바꿈', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => '책', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => '수정', 'pages_permissions_active' => '문서 권한 허용함', 'pages_initial_revision' => '처음 판본', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => '제목 없음', 'pages_editing_draft_notification' => ':timeDiff에 초안 문서입니다.', 'pages_draft_edited_notification' => '최근에 수정한 문서이기 때문에 초안 문서를 폐기하는 편이 좋습니다.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => '챕터 변환', 'convert_chapter_confirm' => '이 챕터를 변환하시겠어요?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/ko/errors.php b/resources/lang/ko/errors.php index 8971e6107..9dd8225ff 100644 --- a/resources/lang/ko/errors.php +++ b/resources/lang/ko/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => '항목이 없습니다.', - 'bookshelf_not_found' => '책꽂이가 없습니다.', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => '책이 없습니다.', 'page_not_found' => '문서가 없습니다.', 'chapter_not_found' => '챕터가 없습니다.', diff --git a/resources/lang/ko/settings.php b/resources/lang/ko/settings.php index eff9f7b91..6d7d49fda 100755 --- a/resources/lang/ko/settings.php +++ b/resources/lang/ko/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => '메일을 정상적으로 수신했습니다.', 'maint_recycle_bin_desc' => '지워진 콘텐츠는 휴지통에 들어가 복원하거나 영구 삭제할 수 있습니다. 오래된 항목은 자동으로 지워집니다.', 'maint_recycle_bin_open' => '휴지통 열기', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => '휴지통', diff --git a/resources/lang/lt/activities.php b/resources/lang/lt/activities.php index 7728f4835..5644a9487 100644 --- a/resources/lang/lt/activities.php +++ b/resources/lang/lt/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Book successfully re-sorted', // Bookshelves - 'bookshelf_create' => 'created bookshelf', - 'bookshelf_create_notification' => 'Bookshelf successfully created', - 'bookshelf_create_from_book' => 'converted book to bookshelf', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf', - 'bookshelf_update' => 'atnaujinta knygų lentyna', - 'bookshelf_update_notification' => 'Bookshelf successfully updated', - 'bookshelf_delete' => 'ištrinta knygų lentyna', - 'bookshelf_delete_notification' => 'Bookshelf successfully deleted', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" has been added to your favourites', diff --git a/resources/lang/lt/entities.php b/resources/lang/lt/entities.php index 62aab8d89..8cf9fac83 100644 --- a/resources/lang/lt/entities.php +++ b/resources/lang/lt/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Atnaujintas :timeLength', 'meta_updated_name' => 'Atnaujinta :timeLength naudotojo :user', 'meta_owned_name' => 'Priklauso :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Pasirinkti subjektą', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Nuotraukos', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Lentyna', 'shelves' => 'Lentynos', 'x_shelves' => ':count lentyna|:count lentynos', - 'shelves_long' => 'Knygų lentynos', 'shelves_empty' => 'Nebuvo sukurtos jokios lentynos', 'shelves_create' => 'Sukurti naują lentyną', 'shelves_popular' => 'Populiarios lentynos', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'Ši lentyną neturi jokių pridėtų knygų', 'shelves_edit_and_assign' => 'Redaguoti lentyną, kad pridėti knygų', - 'shelves_edit_named' => 'Redaguoti knygų lentyną :name', - 'shelves_edit' => 'Redaguoti knygų lentyną', - 'shelves_delete' => 'Ištrinti knygų lentyną', - 'shelves_delete_named' => 'Ištrinti knygų lentyną :name', - 'shelves_delete_explain' => "This will delete the bookshelf with the name ':name'. Contained books will not be deleted.", - 'shelves_delete_confirmation' => 'Ar jūs esate tikri, kad norite ištrinti šią knygų lentyną?', - 'shelves_permissions' => 'Knygų lentynos leidimai', - 'shelves_permissions_updated' => 'Knygų lentynos leidimai atnaujinti', - 'shelves_permissions_active' => 'Knygų lentynos leidimai aktyvūs', - 'shelves_permissions_cascade_warning' => 'Permissions on bookshelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Kopijuoti leidimus knygoms', 'shelves_copy_permissions' => 'Kopijuoti leidimus', - 'shelves_copy_permissions_explain' => 'Visoms knygoms, esančioms šioje knygų lentynoje, bus taikomi dabartiniai leidimų nustatymai. Prieš suaktyvindami įsitikinkite, kad visi šios knygų lentynos leidimų pakeitimai buvo išsaugoti.', - 'shelves_copy_permission_success' => 'Knygų lentynos leidimai nukopijuoti į :count knygas', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Knyga', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Redaguoti turinį', 'pages_permissions_active' => 'Puslapio leidimai aktyvūs', 'pages_initial_revision' => 'Pradinis skelbimas', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Naujas puslapis', 'pages_editing_draft_notification' => 'Dabar jūs redaguojate juodraštį, kuris paskutinį kartą buvo išsaugotas :timeDiff', 'pages_draft_edited_notification' => 'Šis puslapis buvo redaguotas iki to laiko. Rekomenduojame jums išmesti šį juodraštį.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/lt/errors.php b/resources/lang/lt/errors.php index 1ceeb03e1..ac93298cb 100644 --- a/resources/lang/lt/errors.php +++ b/resources/lang/lt/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Subjektas nerastas', - 'bookshelf_not_found' => 'Knygų lentyna nerasta', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Knyga nerasta', 'page_not_found' => 'Puslapis nerastas', 'chapter_not_found' => 'Skyrius nerastas', diff --git a/resources/lang/lt/settings.php b/resources/lang/lt/settings.php index cd44eff67..16df6b826 100644 --- a/resources/lang/lt/settings.php +++ b/resources/lang/lt/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Sveikiname! Kadangi gavote šį elektroninio pašto pranešimą, jūsų elektroninio pašto nustatymai buvo sukonfigūruoti teisingai.', 'maint_recycle_bin_desc' => 'Ištrintos lentynos, knygos, skyriai ir puslapiai yra perkeliami į šiukšliadėžę tam, kad jie galėtų būti atkurti arba ištrinti visam laikui. Senesni elementai, esantys šiukšliadėžėje, gali būti automatiškai panaikinti po tam tikro laiko priklausomai nuo sistemos konfigūracijos.', 'maint_recycle_bin_open' => 'Atidaryti šiukšliadėžę', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Šiukšliadėžė', diff --git a/resources/lang/lv/activities.php b/resources/lang/lv/activities.php index c76041a0a..356d4890f 100644 --- a/resources/lang/lv/activities.php +++ b/resources/lang/lv/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Grāmata veiksmīgi pārkārtota', // Bookshelves - 'bookshelf_create' => 'izveidoja plautku', - 'bookshelf_create_notification' => 'Plaukts veiksmīgi izveidots', - 'bookshelf_create_from_book' => 'converted book to bookshelf', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf', - 'bookshelf_update' => 'atjaunoja plauktu', - 'bookshelf_update_notification' => 'Plaukts veiksmīgi atjaunināts', - 'bookshelf_delete' => 'izdzēsa plauktu', - 'bookshelf_delete_notification' => 'Plaukts veiksmīgi dzēsts', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" ir pievienots jūsu favorītiem', diff --git a/resources/lang/lv/entities.php b/resources/lang/lv/entities.php index ec1b9c8ac..48bd922ed 100644 --- a/resources/lang/lv/entities.php +++ b/resources/lang/lv/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Atjaunināts :timeLength', 'meta_updated_name' => ':user atjauninājis pirms :timeLength', 'meta_owned_name' => 'Īpašnieks :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Izvēlēties vienumu', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Attēli', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Plaukts', 'shelves' => 'Plaukti', 'x_shelves' => ':count Plaukts|:count Plaukti', - 'shelves_long' => 'Grāmatu plautki', 'shelves_empty' => 'Neviens plaukts nav izveidots', 'shelves_create' => 'Izveidot jaunu plauktu', 'shelves_popular' => 'Populāri plaukti', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'Šim gŗamatplauktam nav pievienotu grāmatu', 'shelves_edit_and_assign' => 'Labot plauktu, lai tam pievienotu grāmatas', - 'shelves_edit_named' => 'Labot grāmatplauktu :name', - 'shelves_edit' => 'Labot grāmatplauktu', - 'shelves_delete' => 'Dzēst grāmatplauktu', - 'shelves_delete_named' => 'Dzēst grāmatplauktu :name', - 'shelves_delete_explain' => "Tiks dzēsts grāmatplaukts ar nosaukumu \":name\". Tajā ievietotās grāmatas netiks dzēstas.", - 'shelves_delete_confirmation' => 'Vai esat pārliecināts, ka vēlaties dzēst šo grāmatplauktu?', - 'shelves_permissions' => 'Grāmatplaukta atļaujas', - 'shelves_permissions_updated' => 'Grāmatplaukta atļaujas atjauninātas', - 'shelves_permissions_active' => 'Grāmatplaukta atļaujas ir aktīvas', - 'shelves_permissions_cascade_warning' => 'Grāmatu plauktu atļaujas netiek automātiski pārvietotas uz grāmatām. Tas ir tāpēc, ka grāmata var atrasties vairākos plauktos. Tomēr atļaujas var nokopēt uz plauktam pievienotajām grāmatām, izmantojot zemāk norādīto opciju.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Kopēt grāmatplaukta atļaujas uz grāmatām', 'shelves_copy_permissions' => 'Kopēt atļaujas', - 'shelves_copy_permissions_explain' => 'Šis piemēros pašreizējās grāmatplaukta piekļuves tiesības visām tajā esošajām grāmatām. Pirms ieslēgšanas pārliecinieties, ka ir saglabātas izmaiņas grāmatplaukta piekļuves tiesībām.', - 'shelves_copy_permission_success' => 'Grāmatplaukta atļaujas ir pārkopētas uz :count grāmatām', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Grāmata', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Labot saturu', 'pages_permissions_active' => 'Lapas atļaujas ir aktīvas', 'pages_initial_revision' => 'Sākotnējā publikācija', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Jauna lapa', 'pages_editing_draft_notification' => 'Jūs pašlaik veicat izmaiņas melnrakstā, kurš pēdējo reizi ir saglabāts :timeDiff.', 'pages_draft_edited_notification' => 'Šī lapa ir tikusi atjaunināta. Šo melnrakstu ieteicams atmest.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/lv/errors.php b/resources/lang/lv/errors.php index 9ce820191..0a7190fa6 100644 --- a/resources/lang/lv/errors.php +++ b/resources/lang/lv/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Vienība nav atrasta', - 'bookshelf_not_found' => 'Grāmatplaukts nav atrasts', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Grāmata nav atrasta', 'page_not_found' => 'Lapa nav atrasta', 'chapter_not_found' => 'Nodaļa nav atrasta', diff --git a/resources/lang/lv/settings.php b/resources/lang/lv/settings.php index 60faef802..66381a595 100644 --- a/resources/lang/lv/settings.php +++ b/resources/lang/lv/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Apsveicam! Tā kā jūs saņēmāt šo epasta paziņojumu, jūsu epasta uzstādījumi šķiet pareizi.', 'maint_recycle_bin_desc' => 'Dzēstie plaukti, grāmatas, nodaļas un lapas ir pārceltas uz miskasti, lai tos varētu atjaunot vai izdzēst pilnībā. Vecākas vienības miskastē var tikt automātiski dzēstas pēc kāda laika atkarībā no sistēmas uzstādījumiem.', 'maint_recycle_bin_open' => 'Atvērt miskasti', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Miskaste', diff --git a/resources/lang/nb/activities.php b/resources/lang/nb/activities.php index 136e36373..ca99ff8ff 100644 --- a/resources/lang/nb/activities.php +++ b/resources/lang/nb/activities.php @@ -39,14 +39,14 @@ return [ 'book_sort_notification' => 'Boken ble gjenopprettet', // Bookshelves - 'bookshelf_create' => 'opprettet bokhylle', - 'bookshelf_create_notification' => 'Bokhylle ble opprettet', - 'bookshelf_create_from_book' => 'konverterte bok til bokhylle', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Boken ble konvertert til en bokhylle', - 'bookshelf_update' => 'oppdaterte bokhylle', - 'bookshelf_update_notification' => 'Bookshelf successfully updated', - 'bookshelf_delete' => 'slettet bokhylle', - 'bookshelf_delete_notification' => 'Bookshelf successfully deleted', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '«:name» ble lagt til i dine favoritter', diff --git a/resources/lang/nb/entities.php b/resources/lang/nb/entities.php index f73ea3691..503708352 100644 --- a/resources/lang/nb/entities.php +++ b/resources/lang/nb/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Oppdatert :timeLength', 'meta_updated_name' => 'Oppdatert :timeLength av :user', 'meta_owned_name' => 'Eies av :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Velg entitet', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Bilder', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Hylle', 'shelves' => 'Hyller', 'x_shelves' => ':count hylle|:count hyller', - 'shelves_long' => 'Bokhyller', 'shelves_empty' => 'Ingen bokhyller er opprettet', 'shelves_create' => 'Opprett ny bokhylle', 'shelves_popular' => 'Populære bokhyller', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'INgen bøker er stablet i denne hylla', 'shelves_edit_and_assign' => 'Endre hylla for å legge til bøker', - 'shelves_edit_named' => 'Endre hyllen :name', - 'shelves_edit' => 'Endre bokhylle', - 'shelves_delete' => 'Fjern bokhylle', - 'shelves_delete_named' => 'Fjern bokhyllen :name', - 'shelves_delete_explain' => "Dette vil fjerne bokhyllen ':name'. Bøkene vil ikke fjernes fra systemet.", - 'shelves_delete_confirmation' => 'Er du helt sikker på at du vil skru ned hylla?', - 'shelves_permissions' => 'Tilganger til hylla', - 'shelves_permissions_updated' => 'Hyllas tilganger er oppdatert', - 'shelves_permissions_active' => 'Hyllas tilganger er aktive', - 'shelves_permissions_cascade_warning' => 'Tillatelser på bokhyller vil ikke automatisk fordeles til bøkene på aktuell bokhylle. Dette da en bok kan tilhøre flere bokhyller. Tillatelser kan imidlertid kopieres til underliggende bøker ved å benytte alternativet nedenfor.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Kopier tilganger til bøkene på hylla', 'shelves_copy_permissions' => 'Kopier tilganger', - 'shelves_copy_permissions_explain' => 'Dette vil angi gjeldende tillatelsesinnstillinger for denne bokhyllen på alle bøkene som finnes på den. Før du aktiverer, må du forsikre deg om at endringer i tillatelsene til denne bokhyllen er lagret.', - 'shelves_copy_permission_success' => 'Tilgangene ble overført til :count bøker', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Bok', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Endre innhold', 'pages_permissions_active' => 'Sidetilganger er aktive', 'pages_initial_revision' => 'Første publisering', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Ny side', 'pages_editing_draft_notification' => 'Du skriver på et utkast som sist ble lagret :timeDiff.', 'pages_draft_edited_notification' => 'Siden har blitt endret siden du startet. Det anbefales at du forkaster dine endringer.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/nb/errors.php b/resources/lang/nb/errors.php index d6f0288b9..7f3bc14c3 100644 --- a/resources/lang/nb/errors.php +++ b/resources/lang/nb/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Entitet ble ikke funnet', - 'bookshelf_not_found' => 'Bokhyllen ble ikke funnet', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Boken ble ikke funnet', 'page_not_found' => 'Siden ble ikke funnet', 'chapter_not_found' => 'Kapittel ble ikke funnet', diff --git a/resources/lang/nb/settings.php b/resources/lang/nb/settings.php index 4251cce69..c0b5a8596 100644 --- a/resources/lang/nb/settings.php +++ b/resources/lang/nb/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Gratulerer! Da du mottok dette e-postvarselet, ser det ut til at e-postinnstillingene dine er konfigurert riktig.', 'maint_recycle_bin_desc' => 'Slettede hyller, bøker, kapitler og sider kastes i papirkurven så de kan bli gjenopprettet eller slettet permanent. Eldre utgaver i papirkurven kan slettes automatisk etter en stund, avhengig av systemkonfigurasjonen.', 'maint_recycle_bin_open' => 'Åpne papirkurven', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Papirkurven', diff --git a/resources/lang/nl/activities.php b/resources/lang/nl/activities.php index e8009795e..9b896b2ae 100644 --- a/resources/lang/nl/activities.php +++ b/resources/lang/nl/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Boek succesvol opnieuw gesorteerd', // Bookshelves - 'bookshelf_create' => 'boekenplank aangemaakt', - 'bookshelf_create_notification' => 'Boekenplank succesvol aangemaakt', - 'bookshelf_create_from_book' => 'Boek is geconverteerd naar boekenplank', + 'bookshelf_create' => 'heeft boekenplank aangemaakt', + 'bookshelf_create_notification' => 'Boekenplank is succesvol aangemaakt', + 'bookshelf_create_from_book' => 'heeft boek geconverteerd naar boekenplank', 'bookshelf_create_from_book_notification' => 'Boek is succesvol geconverteerd naar boekenplank', - 'bookshelf_update' => 'wijzigde boekenplank', - 'bookshelf_update_notification' => 'Boekenplank succesvol bijgewerkt', - 'bookshelf_delete' => 'verwijderde boekenplank', - 'bookshelf_delete_notification' => 'Boekenplank succesvol verwijderd', + 'bookshelf_update' => 'heeft boekenplank bijgewerkt', + 'bookshelf_update_notification' => 'Boekenplank is succesvol bijgewerkt', + 'bookshelf_delete' => 'heeft boekenplank verwijderd', + 'bookshelf_delete_notification' => 'Boekenplank is succesvol verwijderd', // Favourites 'favourite_add_notification' => '":name" is toegevoegd aan je favorieten', diff --git a/resources/lang/nl/entities.php b/resources/lang/nl/entities.php index ad1c71618..3ee393cdb 100644 --- a/resources/lang/nl/entities.php +++ b/resources/lang/nl/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Bijgewerkt: :timeLength', 'meta_updated_name' => 'Bijgewerkt: :timeLength door :user', 'meta_owned_name' => 'Eigendom van :user', + 'meta_reference_page_count' => 'Naartoe verwezen op 1 pagina|Naartoe verwezen op :count pagina\'s', 'entity_select' => 'Entiteit selecteren', 'entity_select_lack_permission' => 'Je hebt niet de vereiste machtiging om dit item te selecteren', 'images' => 'Afbeeldingen', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Boekenplank', 'shelves' => 'Boekenplanken', 'x_shelves' => ':count Boekenplank|:count Boekenplanken', - 'shelves_long' => 'Boekenplanken', 'shelves_empty' => 'Er zijn geen boekenplanken aangemaakt', 'shelves_create' => 'Nieuwe boekenplank maken', 'shelves_popular' => 'Populaire boekenplanken', @@ -91,15 +91,15 @@ return [ 'shelves_drag_books' => 'Sleep boeken hieronder om ze toe te voegen aan deze boekenplank', 'shelves_empty_contents' => 'Aan deze plank zijn geen boeken toegewezen', 'shelves_edit_and_assign' => 'Bewerk boekenplank om boeken toe te wijzen', - 'shelves_edit_named' => 'Bewerk boekenplank :name', - 'shelves_edit' => 'Bewerk boekenplank', - 'shelves_delete' => 'Verwijder boekenplank', - 'shelves_delete_named' => 'Verwijder boekenplank :name', - 'shelves_delete_explain' => "Dit zal de boekenplank met de naam ':naam' verwijderen. Boeken worden hierdoor niet verwijderd.", - 'shelves_delete_confirmation' => 'Weet je zeker dat je deze boekenplank wilt verwijderen?', + 'shelves_edit_named' => 'Bewerk Boekenplank :name', + 'shelves_edit' => 'Bewerk Boekenplank', + 'shelves_delete' => 'Verwijder Boekenplank', + 'shelves_delete_named' => 'Verwijder Boekenplank :name', + 'shelves_delete_explain' => "Dit zal de boekenplank met de naam ':naam' verwijderen. Boeken die op deze plank staan worden echter niet verwijderd.", + 'shelves_delete_confirmation' => 'Weet u zeker dat u deze boekenplank wilt verwijderen?', 'shelves_permissions' => 'Boekenplank Machtigingen', 'shelves_permissions_updated' => 'Boekenplank Machtigingen Bijgewerkt', - 'shelves_permissions_active' => 'Boekenplank Machtigingen Actief', + 'shelves_permissions_active' => 'Machtigingen op Boekenplank Actief', 'shelves_permissions_cascade_warning' => 'De ingestelde machtigingen op deze boekenplank worden niet automatisch toegepast op de boeken van deze boekenplank. Dit is omdat een boek toegekend kan worden op meerdere boekenplanken. De machtigingen van deze boekenplank kunnen echter wel gekopieerd worden naar de boeken van deze boekenplank via de optie hieronder.', 'shelves_copy_permissions_to_books' => 'Kopieer Machtigingen naar Boeken', 'shelves_copy_permissions' => 'Kopieer Machtigingen', @@ -132,7 +132,7 @@ return [ 'books_empty_create_page' => 'Nieuwe pagina maken', 'books_empty_sort_current_book' => 'Boek sorteren', 'books_empty_add_chapter' => 'Hoofdstuk toevoegen', - 'books_permissions_active' => 'Boek Machtigingen Actief', + 'books_permissions_active' => 'Machtigingen op Boek Actief', 'books_search_this' => 'Zoeken in dit boek', 'books_navigation' => 'Boek navigatie', 'books_sort' => 'Inhoud van het boek sorteren', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Bewerk inhoud', 'pages_permissions_active' => 'Pagina Machtigingen Actief', 'pages_initial_revision' => 'Eerste publicatie', + 'pages_references_update_revision' => 'Automatische systeemupdate van interne links', 'pages_initial_name' => 'Nieuwe pagina', 'pages_editing_draft_notification' => 'U bewerkt momenteel een concept dat voor het laatst is opgeslagen op :timeDiff.', 'pages_draft_edited_notification' => 'Deze pagina is sindsdien bijgewerkt. Het wordt aanbevolen dat u dit concept verwijderd.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'Je kan dit hoofdstuk converteren naar een nieuw boek met dezelfde inhoud. Alle machtigingen ingesteld op dit hoofdstuk zullen worden gekopieerd naar het nieuwe boek, maar alle geërfde machtigingen, van het bovenliggende boek, zullen niet worden gekopieerd, wat kan leiden tot een wijziging van de toegangscontrole.', 'convert_chapter' => 'Converteer Hoofdstuk', 'convert_chapter_confirm' => 'Weet je zeker dat je dit hoofdstuk wil converteren?', + + // References + 'references' => 'Verwijzingen', + 'references_none' => 'Er zijn geen verwijzingen naar dit artikel bijgehouden.', + 'references_to_desc' => 'Hieronder staan alle gekende pagina\'s in het systeem die naar dit item linken.', ]; diff --git a/resources/lang/nl/settings.php b/resources/lang/nl/settings.php index 65596d3b4..96dd849b0 100644 --- a/resources/lang/nl/settings.php +++ b/resources/lang/nl/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Gefeliciteerd! Nu je deze e-mailmelding hebt ontvangen, lijken je e-mailinstellingen correct te zijn geconfigureerd.', 'maint_recycle_bin_desc' => 'Verwijderde boekenplanken, boeken, hoofdstukken en pagina\'s worden naar de prullenbak gestuurd waar ze hersteld of definitief verwijderd kunnen worden. Oudere items in de prullenbak kunnen automatisch worden verwijderd, afhankelijk van de systeemconfiguratie.', 'maint_recycle_bin_open' => 'Prullenbak openen', + 'maint_regen_references' => 'Verwijzingen opnieuw genereren', + 'maint_regen_references_desc' => 'Deze actie zal de kruisverwijzingen index binnen de database opnieuw opbouwen. Dit wordt doorgaans automatisch gedaan, maar deze actie kan nuttig zijn om oude inhoud of inhoud die via onofficiële methoden is toegevoegd te indexeren.', + 'maint_regen_references_success' => 'Verwijzingen index is opnieuw gegenereerd!', + 'maint_timeout_command_note' => 'Opmerking: Het uitvoeren van deze actie kan enige tijd in beslag nemen, wat in sommige webomgevingen kan leiden tot time-outs. Als alternatief kan deze actie ook worden uitgevoerd met een terminal commando.', // Recycle Bin 'recycle_bin' => 'Prullenbak', diff --git a/resources/lang/pl/activities.php b/resources/lang/pl/activities.php index 880dc219b..77a8337dd 100644 --- a/resources/lang/pl/activities.php +++ b/resources/lang/pl/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Książka posortowana pomyślnie', // Bookshelves - 'bookshelf_create' => 'utworzył półkę', - 'bookshelf_create_notification' => 'Półka utworzona pomyślnie', - 'bookshelf_create_from_book' => 'skonwertował książkę na półkę', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Książka została pomyślnie skonwertowana na półkę', - 'bookshelf_update' => 'zaktualizował półkę', - 'bookshelf_update_notification' => 'Półka zaktualizowana pomyślnie', - 'bookshelf_delete' => 'usunął półkę', - 'bookshelf_delete_notification' => 'Półka usunięta pomyślnie', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" został dodany do Twoich ulubionych', diff --git a/resources/lang/pl/entities.php b/resources/lang/pl/entities.php index 2237682ae..d099a2972 100644 --- a/resources/lang/pl/entities.php +++ b/resources/lang/pl/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Zaktualizowano :timeLength', 'meta_updated_name' => 'Zaktualizowano :timeLength przez :user', 'meta_owned_name' => 'Właściciel: :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Wybór obiektu', 'entity_select_lack_permission' => 'Nie masz wymaganych uprawnień do wybrania tej pozycji', 'images' => 'Obrazki', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Półka', 'shelves' => 'Półki', 'x_shelves' => ':count Półek|:count Półek', - 'shelves_long' => 'Półki', 'shelves_empty' => 'Brak utworzonych półek', 'shelves_create' => 'Utwórz półkę', 'shelves_popular' => 'Popularne półki', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Przeciągnij książki poniżej, aby dodać je do tej półki', 'shelves_empty_contents' => 'Ta półka nie ma przypisanych żadnych książek', 'shelves_edit_and_assign' => 'Edytuj półkę aby przypisać książki', - 'shelves_edit_named' => 'Edytuj półkę :name', - 'shelves_edit' => 'Edytuj półkę', - 'shelves_delete' => 'Usuń półkę', - 'shelves_delete_named' => 'Usuń półkę :name', - 'shelves_delete_explain' => "Ta operacja usunie półkę o nazwie ':name'. Książki z tej półki nie zostaną usunięte.", - 'shelves_delete_confirmation' => 'Czy jesteś pewien, że chcesz usunąć tę półkę?', - 'shelves_permissions' => 'Uprawnienia półki', - 'shelves_permissions_updated' => 'Uprawnienia półki zostały zaktualizowane', - 'shelves_permissions_active' => 'Uprawnienia półki są aktywne', - 'shelves_permissions_cascade_warning' => 'Uprawnienia na półkach nie są automatycznie kaskadowane do zawartych w nich książek. Dzieje się tak dlatego, że książka może istnieć na wielu półkach. Zezwolenia można jednak skopiować do książek podrzędnych, korzystając z opcji znajdującej się poniżej.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Skopiuj uprawnienia do książek', 'shelves_copy_permissions' => 'Skopiuj uprawnienia', - 'shelves_copy_permissions_explain' => 'To spowoduje zastosowanie obecnych ustawień uprawnień dla tej półki do wszystkich książek w niej zawartych. Przed aktywacją upewnij się, że wszelkie zmiany w uprawnieniach do tej półki zostały zapisane.', - 'shelves_copy_permission_success' => 'Uprawnienia półki zostały skopiowane do :count książek', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Książka', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Edytuj zawartość', 'pages_permissions_active' => 'Uprawnienia strony są aktywne', 'pages_initial_revision' => 'Pierwsze wydanie', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Nowa strona', 'pages_editing_draft_notification' => 'Edytujesz obecnie wersję roboczą, która była ostatnio zapisana :timeDiff.', 'pages_draft_edited_notification' => 'Od tego czasu ta strona była zmieniana. Zalecane jest odrzucenie tej wersji roboczej.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'Możesz skonwertować ten rozdział do nowej książki o tej samej treści. Wszelkie uprawnienia ustawione w tym rozdziale zostaną skopiowane do nowej książki, ale wszelkie dziedziczone uprawnienia z poprzedniej nadrzędnej książki nie będą skopiowane, co może doprowadzić do zmiany w kontroli dostępu.', 'convert_chapter' => 'Konwertuj rozdział', 'convert_chapter_confirm' => 'Czy na pewno chcesz skonwertować ten rozdział?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/pl/errors.php b/resources/lang/pl/errors.php index e493705b5..b80a5f223 100644 --- a/resources/lang/pl/errors.php +++ b/resources/lang/pl/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Nie znaleziono obiektu', - 'bookshelf_not_found' => 'Nie znaleziono półki', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Nie znaleziono książki', 'page_not_found' => 'Nie znaleziono strony', 'chapter_not_found' => 'Nie znaleziono rozdziału', diff --git a/resources/lang/pl/settings.php b/resources/lang/pl/settings.php index f7ef384e8..27587fbd5 100644 --- a/resources/lang/pl/settings.php +++ b/resources/lang/pl/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Gratulacje! Otrzymałeś tego e-maila więc Twoje ustawienia poczty elektronicznej wydają się być prawidłowo skonfigurowane.', 'maint_recycle_bin_desc' => 'Usunięte półki, książki, rozdziały i strony są wysyłane do kosza, aby mogły zostać przywrócone lub trwale usunięte. Starsze przedmioty w koszu mogą zostać automatycznie usunięte po pewnym czasie w zależności od konfiguracji systemu.', 'maint_recycle_bin_open' => 'Otwórz kosz', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Kosz', diff --git a/resources/lang/pt/activities.php b/resources/lang/pt/activities.php index 7ff77f097..1836faa56 100644 --- a/resources/lang/pt/activities.php +++ b/resources/lang/pt/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Livro reordenado com sucesso', // Bookshelves - 'bookshelf_create' => 'estante criada', - 'bookshelf_create_notification' => 'Estante criada com sucesso', - 'bookshelf_create_from_book' => 'livro convertido para estante', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Livro convertido em prateleira com sucesso', - 'bookshelf_update' => 'estante atualizada', - 'bookshelf_update_notification' => 'Estante atualizada com sucesso', - 'bookshelf_delete' => 'excluiu a prateleira', - 'bookshelf_delete_notification' => 'Estante eliminada com sucesso', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" foi adicionado aos seus favoritos', diff --git a/resources/lang/pt/editor.php b/resources/lang/pt/editor.php index ca9b24f4f..51e99e8e3 100644 --- a/resources/lang/pt/editor.php +++ b/resources/lang/pt/editor.php @@ -157,7 +157,7 @@ return [ 'about' => 'Sobre o editor', 'about_title' => 'Sobre o Editor WYSIWYG', 'editor_license' => 'Editor da licença de direitos autorais', - 'editor_tiny_license' => 'This editor is built using :tinyLink which is provided under the MIT license.', + 'editor_tiny_license' => 'Este editor foi criado com :tinyLink que é fornecido sob a licença MIT.', 'editor_tiny_license_link' => 'Os dados relativos aos direitos de autor e à licença do TinyMCE podem ser encontrados aqui.', 'save_continue' => 'Salvar página e continuar', 'callouts_cycle' => '(Continue pressionando para alternar através de tipos)', diff --git a/resources/lang/pt/entities.php b/resources/lang/pt/entities.php index 9f11b8376..2ec85d6a0 100644 --- a/resources/lang/pt/entities.php +++ b/resources/lang/pt/entities.php @@ -23,8 +23,9 @@ return [ 'meta_updated' => 'Atualizado :timeLength', 'meta_updated_name' => 'Atualizado :timeLength por :user', 'meta_owned_name' => 'Propriedade de :user', + 'meta_reference_page_count' => 'Referenciado em 1 página|Referenciado em :count páginas', 'entity_select' => 'Seleção de Entidade', - 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', + 'entity_select_lack_permission' => 'Não tem as permissões necessárias para selecionar este item', 'images' => 'Imagens', 'my_recent_drafts' => 'Os Meus Rascunhos Recentes', 'my_recently_viewed' => 'Visualizados Recentemente Por Mim', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Estante', 'shelves' => 'Estantes', 'x_shelves' => ':count Estante|:count Estantes', - 'shelves_long' => 'Estantes de Livros', 'shelves_empty' => 'Nenhuma estante foi criada', 'shelves_create' => 'Criar Nova Estante', 'shelves_popular' => 'Estantes Populares', @@ -88,23 +88,23 @@ return [ 'shelves_save' => 'Guardar Estante', 'shelves_books' => 'Livros nesta estante', 'shelves_add_books' => 'Adicionar livros a esta estante', - 'shelves_drag_books' => 'Drag books below to add them to this shelf', + 'shelves_drag_books' => 'Arraste os livros abaixo para adicioná-los a esta prateleira', 'shelves_empty_contents' => 'Esta estante não tem livros atribuídos', 'shelves_edit_and_assign' => 'Editar estante para atribuir livros', - 'shelves_edit_named' => 'Editar Estante de Livros :name', - 'shelves_edit' => 'Editar Estante de Livros', - 'shelves_delete' => 'Eliminar Estante de Livros', - 'shelves_delete_named' => 'Excluir Prateleira de Livros :name', - 'shelves_delete_explain' => "A ação vai eliminar a estante de nome ':name'. Os livros nela presentes não serão eliminados.", - 'shelves_delete_confirmation' => 'Tem a certeza que quer eliminar esta estante de livros?', - 'shelves_permissions' => 'Permissões da Estante', - 'shelves_permissions_updated' => 'Permissões da Estante de Livros Atualizada', - 'shelves_permissions_active' => 'Permissões da Estante de Livros Ativas', - 'shelves_permissions_cascade_warning' => 'As permissões nas estantes não são passadas automaticamente em efeito dominó para os livros contidos. Isto acontece porque um livro pode existir em várias prateleiras. As permissões podem, no entanto, ser copiadas para livros filhos usando a opção encontrada abaixo.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Copiar Permissões para Livros', 'shelves_copy_permissions' => 'Copiar Permissões', - 'shelves_copy_permissions_explain' => 'Isto aplicará as configurações de permissões atuais desta estante a todos os livros nela contidos. Antes de ativar, assegure-se de que quaisquer alterações nas permissões desta estante foram guardadas.', - 'shelves_copy_permission_success' => 'Permissões de estante copiadas para :count livros', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Livro', @@ -171,7 +171,7 @@ return [ 'chapters_permissions_active' => 'Permissões de Capítulo Ativas', 'chapters_permissions_success' => 'Permissões de Capítulo Atualizadas', 'chapters_search_this' => 'Pesquisar neste Capítulo', - 'chapter_sort_book' => 'Sort Book', + 'chapter_sort_book' => 'Ordenar livro', // Pages 'page' => 'Página', @@ -199,8 +199,8 @@ return [ 'pages_edit_delete_draft' => 'Eliminar Rascunho', 'pages_edit_discard_draft' => 'Descartar Rascunho', 'pages_edit_switch_to_markdown' => 'Alternar para o editor Markdown', - 'pages_edit_switch_to_markdown_clean' => '(Clean Content)', - 'pages_edit_switch_to_markdown_stable' => '(Stable Content)', + 'pages_edit_switch_to_markdown_clean' => '(Conteúdo Limitado)', + 'pages_edit_switch_to_markdown_stable' => '(Conteúdo Estável)', 'pages_edit_switch_to_wysiwyg' => 'Alternar para o editor WYSIWYG', 'pages_edit_set_changelog' => 'Relatar Alterações', 'pages_edit_enter_changelog_desc' => 'Digite uma breve descrição das alterações efetuadas por si', @@ -210,7 +210,7 @@ return [ 'pages_editor_switch_consider_following' => 'Considere o seguinte ao alterar editores:', 'pages_editor_switch_consideration_a' => 'Uma vez alterada, o novo editor será usado por quaisquer editores futuros, incluindo aqueles que podem não ser capazes de mudar o tipo do editor.', 'pages_editor_switch_consideration_b' => 'Isso pode levar a uma perda de detalhes e sintaxe em certas circunstâncias.', - 'pages_editor_switch_consideration_c' => 'Tag or changelog changes, made since last save, won\'t persist across this change.', + 'pages_editor_switch_consideration_c' => 'Etiqueta ou alterações no \'changelog\', não guardadas, não persistem nesta alteração.', 'pages_save' => 'Guardar Página', 'pages_title' => 'Título da Página', 'pages_name' => 'Nome da Página', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Editar Conteúdo', 'pages_permissions_active' => 'Permissões de Página Ativas', 'pages_initial_revision' => 'Publicação Inicial', + 'pages_references_update_revision' => 'Atualização automática do sistema de links internos', 'pages_initial_name' => 'Nova Página', 'pages_editing_draft_notification' => 'Você está atualmente a editar um rascunho que foi guardado pela última vez a :timeDiff.', 'pages_draft_edited_notification' => 'Esta página entretanto já foi atualizada. É recomendado que você descarte este rascunho.', @@ -366,7 +367,12 @@ return [ 'convert_book_confirm' => 'Tem a certeza de que deseja converter este livro?', 'convert_undo_warning' => 'Isto não pode ser tão facilmente desfeito.', 'convert_to_book' => 'Converter para Livro', - 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', + 'convert_to_book_desc' => 'Você pode converter este capítulo em um novo livro com o mesmo conteúdo. Qualquer permissão definida neste capítulo será copiada para o novo livro, mas para as permissões herdadas, do livro pai não será copiado que possa levar a uma mudança de controlo de acesso.', 'convert_chapter' => 'Converter Capítulo', 'convert_chapter_confirm' => 'Tem certeza de que deseja converter este capítulo?', + + // References + 'references' => 'Referências', + 'references_none' => 'Não há referências registadas para este item.', + 'references_to_desc' => 'Abaixo estão todas as páginas conhecidas do sistema que vinculam este item.', ]; diff --git a/resources/lang/pt/errors.php b/resources/lang/pt/errors.php index 93b06ad3d..7b43fca19 100644 --- a/resources/lang/pt/errors.php +++ b/resources/lang/pt/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Entidade não encontrada', - 'bookshelf_not_found' => 'Estante de Livros não encontrada', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Livro não encontrado', 'page_not_found' => 'Página não encontrada', 'chapter_not_found' => 'Capítulo não encontrado', diff --git a/resources/lang/pt/settings.php b/resources/lang/pt/settings.php index e6ee7ec34..3a2c9c62f 100644 --- a/resources/lang/pt/settings.php +++ b/resources/lang/pt/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Parabéns! Já que recebeu esta notificação, as suas opções de e-mail parecem estar configuradas corretamente.', 'maint_recycle_bin_desc' => 'Estantes, livros, capítulos e páginas eliminados são mandados para a reciclagem podendo assim ser restaurados ou excluídos permanentemente. Itens mais antigos da podem vir a ser automaticamente removidos da reciclagem após um tempo, dependendo da configuração do sistema.', 'maint_recycle_bin_open' => 'Abrir Reciclagem', + 'maint_regen_references' => 'Regerar Referências', + 'maint_regen_references_desc' => 'Esta ação irá reconstruir o índice de referência no banco de dados. Isto geralmente é tratado automaticamente, mas esta ação pode ser útil para indexar conteúdo antigo ou conteúdo adicionado através de métodos não oficiais.', + 'maint_regen_references_success' => 'Índice de referência foi regenerado!', + 'maint_timeout_command_note' => 'Nota: Esta ação pode levar algum tempo para executar, retornando \'timeout\' em alguns ambientes web. Como alternativa, esta ação pode ser executada via terminal.', // Recycle Bin 'recycle_bin' => 'Reciclagem', diff --git a/resources/lang/pt_BR/activities.php b/resources/lang/pt_BR/activities.php index 0006a9e91..427648312 100644 --- a/resources/lang/pt_BR/activities.php +++ b/resources/lang/pt_BR/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Livro reordenado com sucesso', // Bookshelves - 'bookshelf_create' => 'prateleira criada', - 'bookshelf_create_notification' => 'Prateleira criada com sucesso', - 'bookshelf_create_from_book' => 'livro convertido em estante', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Capítulo convertido com sucesso em um livro', - 'bookshelf_update' => 'atualizou a prateleira', - 'bookshelf_update_notification' => 'Prateleira atualizada com sucesso', - 'bookshelf_delete' => 'excluiu a prateleira', - 'bookshelf_delete_notification' => 'Prateleira excluída com sucesso', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" foi adicionada aos seus favoritos', diff --git a/resources/lang/pt_BR/entities.php b/resources/lang/pt_BR/entities.php index d65e939d8..fbede6da7 100644 --- a/resources/lang/pt_BR/entities.php +++ b/resources/lang/pt_BR/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Atualizado :timeLength', 'meta_updated_name' => 'Atualizado :timeLength por :user', 'meta_owned_name' => 'De :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Seleção de Entidade', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Imagens', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Prateleira', 'shelves' => 'Prateleiras', 'x_shelves' => ':count Prateleira|:count Prateleiras', - 'shelves_long' => 'Prateleiras de Livros', 'shelves_empty' => 'Nenhuma prateleira foi criada', 'shelves_create' => 'Criar Nova Prateleira', 'shelves_popular' => 'Prateleiras Populares', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'Esta prateleira não possui livros atribuídos a ela', 'shelves_edit_and_assign' => 'Editar prateleira para atribuir livros', - 'shelves_edit_named' => 'Editar Prateleira de Livros :name', - 'shelves_edit' => 'Edit Prateleira de Livros', - 'shelves_delete' => 'Excluir Prateleira de Livros', - 'shelves_delete_named' => 'Excluir Prateleira de Livros :name', - 'shelves_delete_explain' => "A ação vai excluír a prateleira com o nome ':name'. Livros contidos não serão excluídos.", - 'shelves_delete_confirmation' => 'Você tem certeza que quer excluir esta prateleira de livros?', - 'shelves_permissions' => 'Permissões da Prateleira', - 'shelves_permissions_updated' => 'Permissões da Prateleira Atualizadas', - 'shelves_permissions_active' => 'Permissões da Prateleira Ativas', - 'shelves_permissions_cascade_warning' => 'As permissões nas estantes não são automaticamente cascatas para conter livros. Isto ocorre porque um livro existe em várias prateleiras. As permissões podem, no entanto, ser copiadas para livros filhos usando a opção encontrada abaixo.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Copiar Permissões para Livros', 'shelves_copy_permissions' => 'Copiar Permissões', - 'shelves_copy_permissions_explain' => 'Isto aplicará as configurações de permissões atuais desta prateleira a todos os livros contidos nela. Antes de ativar, assegure-se de que quaisquer alterações nas permissões desta prateleira tenham sido salvas.', - 'shelves_copy_permission_success' => 'Permissões da prateleira copiadas para :count livros', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Livro', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Editar Conteúdo', 'pages_permissions_active' => 'Permissões de Página Ativas', 'pages_initial_revision' => 'Publicação Inicial', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Nova Página', 'pages_editing_draft_notification' => 'Você está atualmente editando um rascunho que foi salvo da última vez em :timeDiff.', 'pages_draft_edited_notification' => 'Essa página foi atualizada desde então. É recomendado que você descarte esse rascunho.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/pt_BR/errors.php b/resources/lang/pt_BR/errors.php index 1ebc28f8c..afa0b3962 100644 --- a/resources/lang/pt_BR/errors.php +++ b/resources/lang/pt_BR/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Entidade não encontrada', - 'bookshelf_not_found' => 'Prateleira de Livros não encontrada', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Livro não encontrado', 'page_not_found' => 'Página não encontrada', 'chapter_not_found' => 'Capítulo não encontrado', diff --git a/resources/lang/pt_BR/settings.php b/resources/lang/pt_BR/settings.php index 8773ce865..7b8234c59 100644 --- a/resources/lang/pt_BR/settings.php +++ b/resources/lang/pt_BR/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Parabéns! Já que você recebeu esta notificação, suas opções de e-mail parecem estar configuradas corretamente.', 'maint_recycle_bin_desc' => 'Prateleiras, livros, capítulos e páginas deletados são mandados para a lixeira podendo assim ser restaurados ou excluídos permanentemente. Itens mais antigos da lixeira podem vir a ser automaticamente removidos da lixeira após um tempo dependendo da configuração do sistema.', 'maint_recycle_bin_open' => 'Abrir Lixeira', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Lixeira', diff --git a/resources/lang/ro/activities.php b/resources/lang/ro/activities.php new file mode 100644 index 000000000..92fc94740 --- /dev/null +++ b/resources/lang/ro/activities.php @@ -0,0 +1,73 @@ + 'a creat pagina', + 'page_create_notification' => 'Pagina creată cu succes', + 'page_update' => 'a actualizat pagina', + 'page_update_notification' => 'Pagina a fost actualizată cu succes', + 'page_delete' => 'a șters pagina', + 'page_delete_notification' => 'Pagina a fost ștearsă cu succes', + 'page_restore' => 'a restabilit pagina', + 'page_restore_notification' => 'Pagina a fost restaurată cu succes', + 'page_move' => 'a mutat pagina', + + // Chapters + 'chapter_create' => 'a creat capitolul', + 'chapter_create_notification' => 'Capitol creat cu succes', + 'chapter_update' => 'a actualizat capitolul', + 'chapter_update_notification' => 'Capitolul a fost actualizat cu succes', + 'chapter_delete' => 'a șters capitolul', + 'chapter_delete_notification' => 'Capitolul a fost șters cu succes', + 'chapter_move' => 'a mutat capitolul', + + // Books + 'book_create' => 'a creat cartea', + 'book_create_notification' => 'Carte creată cu succes', + 'book_create_from_chapter' => 'a convertit capitolul în carte', + 'book_create_from_chapter_notification' => 'Capitol convertit cu succes într-o carte', + 'book_update' => 'a actualizat cartea', + 'book_update_notification' => 'Carte actualizată cu succes', + 'book_delete' => 'a șters cartea', + 'book_delete_notification' => 'Carte ștearsă cu succes', + 'book_sort' => 'a sortat cartea', + 'book_sort_notification' => 'Carte reordonată cu succes', + + // Bookshelves + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', + 'bookshelf_create_from_book_notification' => 'Carte transformată cu succes într-un raft', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', + + // Favourites + 'favourite_add_notification' => '":name" a fost adăugat la favorite', + 'favourite_remove_notification' => '":name" a fost eliminat din favorite', + + // MFA + 'mfa_setup_method_notification' => 'Metoda multi-factor a fost configurată cu succes', + 'mfa_remove_method_notification' => 'Metoda multi-factor a fost configurată cu succes', + + // Webhooks + 'webhook_create' => 'a creat webhook', + 'webhook_create_notification' => 'Webhook creat cu succes', + 'webhook_update' => 'a actualizat webhook', + 'webhook_update_notification' => 'Webhook actualizat cu succes', + 'webhook_delete' => 'a șters webhook', + 'webhook_delete_notification' => 'Webhook șters cu succes', + + // Users + 'user_update_notification' => 'Utilizator actualizat cu succes', + 'user_delete_notification' => 'Utilizator eliminat cu succes', + + // Other + 'commented_on' => 'a comentat la', + 'permissions_update' => 'a actualizat permisiunile', +]; diff --git a/resources/lang/ro/auth.php b/resources/lang/ro/auth.php new file mode 100644 index 000000000..05a01c6c6 --- /dev/null +++ b/resources/lang/ro/auth.php @@ -0,0 +1,115 @@ + 'Aceste credenţiale nu se potrivesc cu înregistrările noastre.', + 'throttle' => 'Prea multe încercări de conectare. Vă rugăm să încercați din nou în :seconds secunde.', + + // Login & Register + 'sign_up' => 'Inregistrează-te', + 'log_in' => 'Autentifică-te', + 'log_in_with' => 'Autentifică-te cu :socialDriver', + 'sign_up_with' => 'Inregistrează-te cu :socialDriver', + 'logout' => 'Deconectează-te', + + 'name' => 'Nume', + 'username' => 'Nume utilizator', + 'email' => 'E-mail', + 'password' => 'Parolă', + 'password_confirm' => 'Confirmă parola', + 'password_hint' => 'Trebuie să aibă cel puțin 8 caractere', + 'forgot_password' => 'Ai uitat parola?', + 'remember_me' => 'Amintește-ți de mine', + 'ldap_email_hint' => 'Te rog să introduci o adresa de e-mail pentru a utiliza acest cont.', + 'create_account' => 'Crează cont', + 'already_have_account' => 'Ai deja cont?', + 'dont_have_account' => 'Nu ai cont?', + 'social_login' => 'Conectare folosind rețea socială', + 'social_registration' => 'Înregistrare cu rețea socială', + 'social_registration_text' => 'Înregistrați-vă și conectați-vă utilizând alt serviciu.', + + 'register_thanks' => 'Mulțumesc pentru înregistrare!', + 'register_confirm' => 'Verifică-ți e-mailul și dă clic pe butonul de confirmare pentru a accesa :appName.', + 'registrations_disabled' => 'Înregistrările sunt momentan dezactivate', + 'registration_email_domain_invalid' => 'Acel domeniu de e-mail nu are acces la această aplicație', + 'register_success' => 'Mulțumesc pentru înscriere! Acum sunteți înregistrat și conectat.', + + // Login auto-initiation + 'auto_init_starting' => 'Se încearcă autentificarea', + 'auto_init_starting_desc' => 'Vă contactăm sistemul de autentificare pentru a începe procesul de conectare. Dacă nu există niciun progres după 5 secunde, puteți încerca să dați clic pe linkul de mai jos.', + 'auto_init_start_link' => 'Continuă cu autentificarea', + + // Password Reset + 'reset_password' => 'Resetează parola', + 'reset_password_send_instructions' => 'Introduceți adresa de e-mail mai jos și vi se va trimite un e-mail cu un link pentru resetarea parolei.', + 'reset_password_send_button' => 'Trimite linkul de resetare', + 'reset_password_sent' => 'Un link pentru resetarea parolei va fi trimis la :email dacă acea adresă de e-mail este găsită în sistem.', + 'reset_password_success' => 'Parola a fost resetată cu succes.', + 'email_reset_subject' => 'Resetează parola ta :appName', + 'email_reset_text' => 'Primești acest e-mail deoarece am primit o solicitare de resetare a parolei pentru contul tău.', + 'email_reset_not_requested' => 'Dacă nu ai solicitat resetarea parolei, nu este necesară nicio acțiune suplimentară.', + + // Email Confirmation + 'email_confirm_subject' => 'Confirmă e-mailul pentru :appName', + 'email_confirm_greeting' => 'Mulțumim că te-ai alăturat :appName!', + 'email_confirm_text' => 'Te rog să confirmi adresa ta de e-mail făcând clic pe butonul de mai jos:', + 'email_confirm_action' => 'Confirmă emailul', + 'email_confirm_send_error' => 'Este necesară confirmarea prin e-mail, dar sistemul nu a putut trimite e-mailul. Contactează administratorul pentru a te asigura că e-mailul este configurat corect.', + 'email_confirm_success' => 'E-mailul a fost confirmat! Acum ar trebui să te poți autentifica folosind această adresă de e-mail.', + 'email_confirm_resent' => 'E-mailul de confirmare a fost retrimis, te rugăm să îți verifici căsuța de e-mail.', + + 'email_not_confirmed' => 'Adresa de e-mail neconfirmată', + 'email_not_confirmed_text' => 'Adresa ta de e-mail nu a fost încă confirmată.', + 'email_not_confirmed_click_link' => 'Accesează linkul din e-mailul care a fost trimis la scurt timp după ce te-ai înregistrat.', + 'email_not_confirmed_resend' => 'Dacă nu găsești e-mailul, poți retrimite e-mailul de confirmare completând formularul de mai jos.', + 'email_not_confirmed_resend_button' => 'Retrimite e-mail de confirmare', + + // User Invite + 'user_invite_email_subject' => 'Ai fost invitat să te alături :appName!', + 'user_invite_email_greeting' => 'A fost creat un cont pentru tine pe :appName.', + 'user_invite_email_text' => 'Fă clic pe butonul de mai jos pentru a seta o parolă de cont și a obține acces:', + 'user_invite_email_action' => 'Setează parola contului', + 'user_invite_page_welcome' => 'Bun venit la :appName!', + 'user_invite_page_text' => 'Pentru a vă finaliza configurarea contului și a obține acces, trebuie să setezi o parolă care va fi folosită pentru a te conecta la :appName la vizitele viitoare.', + 'user_invite_page_confirm_button' => 'Confirmă parola', + 'user_invite_success_login' => 'Parola setată, acum ar trebui să te poți autentifica folosind parola setată pentru a accesa :appName!', + + // Multi-factor Authentication + 'mfa_setup' => 'Configurează autentificarea cu mai mulți factori de autentificare', + 'mfa_setup_desc' => 'Configurează autentificarea cu mai mulți factori ca un nivel suplimentar de securitate pentru contul tău de utilizator.', + 'mfa_setup_configured' => 'Deja configurat', + 'mfa_setup_reconfigure' => 'Reconfigurează', + 'mfa_setup_remove_confirmation' => 'Sigur dorești să elimini această metodă de autentificare cu mai mulți factori?', + 'mfa_setup_action' => 'Configurare', + 'mfa_backup_codes_usage_limit_warning' => 'Mai ai mai puțin de 5 coduri de rezervă rămase. Vă rugăm să generați și să stocați un nou set înainte de a rămâne fără coduri pentru a preveni blocarea contului.', + 'mfa_option_totp_title' => 'Aplicație mobilă', + 'mfa_option_totp_desc' => 'Pentru a utiliza autentificarea multifactor, vei avea nevoie de o aplicație mobilă care acceptă TOTP, cum ar fi Google Authenticator, Authy sau Microsoft Authenticator.', + 'mfa_option_backup_codes_title' => 'Coduri de rezervă', + 'mfa_option_backup_codes_desc' => 'Stochează în siguranță un set de coduri de rezervă de unică folosință pe care le poți introduce pentru verificarea identității.', + 'mfa_gen_confirm_and_enable' => 'Confirmă și activează', + 'mfa_gen_backup_codes_title' => 'Configurarea codurilor de rezervă', + 'mfa_gen_backup_codes_desc' => 'Păstrează lista de coduri de mai jos într-un loc sigur. Când accesezi sistemul, vei putea folosi unul dintre coduri ca un al doilea mecanism de autentificare.', + 'mfa_gen_backup_codes_download' => 'Descarcă codurile', + 'mfa_gen_backup_codes_usage_warning' => 'Fiecare cod poate fi folosit o singură dată', + 'mfa_gen_totp_title' => 'Configurare aplicație mobilă', + 'mfa_gen_totp_desc' => 'Pentru a utiliza autentificarea cu mai mulți factori, vei avea nevoie de o aplicație mobilă care acceptă TOTP, cum ar fi Google Authenticator, Authy sau Microsoft Authenticator.', + 'mfa_gen_totp_scan' => 'Scanează codul QR de mai jos folosind aplicația de autentificare preferată pentru a începe.', + 'mfa_gen_totp_verify_setup' => 'Verifică configurarea', + 'mfa_gen_totp_verify_setup_desc' => 'Verifică dacă totul funcționează introducând un cod, generat în aplicația de autentificare, în caseta de introducere de mai jos:', + 'mfa_gen_totp_provide_code_here' => 'Furnizează aici codul generat de aplicație', + 'mfa_verify_access' => 'Verifică accesul', + 'mfa_verify_access_desc' => 'Contul tău de utilizator necesită să îți confirmi identitatea printr-un nivel suplimentar de verificare înainte de acordare acces. Verifică folosind una dintre metodele configurate pentru a continua.', + 'mfa_verify_no_methods' => 'Nicio metodă configurată', + 'mfa_verify_no_methods_desc' => 'Nu s-au găsit metode de autentificare cu mai mulți factori pentru contul tău. Va trebui să configurezi cel puțin o metodă înainte de a obține acces.', + 'mfa_verify_use_totp' => 'Verifică folosind o aplicație mobilă', + 'mfa_verify_use_backup_codes' => 'Verifică folosind un cod de rezervă', + 'mfa_verify_backup_code' => 'Cod de rezervă', + 'mfa_verify_backup_code_desc' => 'Introdu unul dintre codurile de rezervă rămase mai jos:', + 'mfa_verify_backup_code_enter_here' => 'Introdu codul de rezervă aici', + 'mfa_verify_totp_desc' => 'Introdu codul, generat folosind aplicația mobilă, mai jos:', + 'mfa_setup_login_notification' => 'Metodă multifactorială configurată. Te rog să te conectezi din nou folosind metoda configurată.', +]; diff --git a/resources/lang/ro/common.php b/resources/lang/ro/common.php new file mode 100644 index 000000000..a98a20bee --- /dev/null +++ b/resources/lang/ro/common.php @@ -0,0 +1,104 @@ + 'Anulează', + 'confirm' => 'Confirmă', + 'back' => 'Înapoi', + 'save' => 'Salvează', + 'continue' => 'Continuă', + 'select' => 'Selecteză', + 'toggle_all' => 'Comutați toate', + 'more' => 'Mai mult', + + // Form Labels + 'name' => 'Nume', + 'description' => 'Descriere', + 'role' => 'Rol', + 'cover_image' => 'Imagine copertă', + 'cover_image_description' => 'Această imagine ar trebui să aibă aproximativ 440x250px.', + + // Actions + 'actions' => 'Acțiuni', + 'view' => 'Vizualizare', + 'view_all' => 'Vizualizează tot', + 'create' => 'Crează', + 'update' => 'Actualzează', + 'edit' => 'Editează', + 'sort' => 'Sortează', + 'move' => 'Mută', + 'copy' => 'Copiază', + 'reply' => 'Răspunde', + 'delete' => 'Șterge', + 'delete_confirm' => 'Confirmă ștergerea', + 'search' => 'Caută', + 'search_clear' => 'Șterge căutarea', + 'reset' => 'Resetează', + 'remove' => 'Elimină', + 'add' => 'Adaugă', + 'configure' => 'Configurează', + 'fullscreen' => 'Ecran complet', + 'favourite' => 'Adaugă la favorite', + 'unfavourite' => 'Șterge de la favorite', + 'next' => 'Următorul', + 'previous' => 'Anterior', + 'filter_active' => 'Filtru activ:', + 'filter_clear' => 'Șterge filtru', + 'download' => 'Descarcă', + 'open_in_tab' => 'Deschide in tab', + + // Sort Options + 'sort_options' => 'Opțiuni ordonare', + 'sort_direction_toggle' => 'Comutare direcție sortare', + 'sort_ascending' => 'Ordonează crescător', + 'sort_descending' => 'Ordonează descrescător', + 'sort_name' => 'Nume', + 'sort_default' => 'Implicit', + 'sort_created_at' => 'Data creării', + 'sort_updated_at' => 'Data actualizării', + + // Misc + 'deleted_user' => 'Utilizator șters', + 'no_activity' => 'Nicio activitate de afișat', + 'no_items' => 'Niciun articol disponibil', + 'back_to_top' => 'Înapoi sus', + 'skip_to_main_content' => 'Treci la conținutul principal', + 'toggle_details' => 'Comută detaliile', + 'toggle_thumbnails' => 'Comută miniaturi', + 'details' => 'Detalii', + 'grid_view' => 'Vizualizare grilă', + 'list_view' => 'Vizualizare listă', + 'default' => 'Implicit', + 'breadcrumb' => 'Navigare', + 'status' => 'Status', + 'status_active' => 'Activ', + 'status_inactive' => 'Inactiv', + 'never' => 'Niciodată', + 'none' => 'Niciunul', + + // Header + 'header_menu_expand' => 'Extindere meniu antet', + 'profile_menu' => 'Meniu profil', + 'view_profile' => 'Vezi profil', + 'edit_profile' => 'Editare profil', + 'dark_mode' => 'Mod întunecat', + 'light_mode' => 'Mod luminos', + + // Layout tabs + 'tab_info' => 'Informații', + 'tab_info_label' => 'Tab: Arată informații secundare', + 'tab_content' => 'Conținut', + 'tab_content_label' => 'Tab: Arată conţinutul primar', + + // Email Content + 'email_action_help' => 'Dacă întâmpini probleme la apăsarea butonului ":actionText", copiază și inserează URL-ul de mai jos în browser-ul web:', + 'email_rights' => 'Toate drepturile rezervate', + + // Footer Link Options + // Not directly used but available for convenience to users. + 'privacy_policy' => 'Politică de confidențialitate', + 'terms_of_service' => 'Termeni și condiții', +]; diff --git a/resources/lang/ro/components.php b/resources/lang/ro/components.php new file mode 100644 index 000000000..1284ca104 --- /dev/null +++ b/resources/lang/ro/components.php @@ -0,0 +1,34 @@ + 'Selectează imaginea', + 'image_all' => 'Tot', + 'image_all_title' => 'Vezi toate imaginile', + 'image_book_title' => 'Vezi imaginile încărcate în această carte', + 'image_page_title' => 'Vezi imaginile încărcate în această pagină', + 'image_search_hint' => 'Caută după numele imaginii', + 'image_uploaded' => 'Încărcat la :uploadedDate', + 'image_load_more' => 'Încarcă mai mult', + 'image_image_name' => 'Nume imagine', + 'image_delete_used' => 'Această imagine este folosită în paginile de mai jos.', + 'image_delete_confirm_text' => 'Ești sigur că vrei să ștergi această imagine?', + 'image_select_image' => 'Selectează imaginea', + 'image_dropzone' => 'Trage imaginile sau apasă aici pentru a le încărca', + 'images_deleted' => 'Imagini șterse', + 'image_preview' => 'Previzualizare imagine', + 'image_upload_success' => 'Imaginea a fost încărcată cu succes', + 'image_update_success' => 'Detalii imagine actualizate cu succes', + 'image_delete_success' => 'Imaginea a fost ștearsă', + 'image_upload_remove' => 'Elimină', + + // Code Editor + 'code_editor' => 'Editare cod', + 'code_language' => 'Limba codului', + 'code_content' => 'Conținut cod', + 'code_session_history' => 'Istoric sesiune', + 'code_save' => 'Salvează cod', +]; diff --git a/resources/lang/ro/editor.php b/resources/lang/ro/editor.php new file mode 100644 index 000000000..384d93212 --- /dev/null +++ b/resources/lang/ro/editor.php @@ -0,0 +1,171 @@ + 'General', + 'advanced' => 'Avansat', + 'none' => 'Niciunul', + 'cancel' => 'Anulează', + 'save' => 'Salvează', + 'close' => 'Închide', + 'undo' => 'Anulează', + 'redo' => 'Refă', + 'left' => 'Stânga', + 'center' => 'Centru', + 'right' => 'Dreapta', + 'top' => 'Sus', + 'middle' => 'Mijloc', + 'bottom' => 'Jos', + 'width' => 'Lățime', + 'height' => 'Înălțime', + 'More' => 'Mai mult', + 'select' => 'Selectează...', + + // Toolbar + 'formats' => 'Formate', + 'header_large' => 'Antet mare', + 'header_medium' => 'Antet mediu', + 'header_small' => 'Antet mic', + 'header_tiny' => 'Antet minuscul', + 'paragraph' => 'Paragraf', + 'blockquote' => 'Citat', + 'inline_code' => 'Cod inline', + 'callouts' => 'Indicații', + 'callout_information' => 'Informație', + 'callout_success' => 'Succes', + 'callout_warning' => 'Avertisment', + 'callout_danger' => 'Pericol', + 'bold' => 'Îngroșat', + 'italic' => 'Italic', + 'underline' => 'Subliniat', + 'strikethrough' => 'Tăiat cu o linie', + 'superscript' => 'Scris sus', + 'subscript' => 'Scris jos', + 'text_color' => 'Culoare text', + 'custom_color' => 'Culoare personalizată', + 'remove_color' => 'Elimină culoarea', + 'background_color' => 'Culoare fundal', + 'align_left' => 'Aliniere la stânga', + 'align_center' => 'Aliniere în centru', + 'align_right' => 'Aliniere la dreapta', + 'align_justify' => 'Margini egale', + 'list_bullet' => 'Listă cu puncte', + 'list_numbered' => 'Listă numerotată', + 'list_task' => 'Listă de sarcini', + 'indent_increase' => 'Crește indentarea', + 'indent_decrease' => 'Scade indentarea', + 'table' => 'Tabel', + 'insert_image' => 'Inserare imagine', + 'insert_image_title' => 'Inserare/Editare Imagine', + 'insert_link' => 'Inserare/editare link', + 'insert_link_title' => 'Inserare/Editare link', + 'insert_horizontal_line' => 'Inserează linie orizontală', + 'insert_code_block' => 'Inserează bloc de cod', + 'insert_drawing' => 'Inserare/editare desen', + 'drawing_manager' => 'Manager de desene', + 'insert_media' => 'Inserare/editare media', + 'insert_media_title' => 'Inserare/Editare media', + 'clear_formatting' => 'Șterge formatarea', + 'source_code' => 'Cod sursă', + 'source_code_title' => 'Cod sursă', + 'fullscreen' => 'Ecran complet', + 'image_options' => 'Opțiuni imagine', + + // Tables + 'table_properties' => 'Proprietăți tabel', + 'table_properties_title' => 'Proprietăți tabel', + 'delete_table' => 'Șterge tabel', + 'insert_row_before' => 'Inserează rând după', + 'insert_row_after' => 'Inserează rând înainte', + 'delete_row' => 'Șterge rând', + 'insert_column_before' => 'Inserare coloană înainte', + 'insert_column_after' => 'Inserare coloană după', + 'delete_column' => 'Șterge coloana', + 'table_cell' => 'Celulă', + 'table_row' => 'Rând', + 'table_column' => 'Coloană', + 'cell_properties' => 'Proprietăți celulă', + 'cell_properties_title' => 'Proprietăți celulă', + 'cell_type' => 'Tip celulă', + 'cell_type_cell' => 'Celulă', + 'cell_scope' => 'Scop', + 'cell_type_header' => 'Celulă antet', + 'merge_cells' => 'Îmbină celule', + 'split_cell' => 'Scindare celulă', + 'table_row_group' => 'Grup rând', + 'table_column_group' => 'Grup Coloană', + 'horizontal_align' => 'Aliniere orizontală', + 'vertical_align' => 'Aliniere verticală', + 'border_width' => 'Lățime margine', + 'border_style' => 'Stil margine', + 'border_color' => 'Culoare margine', + 'row_properties' => 'Proprietăți rând', + 'row_properties_title' => 'Proprietăți rând', + 'cut_row' => 'Taie rândul', + 'copy_row' => 'Copiază rândul', + 'paste_row_before' => 'Inserează rând înainte', + 'paste_row_after' => 'Inserează rând după', + 'row_type' => 'Tip rând', + 'row_type_header' => 'Antet', + 'row_type_body' => 'Corp', + 'row_type_footer' => 'Subsol', + 'alignment' => 'Aliniere', + 'cut_column' => 'Șterge coloana', + 'copy_column' => 'Copiază coloana', + 'paste_column_before' => 'Lipiți coloana înainte', + 'paste_column_after' => 'Lipește coloana după', + 'cell_padding' => 'Spațiere celulă', + 'cell_spacing' => 'Spațiere celulară', + 'caption' => 'Titlu', + 'show_caption' => 'Afișează legenda', + 'constrain' => 'Proporții constrângeri', + 'cell_border_solid' => 'Solid', + 'cell_border_dotted' => 'Punctat', + 'cell_border_dashed' => 'Liniuțe', + 'cell_border_double' => 'Duble', + 'cell_border_groove' => 'Groove', + 'cell_border_ridge' => 'Creastă', + 'cell_border_inset' => 'Inserat', + 'cell_border_outset' => 'Început', + 'cell_border_none' => 'Niciunul', + 'cell_border_hidden' => 'Ascuns', + + // Images, links, details/summary & embed + 'source' => 'Sursă', + 'alt_desc' => 'Descriere alternativă', + 'embed' => 'Încorporează', + 'paste_embed' => 'Lipește codul încorporat mai jos:', + 'url' => 'URL', + 'text_to_display' => 'Text de afișat', + 'title' => 'Titlu', + 'open_link' => 'Deschie link în...', + 'open_link_current' => 'Fereastra curentă', + 'open_link_new' => 'Fereastră nouă', + 'insert_collapsible' => 'Inserează bloc colapsabil', + 'collapsible_unwrap' => 'Desfășoară', + 'edit_label' => 'Editează eticheta', + 'toggle_open_closed' => 'Comută deschis/închis', + 'collapsible_edit' => 'Editează bloc colapsabil', + 'toggle_label' => 'Comută etichetă', + + // About view + 'about' => 'Despre editor', + 'about_title' => 'Despre editorul WYSIWYG', + 'editor_license' => 'Editor licență și drepturi de autor', + 'editor_tiny_license' => 'Acest editor este construit folosind :tinyLink care este furnizat sub licența MIT.', + 'editor_tiny_license_link' => 'Detaliile privind drepturile de autor şi licența TinyMCE pot fi consultate aici.', + 'save_continue' => 'Salvează pagina și continuă', + 'callouts_cycle' => '(Continuă să apăși pentru a comuta prin tipuri)', + 'link_selector' => 'Link către conținut', + 'shortcuts' => 'Scurtături', + 'shortcut' => 'Scurtătură', + 'shortcuts_intro' => 'Următoarele comenzi rapide sunt disponibile în editor:', + 'windows_linux' => '(Windows/Linux)', + 'mac' => '(Mac)', + 'description' => 'Descriere', +]; diff --git a/resources/lang/ro/entities.php b/resources/lang/ro/entities.php new file mode 100644 index 000000000..5822c3233 --- /dev/null +++ b/resources/lang/ro/entities.php @@ -0,0 +1,378 @@ + 'Creat recent', + 'recently_created_pages' => 'Pagini create recent', + 'recently_updated_pages' => 'Pagini actualizate recent', + 'recently_created_chapters' => 'Capitole create recent', + 'recently_created_books' => 'Cărți create recent', + 'recently_created_shelves' => 'Rafturi create recent', + 'recently_update' => 'Actualizate recent', + 'recently_viewed' => 'Vizualizate recent', + 'recent_activity' => 'Activitate recentă', + 'create_now' => 'Creează unul acum', + 'revisions' => 'Revizii', + 'meta_revision' => 'Revizuirea #:revisionCount', + 'meta_created' => 'Creat :timeLungime', + 'meta_created_name' => 'Creat de :timeLlungime de :user', + 'meta_updated' => 'Actualizat :timeLungime', + 'meta_updated_name' => 'Actualizat :timeLength de :user', + 'meta_owned_name' => 'Deținut de :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', + 'entity_select' => 'Selectare entitate', + 'entity_select_lack_permission' => 'Nu ai drepturile necesare pentru a selecta acest element', + 'images' => 'Imagini', + 'my_recent_drafts' => 'Ciornele mele recente', + 'my_recently_viewed' => 'Vizualizarea mea recentă', + 'my_most_viewed_favourites' => 'Favoritele mele cele mai vizualizate', + 'my_favourites' => 'Favoritele Mele', + 'no_pages_viewed' => 'Nu ai vizualizat nicio pagină', + 'no_pages_recently_created' => 'Nicio pagină nu a fost creată recent', + 'no_pages_recently_updated' => 'Nicio pagină nu a fost actualizată recent', + 'export' => 'Exportă', + 'export_html' => 'Fișier web inclus', + 'export_pdf' => 'Fișier PDF', + 'export_text' => 'Fișier text simplu', + 'export_md' => 'Fișier Markdown', + + // Permissions and restrictions + 'permissions' => 'Permisiuni', + 'permissions_intro' => 'Odată activat, aceste permisiuni vor avea prioritate față de toate permisiunile de rol stabilite.', + 'permissions_enable' => 'Activare permisiuni personalizate', + 'permissions_save' => 'Salvează permisiuni', + 'permissions_owner' => 'Proprietar', + + // Search + 'search_results' => 'Rezultatele căutării', + 'search_total_results_found' => ':count rezultat găsit|:count rezultate totale găsite', + 'search_clear' => 'Șterge căutarea', + 'search_no_pages' => 'Nicio pagină nu se potrivește cu această căutare', + 'search_for_term' => 'Caută după :term', + 'search_more' => 'Mai multe rezultate', + 'search_advanced' => 'Căutare avansată', + 'search_terms' => 'Termeni de căutare', + 'search_content_type' => 'Tip conținut', + 'search_exact_matches' => 'Potriviri exacte', + 'search_tags' => 'Căutări cu etichete', + 'search_options' => 'Opţiuni', + 'search_viewed_by_me' => 'Vizualizat de mine', + 'search_not_viewed_by_me' => 'Nevizualizate de mine', + 'search_permissions_set' => 'Permisiuni setate', + 'search_created_by_me' => 'Creat de mine', + 'search_updated_by_me' => 'Actualizat de mine', + 'search_owned_by_me' => 'Deținut de mine', + 'search_date_options' => 'Opțiuni dată', + 'search_updated_before' => 'Actualizat înainte de', + 'search_updated_after' => 'Actualizat după', + 'search_created_before' => 'Creat înainte de', + 'search_created_after' => 'Creat după', + 'search_set_date' => 'Setează data', + 'search_update' => 'Actualizează căutarea', + + // Shelves + 'shelf' => 'Raft', + 'shelves' => 'Rafturi', + 'x_shelves' => ':count Raft|:count Rafturi', + 'shelves_empty' => 'Nu a fost creat niciun raft', + 'shelves_create' => 'Creează raft nou', + 'shelves_popular' => 'Rafturi populare', + 'shelves_new' => 'Rafturi noi', + 'shelves_new_action' => 'Raft nou', + 'shelves_popular_empty' => 'Cele mai populare rafturi vor apărea aici.', + 'shelves_new_empty' => 'Cele mai recente rafturi vor apărea aici.', + 'shelves_save' => 'Salvează raft', + 'shelves_books' => 'Cărți pe acest raft', + 'shelves_add_books' => 'Adaugă cărți pe acest raft', + 'shelves_drag_books' => 'Trage cărțile mai jos pentru a le adăuga pe acest raft', + 'shelves_empty_contents' => 'Acest raft nu are cărți atribuite lui', + 'shelves_edit_and_assign' => 'Editare raft pentru a atribui cărți', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', + 'shelves_copy_permissions_to_books' => 'Copiază permisiunile către cărți', + 'shelves_copy_permissions' => 'Copiază permisiunile', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', + + // Books + 'book' => 'Carte', + 'books' => 'Cărți', + 'x_books' => ':count Carte|:count Cărți', + 'books_empty' => 'Nicio carte nu a fost creată', + 'books_popular' => 'Cărți populare', + 'books_recent' => 'Cărți recente', + 'books_new' => 'Cărți noi', + 'books_new_action' => 'Carte nouă', + 'books_popular_empty' => 'Cele mai populare cărți vor apărea aici.', + 'books_new_empty' => 'Cele mai recente cărți create vor apărea aici.', + 'books_create' => 'Creează o carte nouă', + 'books_delete' => 'Șterge carte', + 'books_delete_named' => 'Șterge cartea :bookName', + 'books_delete_explain' => 'Aceasta operațiune va șterge cartea cu numele \':bookName\'. Toate paginile și capitolele vor fi eliminate.', + 'books_delete_confirmation' => 'Ești sigur că vrei să ștergi această carte?', + 'books_edit' => 'Editează carte', + 'books_edit_named' => 'Editează cartea :bookName', + 'books_form_book_name' => 'Nume carte', + 'books_save' => 'Salvează cartea', + 'books_permissions' => 'Permisiuni carte', + 'books_permissions_updated' => 'Permisiuni carte actualizate', + 'books_empty_contents' => 'Nu au fost create pagini sau capitole pentru această carte.', + 'books_empty_create_page' => 'Creează pagină nouă', + 'books_empty_sort_current_book' => 'Sortează cartea curentă', + 'books_empty_add_chapter' => 'Adaugă un capitol', + 'books_permissions_active' => 'Permisiuni carte active', + 'books_search_this' => 'Caută în această carte', + 'books_navigation' => 'Navigare carte', + 'books_sort' => 'Sortează conținutul cărții', + 'books_sort_named' => 'Sortează cartea :bookName', + 'books_sort_name' => 'Sortează după nume', + 'books_sort_created' => 'Sortează după data creării', + 'books_sort_updated' => 'Sortează după data actualizării', + 'books_sort_chapters_first' => 'Capitole mai întâi', + 'books_sort_chapters_last' => 'Capitole la final', + 'books_sort_show_other' => 'Arată alte cărți', + 'books_sort_save' => 'Salvează noua ordine', + 'books_copy' => 'Copiază cartea', + 'books_copy_success' => 'Carte copiată cu succes', + + // Chapters + 'chapter' => 'Capitol', + 'chapters' => 'Capitole', + 'x_chapters' => ':count Capitol|:count Capitole', + 'chapters_popular' => 'Capitole populare', + 'chapters_new' => 'Capitol nou', + 'chapters_create' => 'Creează un nou capitol', + 'chapters_delete' => 'Șterge capitol', + 'chapters_delete_named' => 'Şterge capitolul :chapterName', + 'chapters_delete_explain' => 'Se va șterge capitolul cu numele \':chapterName\'. Toate paginile care există în acest capitol vor fi, de asemenea, șterse.', + 'chapters_delete_confirm' => 'Ești sigur că vrei să ștergi acest capitol?', + 'chapters_edit' => 'Editează capitol', + 'chapters_edit_named' => 'Editați capitolul :chapterName', + 'chapters_save' => 'Salvează capitolul', + 'chapters_move' => 'Mută capitolul', + 'chapters_move_named' => 'Mutați capitolul :chapterName', + 'chapter_move_success' => 'Capitol mutat la :bookName', + 'chapters_copy' => 'Copiază capitolul', + 'chapters_copy_success' => 'Capitolul a fost copiat', + 'chapters_permissions' => 'Permisiuni capitol', + 'chapters_empty' => 'În prezent nu există pagini în acest capitol.', + 'chapters_permissions_active' => 'Permisiuni capitol active', + 'chapters_permissions_success' => 'Permisiuni capitol actualizate', + 'chapters_search_this' => 'Caută în acest capitol', + 'chapter_sort_book' => 'Ordonare carte', + + // Pages + 'page' => 'Pagină', + 'pages' => 'Pagini', + 'x_pages' => ':count Pagină|:count Pagini', + 'pages_popular' => 'Pagini populare', + 'pages_new' => 'Pagină nouă', + 'pages_attachments' => 'Atașamente', + 'pages_navigation' => 'Navigație pagină', + 'pages_delete' => 'Șterge pagină', + 'pages_delete_named' => 'Șterge pagina :pageNume', + 'pages_delete_draft_named' => 'Șterge schița paginii :pageNume', + 'pages_delete_draft' => 'Șterge ciorna', + 'pages_delete_success' => 'Pagină ștearsă', + 'pages_delete_draft_success' => 'Pagină ciornă ștearsă', + 'pages_delete_confirm' => 'Ești sigur că dorești să ștergi acestă pagină?', + 'pages_delete_draft_confirm' => 'Ești sigur că vrei să ștergi această pagină schiță?', + 'pages_editing_named' => 'Editare pagină :pageNume', + 'pages_edit_draft_options' => 'Opțiuni ciornă', + 'pages_edit_save_draft' => 'Salvare ciornă', + 'pages_edit_draft' => 'Editare ciornă pagină', + 'pages_editing_draft' => 'Editare ciornă', + 'pages_editing_page' => 'Editare pagină', + 'pages_edit_draft_save_at' => 'Ciornă salvată la ', + 'pages_edit_delete_draft' => 'Șterge ciorna', + 'pages_edit_discard_draft' => 'Renunță la ciornă', + 'pages_edit_switch_to_markdown' => 'Comută la editorul Markdown', + 'pages_edit_switch_to_markdown_clean' => '(Curăță conținut)', + 'pages_edit_switch_to_markdown_stable' => '(Conținut stabil)', + 'pages_edit_switch_to_wysiwyg' => 'Comută la editorul WYSIWYG', + 'pages_edit_set_changelog' => 'Setare jurnal modificări', + 'pages_edit_enter_changelog_desc' => 'Adaugă o scurtă descriere a modificărilor făcute', + 'pages_edit_enter_changelog' => 'Intră în jurnalul de modificări', + 'pages_editor_switch_title' => 'Schimbă editorul', + 'pages_editor_switch_are_you_sure' => 'Ești sigur că vrei să schimbi editorul pentru această pagină?', + 'pages_editor_switch_consider_following' => 'Ia în considerare următoarele la schimbarea editorilor:', + 'pages_editor_switch_consideration_a' => 'Odată salvată, noua opțiune de editor va fi utilizată de orice editori viitori, inclusiv de cei care nu pot schimba însuși tipul de editor.', + 'pages_editor_switch_consideration_b' => 'Acest lucru poate duce la pierderea detaliilor și a sintaxei în anumite circumstanțe.', + 'pages_editor_switch_consideration_c' => 'Schimbări de etichete sau schimbări de jurnal de modificări, făcute de la ultima salvare, nu vor persista în această schimbare.', + 'pages_save' => 'Salvează pagina', + 'pages_title' => 'Titlu pagină', + 'pages_name' => 'Nume pagină', + 'pages_md_editor' => 'Editor', + 'pages_md_preview' => 'Previzualizare', + 'pages_md_insert_image' => 'Inserare imagine', + 'pages_md_insert_link' => 'Inserează link-ul entității', + 'pages_md_insert_drawing' => 'Inserează desen', + 'pages_not_in_chapter' => 'Pagina nu este într-un capitol', + 'pages_move' => 'Mută pagina', + 'pages_move_success' => 'Pagina mutată la ":parentName"', + 'pages_copy' => 'Copiază pagina', + 'pages_copy_desination' => 'Destinație copiere', + 'pages_copy_success' => 'Pagină copiată cu succes', + 'pages_permissions' => 'Permisiunile paginii', + 'pages_permissions_success' => 'Permisiuni pagină actualizate', + 'pages_revision' => 'Revizuire', + 'pages_revisions' => 'Revizuiri pagină', + 'pages_revisions_named' => 'Revizuiri pagină pentru :pageName', + 'pages_revision_named' => 'Revizuire pagină pentru :pageName', + 'pages_revision_restored_from' => 'Restaurat de la #:id; :summary', + 'pages_revisions_created_by' => 'Creat de', + 'pages_revisions_date' => 'Data revizuirii', + 'pages_revisions_number' => '#', + 'pages_revisions_numbered' => 'Revizuire #:id', + 'pages_revisions_numbered_changes' => 'Revizuirea #:id Modificări', + 'pages_revisions_editor' => 'Tip editor', + 'pages_revisions_changelog' => 'Jurnal de modificări', + 'pages_revisions_changes' => 'Modificări', + 'pages_revisions_current' => 'Vrsiunea curentă', + 'pages_revisions_preview' => 'Previzualizare', + 'pages_revisions_restore' => 'Restaurare', + 'pages_revisions_none' => 'Această pagină nu are revizuiri', + 'pages_copy_link' => 'Copiază link', + 'pages_edit_content_link' => 'Editare conținut', + 'pages_permissions_active' => 'Permisiuni carte active', + 'pages_initial_revision' => 'Publicare inițiala', + 'pages_references_update_revision' => 'System auto-update of internal links', + 'pages_initial_name' => 'Pagină nouă', + 'pages_editing_draft_notification' => 'Momentan editezi o schiță care a fost salvată ultima dată :timeDiff.', + 'pages_draft_edited_notification' => 'Această pagină a fost actualizată de atunci. Este recomandat să aruncați această ciornă.', + 'pages_draft_page_changed_since_creation' => 'Această pagină a fost actualizată de la crearea acestei ciorne. Este recomandat să renunțați la această schiță sau să aveți grijă să nu suprascrieți modificările paginii.', + 'pages_draft_edit_active' => [ + 'start_a' => ':count utilizatori au început să editeze această pagină', + 'start_b' => ':userName a început să editeze această pagină', + 'time_a' => 'de când pagina a fost actualizată ultima dată', + 'time_b' => 'în ultimele :minCount minute', + 'message' => ':start :time. Aveți grijă să nu vă suprascrieți reciproc actualizările!', + ], + 'pages_draft_discarded' => 'Schiță eliminată, editorul a fost actualizat cu conținutul paginii curente', + 'pages_specific' => 'Pagina specifică', + 'pages_is_template' => 'Şablon pagină', + + // Editor Sidebar + 'page_tags' => 'Etichete pagină', + 'chapter_tags' => 'Etichete capitol', + 'book_tags' => 'Etichete carte', + 'shelf_tags' => 'Etichete raft', + 'tag' => 'Etichetă', + 'tags' => 'Etichete', + 'tag_name' => 'Nume etichetă', + 'tag_value' => 'Valoare etichetă (opțional)', + 'tags_explain' => "Adăugați unele etichete pentru a clasifica mai bine conținutul. \n Puteți atribui o valoare unei etichete pentru o organizare mai aprofundată.", + 'tags_add' => 'Adaugă o altă etichetă', + 'tags_remove' => 'Elimină această etichetă', + 'tags_usages' => 'Total utilizări etichetă', + 'tags_assigned_pages' => 'Atribuit paginilor', + 'tags_assigned_chapters' => 'Atribuit capitolelor', + 'tags_assigned_books' => 'Atribuit cărților', + 'tags_assigned_shelves' => 'Atribuit rafturilor', + 'tags_x_unique_values' => ':count valori unice', + 'tags_all_values' => 'Toate valorile', + 'tags_view_tags' => 'Vezi etichete', + 'tags_view_existing_tags' => 'Vezi etichetele existente', + 'tags_list_empty_hint' => 'Etichetele pot fi atribuite prin bara laterală a editorului de pagini sau în timpul editării detaliilor unei cărți, capitole sau raft.', + 'attachments' => 'Atașamente', + 'attachments_explain' => 'Încarcă unele fișiere sau atașează unele link-uri pentru a fi afișate pe pagina ta. Acestea sunt vizibile în bara laterală a paginii.', + 'attachments_explain_instant_save' => 'Modificările de aici sunt salvate instant.', + 'attachments_items' => 'Elemente atașate', + 'attachments_upload' => 'Încarcă fișier', + 'attachments_link' => 'Atașare link', + 'attachments_set_link' => 'Setează link', + 'attachments_delete' => 'Ești sigur că dorești să ștergi acest atașament?', + 'attachments_dropzone' => 'Trage fișiere sau apasă aici pentru a atașa un fișier', + 'attachments_no_files' => 'Niciun fișier nu a fost încărcat', + 'attachments_explain_link' => 'Poți atașa un link dacă ai prefera să nu încarci un fișier. Acesta poate fi un link către o altă pagină sau un link către un fișier în cloud.', + 'attachments_link_name' => 'Nume link', + 'attachment_link' => 'Link atașament', + 'attachments_link_url' => 'Link către fișier', + 'attachments_link_url_hint' => 'Url site sau fișier', + 'attach' => 'Atașează', + 'attachments_insert_link' => 'Adăugare link atașament la pagină', + 'attachments_edit_file' => 'Editare fișier', + 'attachments_edit_file_name' => 'Nume fișier', + 'attachments_edit_drop_upload' => 'Trage fișierele aici sau apasă aici pentru a încărca și suprascrie', + 'attachments_order_updated' => 'Ordine atașament actualizată', + 'attachments_updated_success' => 'Detalii atașament actualizate', + 'attachments_deleted' => 'Atașament șters', + 'attachments_file_uploaded' => 'Fișier încărcat cu succes', + 'attachments_file_updated' => 'Fișier actualizat cu succes', + 'attachments_link_attached' => 'Link atașat cu succes la pagină', + 'templates' => 'Șabloane', + 'templates_set_as_template' => 'Pagina este un șablon', + 'templates_explain_set_as_template' => 'Poți seta această pagină ca șablon astfel încât conținutul său să fie utilizat la crearea altor pagini. Alți utilizatori vor putea utiliza acest șablon dacă au permisiuni de vizualizare pentru această pagină.', + 'templates_replace_content' => 'Înlocuiește conținutul paginii', + 'templates_append_content' => 'Adaugă la conținutul paginii', + 'templates_prepend_content' => 'Adaugă la începutul conținutului paginii', + + // Profile View + 'profile_user_for_x' => 'Utilizator pentru :time', + 'profile_created_content' => 'Conținut creat', + 'profile_not_created_pages' => ':userName nu a creat nicio pagină', + 'profile_not_created_chapters' => ':userName nu a creat niciun capitol', + 'profile_not_created_books' => ':userName nu a creat nicio carte', + 'profile_not_created_shelves' => ':userName nu a creat niciun raft', + + // Comments + 'comment' => 'Comentariu', + 'comments' => 'Comentarii', + 'comment_add' => 'Adaugă comentariu', + 'comment_placeholder' => 'Lasă un comentariu aici', + 'comment_count' => '{0} Niciun comentariu|{1} 1 Comentariu [2,*] :count Comentarii', + 'comment_save' => 'Salvează comentariul', + 'comment_saving' => 'Se salvează comentariul...', + 'comment_deleting' => 'Se șterge comentariul...', + 'comment_new' => 'Comentariu nou', + 'comment_created' => 'comentat :createDiff', + 'comment_updated' => 'Actualizat :updateDiff de :username', + 'comment_deleted_success' => 'Comentariu șters', + 'comment_created_success' => 'Comentariu adăugat', + 'comment_updated_success' => 'Comentariu actualizat', + 'comment_delete_confirm' => 'Ești sigur că vrei să ștergi acest comentariu?', + 'comment_in_reply_to' => 'Ca răspuns la :commentId', + + // Revision + 'revision_delete_confirm' => 'Ești sigur că vrei să ștergi această revizuire?', + 'revision_restore_confirm' => 'Ești sigur că vei să restaurezi această revizuire? Conținutul paginii curente va fi înlocuit.', + 'revision_delete_success' => 'Revizuire ștearsă', + 'revision_cannot_delete_latest' => 'Nu se poate șterge ultima revizuire.', + + // Copy view + 'copy_consider' => 'Te rugăm să ie în considerare cele de mai jos atunci când copiezi conținut.', + 'copy_consider_permissions' => 'Setările de permisiuni personalizate nu vor fi copiate.', + 'copy_consider_owner' => 'Vei deveni proprietarul întregului conținut copiat.', + 'copy_consider_images' => 'Fișierele imagine ale paginii nu vor fi duplicate, iar imaginile originale își vor păstra relația cu pagina în care au fost încărcate inițial.', + 'copy_consider_attachments' => 'Atașamentele paginii nu vor fi copiate.', + 'copy_consider_access' => 'O schimbare a locației, a proprietarului sau a permisiunilor poate duce la accesul acestui conținut pentru cei care nu aveau acces anterior.', + + // Conversions + 'convert_to_shelf' => 'Convertește în raft', + 'convert_to_shelf_contents_desc' => 'Poți converti această carte într-un raft nou cu același conținut. Capitolele cuprinse în această carte vor fi convertite în cărți noi. Dacă această carte conține pagini, care nu sunt într-un capitol, această carte va fi redenumită și conține astfel de pagini, iar această carte va deveni parte a noului raft.', + 'convert_to_shelf_permissions_desc' => 'Orice permisiuni stabilite în această carte vor fi copiate pe noul raft și la toate noile cărți copii care nu au drepturi impuse proprii. Țineți cont că permisiunile de pe rafturi nu se aplică în cascadă pentru conținut cuprins în ele, așa cum se întâmplă pentru cărți.', + 'convert_book' => 'Convertește cartea', + 'convert_book_confirm' => 'Ești sigur că vrei să convertești această carte?', + 'convert_undo_warning' => 'Acest lucru nu poate fi anulat la fel de uşor.', + 'convert_to_book' => 'Convertește în carte', + 'convert_to_book_desc' => 'Poți converti acest capitol într-o nouă carte cu același conținut. Orice permisiuni stabilite pe acest capitol vor fi copiate în noua carte, dar orice permisiuni moștenite, din cartea părinte nu vor fi copiate, ceea ce ar putea duce la o schimbare a controlului de acces.', + 'convert_chapter' => 'Convertește capitolul', + 'convert_chapter_confirm' => 'Ești sigur că dorești să convertești acest capitol?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', +]; diff --git a/resources/lang/ro/errors.php b/resources/lang/ro/errors.php new file mode 100644 index 000000000..cda3907af --- /dev/null +++ b/resources/lang/ro/errors.php @@ -0,0 +1,109 @@ + 'Nu ai permisiunea de a accesa pagina solicitată.', + 'permissionJson' => 'Nu ai permisiunea de a efectua acțiunea solicitată.', + + // Auth + 'error_user_exists_different_creds' => 'Un utilizator cu adresa de e-mail :email există deja, dar cu acreditări diferite.', + 'email_already_confirmed' => 'E-mailul a fost deja confirmat, încearcă să te conectezi.', + 'email_confirmation_invalid' => 'Acest token de confirmare nu este valid sau a fost deja folosit, încercă să te înregistrezi din nou.', + 'email_confirmation_expired' => 'Token-ul de confirmare a expirat, a fost trimis un nou e-mail de confirmare.', + 'email_confirmation_awaiting' => 'Adresa de e-mail pentru contul utilizat trebuie să fie confirmată', + 'ldap_fail_anonymous' => 'Accesul LDAP a eșuat utilizând legătura anonimă', + 'ldap_fail_authed' => 'Accesul LDAP a eșuat folosind detaliile date dn și parolă', + 'ldap_extension_not_installed' => 'Extensia LDAP PHP nu este instalată', + 'ldap_cannot_connect' => 'Nu se poate conecta la serverul ldap, conexiunea inițială a eșuat', + 'saml_already_logged_in' => 'Deja conectat', + 'saml_user_not_registered' => 'Utilizatorul :name nu este înregistrat și înregistrarea automată este dezactivată', + 'saml_no_email_address' => 'Nu s-a putut găsi o adresă de e-mail, pentru acest utilizator, în datele furnizate de sistemul extern de autentificare', + 'saml_invalid_response_id' => 'Solicitarea de la sistemul extern de autentificare nu este recunoscută de un proces inițiat de această aplicație. Navigarea înapoi după o autentificare ar putea cauza această problemă.', + 'saml_fail_authed' => 'Autentificarea folosind :system a eșuat, sistemul nu a furnizat autorizare cu succes', + 'oidc_already_logged_in' => 'Deja conectat', + 'oidc_user_not_registered' => 'Utilizatorul :name nu este înregistrat și înregistrarea automată este dezactivată', + 'oidc_no_email_address' => 'Nu s-a putut găsi o adresă de e-mail, pentru acest utilizator, în datele furnizate de sistemul extern de autentificare', + 'oidc_fail_authed' => 'Autentificarea folosind :system a eșuat, sistemul nu a furnizat autorizare cu succes', + 'social_no_action_defined' => 'Nicio acțiune definită', + 'social_login_bad_response' => "Eroare primită în timpul autentificării :socialAccount : \n:error", + 'social_account_in_use' => 'Acest cont :socialAccount este deja utilizat, încercați să vă conectați prin intermediul opțiunii :socialCont.', + 'social_account_email_in_use' => 'E-mailul :email este deja în uz. Dacă ai deja un cont, te poți conecta la contul :socialAccount din setările profilului.', + 'social_account_existing' => 'Acest :socialAccount este deja atașat la profilul tău.', + 'social_account_already_used_existing' => 'Acest cont :socialAccount este deja utilizat de un alt utilizator.', + 'social_account_not_used' => 'Acest cont :socialAccount nu este legat de niciun utilizator. Te rugăm să îl atașezi în setările profilului. ', + 'social_account_register_instructions' => 'Dacă nu ai încă un cont, poți înregistra un cont utilizând opțiunea :socialCont.', + 'social_driver_not_found' => 'Driver social negăsit', + 'social_driver_not_configured' => 'Setările tale sociale :socialAccount nu sunt configurate corect.', + 'invite_token_expired' => 'Acest link de invitație a expirat. Poți încerca să îți resetezi parola contului.', + + // System + 'path_not_writable' => 'Calea fișierului :filePath nu a putut fi încărcată. Asigurați-vă că poate fi scrisă pe server.', + 'cannot_get_image_from_url' => 'Nu se poate obține imaginea de la :url', + 'cannot_create_thumbs' => 'Serverul nu poate crea miniaturi. Verifică dacă este instalată extensia GD PHP.', + 'server_upload_limit' => 'Serverul nu permite încărcarea acestei dimensiuni. Te rog să încerci o dimensiune mai mică a fișierului.', + 'uploaded' => 'Serverul nu permite încărcarea acestei dimensiuni. Te rog să încerci o dimensiune mai mică a fișierului.', + 'image_upload_error' => 'A apărut o eroare la încărcarea imaginii', + 'image_upload_type_error' => 'Tipul de imagine încărcat nu este valid', + 'file_upload_timeout' => 'Încărcarea fișierului a expirat.', + + // Attachments + 'attachment_not_found' => 'Atașamentul nu a fost găsit', + + // Pages + 'page_draft_autosave_fail' => 'Nu s-a reușit salvarea ciornei. Asigură-te că ai conexiune la internet înainte de a salva această pagină', + 'page_custom_home_deletion' => 'Nu se poate șterge o pagină în timp ce este setată ca primă pagină', + + // Entities + 'entity_not_found' => 'Entitate negăsită', + 'bookshelf_not_found' => 'Shelf not found', + 'book_not_found' => 'Carte negăsită', + 'page_not_found' => 'Pagină negăsită', + 'chapter_not_found' => 'Capitol negăsit', + 'selected_book_not_found' => 'Cartea selectată nu a fost găsită', + 'selected_book_chapter_not_found' => 'Cartea selectată sau capitolul nu a fost găsit', + 'guests_cannot_save_drafts' => 'Vizitatorii nu pot salva ciorne', + + // Users + 'users_cannot_delete_only_admin' => 'Nu poți șterge singurul administrator', + 'users_cannot_delete_guest' => 'Nu se poate șterge utilizatorul "Vizitator"', + + // Roles + 'role_cannot_be_edited' => 'Acest rol nu poate fi editat', + 'role_system_cannot_be_deleted' => 'Acest rol este un rol de sistem și nu poate fi șters', + 'role_registration_default_cannot_delete' => 'Acest rol nu poate fi șters când este setat ca rol implicit de înregistrare', + 'role_cannot_remove_only_admin' => 'Acest utilizator este singurul utilizator atribuit rolului de administrator. Atribuiți rolul de administrator unui alt utilizator înainte de a-l elimina aici.', + + // Comments + 'comment_list' => 'A apărut o eroare la preluarea comentariilor.', + 'cannot_add_comment_to_draft' => 'Nu poți adăuga comentarii la o ciornă.', + 'comment_add' => 'A apărut o eroare la adăugarea / actualizarea comentariului.', + 'comment_delete' => 'A apărut o eroare la ștergerea comentariului.', + 'empty_comment' => 'Nu se poate adăuga un comentariu gol.', + + // Error pages + '404_page_not_found' => 'Pagina nu a fost găsită', + 'sorry_page_not_found' => 'Ne pare rău, pagina pe care o cauți nu a putut fi găsită.', + 'sorry_page_not_found_permission_warning' => 'Dacă te aștepți ca această pagină să existe, s-ar putea să nu ai permisiunea de a o vizualiza.', + 'image_not_found' => 'Imagine negăsită', + 'image_not_found_subtitle' => 'Ne pare rău, fișierul de imagine pe care îl cauți nu a putut fi găsit.', + 'image_not_found_details' => 'Dacă te aștepți ca această imagine să existe, e posibil să fie ștearsă.', + 'return_home' => 'Întoarce-te acasă', + 'error_occurred' => 'A apărut o eroare', + 'app_down' => ':appName nu funcționează acum', + 'back_soon' => 'Va reveni în curând.', + + // API errors + 'api_no_authorization_found' => 'Nu s-a găsit niciun token de autorizare la cerere', + 'api_bad_authorization_format' => 'A fost găsit un token de autorizare, dar formatul este incorect', + 'api_user_token_not_found' => 'Nu a fost găsit niciun token API potrivit pentru codul de autorizare furnizat', + 'api_incorrect_token_secret' => 'Secretul furnizat pentru token-ul API folosit este incorect', + 'api_user_no_api_permission' => 'Proprietarul token-ului API folosit nu are permisiunea de a efectua apeluri API', + 'api_user_token_expired' => 'Token-ul de autorizare utilizat a expirat', + + // Settings & Maintenance + 'maintenance_test_email_failure' => 'Eroare la trimiterea unui e-mail de test:', + +]; diff --git a/resources/lang/ro/pagination.php b/resources/lang/ro/pagination.php new file mode 100644 index 000000000..675496041 --- /dev/null +++ b/resources/lang/ro/pagination.php @@ -0,0 +1,12 @@ + '« Înapoi', + 'next' => 'Înainte »', + +]; diff --git a/resources/lang/ro/passwords.php b/resources/lang/ro/passwords.php new file mode 100644 index 000000000..bd27acc15 --- /dev/null +++ b/resources/lang/ro/passwords.php @@ -0,0 +1,15 @@ + 'Parolele trebuie să aibă cel puțin opt caractere și să corespundă confirmării.', + 'user' => "Nu putem găsi un utilizator cu această adresă de e-mail.", + 'token' => 'Token-ul de resetare a parolei nu este valid pentru această adresă de e-mail.', + 'sent' => 'Am trimis prin e-mail link-ul de resetare a parolei!', + 'reset' => 'Parola ta a fost resetată!', + +]; diff --git a/resources/lang/ro/settings.php b/resources/lang/ro/settings.php new file mode 100644 index 000000000..04265581c --- /dev/null +++ b/resources/lang/ro/settings.php @@ -0,0 +1,313 @@ + 'Setări', + 'settings_save' => 'Salvează setările', + 'settings_save_success' => 'Setări salvate', + 'system_version' => 'Versiune sistem', + 'categories' => 'Categorii', + + // App Settings + 'app_customization' => 'Personalizare', + 'app_features_security' => 'Caracteristici și securitate', + 'app_name' => 'Numele aplicației', + 'app_name_desc' => 'Acest nume este afișat în antet și în orice e-mail trimis de sistem.', + 'app_name_header' => 'Arată numele în antet', + 'app_public_access' => 'Acces public', + 'app_public_access_desc' => 'Activarea acestei opțiuni va permite vizitatorilor, care nu sunt autentificați, să acceseze conținutul în instanța de BookStack.', + 'app_public_access_desc_guest' => 'Accesul vizitatorilor publici poate fi controlat prin intermediul utilizatorului "Vizitator".', + 'app_public_access_toggle' => 'Permite accesul public', + 'app_public_viewing' => 'Permiți vizualizarea publică?', + 'app_secure_images' => 'Încărcare imagini cu securitate mai mare', + 'app_secure_images_toggle' => 'Activare încărcare imagini cu securitate mai mare', + 'app_secure_images_desc' => 'Din motive de performanță, toate imaginile sunt publice. Această opțiune adaugă un șir de caractere greu de ghicit în fața url-urilor de imagine. Asigură-te că indexul directorilor nu este activat pentru a preveni accesul ușor.', + 'app_default_editor' => 'Editor de pagină implicit', + 'app_default_editor_desc' => 'Selectează editorul care va fi folosit în mod implicit la editarea paginilor noi. Acest lucru poate fi înlocuit la un nivel de pagină unde permisiunile permit.', + 'app_custom_html' => 'Conținut header HTML personalizat', + 'app_custom_html_desc' => 'Orice conținut adăugat aici va fi inserat în partea de jos a secțiunii a fiecărei pagini. Acest lucru este util pentru a suprascrie stilurile sau pentru a adăuga cod analitic.', + 'app_custom_html_disabled_notice' => 'Conținutul headerului HTML personalizat este dezactivat pe această pagină de setări pentru a asigura că modificările pot fi inversate.', + 'app_logo' => 'Logo aplicație', + 'app_logo_desc' => 'Această imagine ar trebui să fie de 43px în înălțime.
Imaginile mari vor fi reduse în jos.', + 'app_primary_color' => 'Culoare primară aplicaţie', + 'app_primary_color_desc' => 'Setează culoarea principală pentru aplicație, inclusiv bannerul, butoanele și link-urile.', + 'app_homepage' => 'Pagina principală a aplicației', + 'app_homepage_desc' => 'Selectează o vizualizare pentru a afișa pe prima pagină în loc de vizualizarea implicită. Permisiunile paginii sunt ignorate pentru paginile selectate.', + 'app_homepage_select' => 'Selectează o pagină', + 'app_footer_links' => 'Link-uri de subsol', + 'app_footer_links_desc' => 'Adaugă link-uri de afișat în subsolul site-ului. Acestea vor fi afișate în partea de jos a majorității paginilor, inclusiv cele care nu necesită autentificare. Poți folosi o etichetă de "trans::" pentru a folosi traduceri definite de sistem. De exemplu: Folosind "trans:common:common.privacy_policy" va oferi textul tradus "Politica de confidențialitate" și "trans:common.terms_of_service" va furniza textul tradus "Termenii serviciului".', + 'app_footer_links_label' => 'Etichetă link', + 'app_footer_links_url' => 'URL link', + 'app_footer_links_add' => 'Adăugare link subsol', + 'app_disable_comments' => 'Dezactivează comentariile', + 'app_disable_comments_toggle' => 'Dezactivează comentariile', + 'app_disable_comments_desc' => 'Dezactivează comentariile pentru toate paginile aplicației.
Comentariile existente nu sunt afișate.', + + // Color settings + 'content_colors' => 'Culori conținut', + 'content_colors_desc' => 'Setează culori pentru toate elementele din ierarhia organizării paginii. Alegerea de culori cu o luminozitate similară cu cea a culorilor implicite este recomandată pentru lizibilitate.', + 'bookshelf_color' => 'Culoare raft', + 'book_color' => 'Culoare carte', + 'chapter_color' => 'Culoare capitol', + 'page_color' => 'Culoare pagină', + 'page_draft_color' => 'Culoare pagină ciornă', + + // Registration Settings + 'reg_settings' => 'Înregistrare', + 'reg_enable' => 'Permite înregistrarea', + 'reg_enable_toggle' => 'Permite înregistrarea', + 'reg_enable_desc' => 'Când înregistrarea este activată, utilizatorul va putea să se înregistreze ca utilizator al aplicației. La înregistrare, ei au un singur rol implicit de utilizator.', + 'reg_default_role' => 'Rol utilizator implicit după înregistrare', + 'reg_enable_external_warning' => 'Opțiunea de mai sus este ignorată în timp ce autentificarea externă LDAP sau SAML este activă. Conturile de utilizator pentru membrii neexistenți vor fi create automat dacă autentificarea, împotriva sistemului extern utilizat, este reușită.', + 'reg_email_confirmation' => 'Confirmare e-mail', + 'reg_email_confirmation_toggle' => 'Solicită confirmare e-mail', + 'reg_confirm_email_desc' => 'Dacă este folosită restricționarea domeniului, atunci va fi necesară confirmarea e-mailului și această opțiune va fi ignorată.', + 'reg_confirm_restrict_domain' => 'Restricționare domeniu', + 'reg_confirm_restrict_domain_desc' => 'Introduceți o listă de domenii de e-mail separate prin virgulă la care doriți să restricționați înregistrarea. Utilizatorilor le va fi trimis un e-mail pentru a-și confirma adresa înainte de a putea interacționa cu aplicația.
Rețineți că utilizatorii vor putea să își schimbe adresele de e-mail după o înregistrare reușită.', + 'reg_confirm_restrict_domain_placeholder' => 'Nicio restricție setată', + + // Maintenance settings + 'maint' => 'Mentenanţă', + 'maint_image_cleanup' => 'Curățare imagini', + 'maint_image_cleanup_desc' => 'Scanează pagina și conținutul revizuirii pentru a verifica ce imagini și desene sunt utilizate în prezent și care imagini sunt redundante. Asigurați-vă că ați creat o copie de rezervă a bazei de date și a imaginii complete înainte de a o rula.', + 'maint_delete_images_only_in_revisions' => 'De asemenea, șterge imagini care există numai în vechile revizuiri ale paginii', + 'maint_image_cleanup_run' => 'Rulează curățarea', + 'maint_image_cleanup_warning' => ':count potenţiale imagini nefolosite au fost găsite. Sunteţi sigur că doriţi să ştergeţi aceste imagini?', + 'maint_image_cleanup_success' => ':count potențiale imagini nefolosite găsite și șterse!', + 'maint_image_cleanup_nothing_found' => 'Nu au fost găsite imagini nefolosite, nimic șters!', + 'maint_send_test_email' => 'Trimite un e-mail de test', + 'maint_send_test_email_desc' => 'Aceasta trimite un e-mail de test la adresa ta de e-mail specificată în profilul tău.', + 'maint_send_test_email_run' => 'Trimite e-mail de test', + 'maint_send_test_email_success' => 'E-mail trimis la :address', + 'maint_send_test_email_mail_subject' => 'Email de test', + 'maint_send_test_email_mail_greeting' => 'Livrarea e-mailului pare să funcţioneze!', + 'maint_send_test_email_mail_text' => 'Felicitări! Deoarece ai primit această notificare prin e-mail, setările de e-mail par să fie configurate corespunzător.', + 'maint_recycle_bin_desc' => 'Rafturile, cărțile, capitole și paginile șterse se trimit la coșul de gunoi pentru a putea fi restaurate sau șterse definitiv. Elementele mai vechi din coșul de gunoi pot fi eliminate automat după o vreme, în funcție de configurația sistemului.', + 'maint_recycle_bin_open' => 'Deschide coșul de gunoi', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', + + // Recycle Bin + 'recycle_bin' => 'Coș de gunoi', + 'recycle_bin_desc' => 'Aici poți restaura elementele care au fost șterse sau alege să le elimini definitiv din sistem. Această listă este nefiltrată spre deosebire de listele de activități similare din sistemul în care sunt aplicate filtrele de permisiuni.', + 'recycle_bin_deleted_item' => 'Element șters', + 'recycle_bin_deleted_parent' => 'Părinte', + 'recycle_bin_deleted_by' => 'Șters de', + 'recycle_bin_deleted_at' => 'Data ștergerii', + 'recycle_bin_permanently_delete' => 'Ștergere permanentă', + 'recycle_bin_restore' => 'Restaurează', + 'recycle_bin_contents_empty' => 'Coșul de gunoi este în prezent gol', + 'recycle_bin_empty' => 'Golește coșul de gunoi', + 'recycle_bin_empty_confirm' => 'Aceasta va distruge definitiv toate elementele din coșul de gunoi, inclusiv conținutul conținut din fiecare element. Ești sigur că vrei să golești coșul de gunoi?', + 'recycle_bin_destroy_confirm' => 'Această acțiune va șterge permanent acest element din sistem, împreună cu orice elemente copil enumerat mai jos, și nu vei putea restaura acest conținut. Ești sigur că vrei să ștergi definitiv acest element?', + 'recycle_bin_destroy_list' => 'Elemente de distrus', + 'recycle_bin_restore_list' => 'Elemente care vor fi restaurate', + 'recycle_bin_restore_confirm' => 'Această acțiune va restaura elementul șters, inclusiv orice elemente copii, la locația lor originală. În cazul în care locația originală a fost de atunci ștearsă și acum este în coșul de reciclare, elementul părinte va trebui, de asemenea, să fie restaurat.', + 'recycle_bin_restore_deleted_parent' => 'Părintele acestui element a fost de asemenea șters. Acestea vor rămâne șterse până când acel părinte este, de asemenea, restaurat.', + 'recycle_bin_restore_parent' => 'Restaurează părinte', + 'recycle_bin_destroy_notification' => ':count elemente șterse din coșul de gunoi.', + 'recycle_bin_restore_notification' => ':count elemente restaurate din coșul de gunoi.', + + // Audit Log + 'audit' => 'Jurnal de audit', + 'audit_desc' => 'Acest jurnal de audit afișează o listă de activități urmărite în sistem. Această listă este nefiltrată spre deosebire de listele de activități similare din sistemul în care sunt aplicate filtrele de permisiuni.', + 'audit_event_filter' => 'Filtru eveniment', + 'audit_event_filter_no_filter' => 'Niciun filtru', + 'audit_deleted_item' => 'Element șters', + 'audit_deleted_item_name' => 'Nume: :name', + 'audit_table_user' => 'Utilizator', + 'audit_table_event' => 'Eveniment', + 'audit_table_related' => 'Articol asociat sau detalii', + 'audit_table_ip' => 'Adresă IP', + 'audit_table_date' => 'Data activității', + 'audit_date_from' => 'Interval dată de la', + 'audit_date_to' => 'Interval dată până la', + + // Role Settings + 'roles' => 'Roluri', + 'role_user_roles' => 'Roluri utilizator', + 'role_create' => 'Crează rol nou', + 'role_create_success' => 'Rol creat cu succes', + 'role_delete' => 'Șterge rolul', + 'role_delete_confirm' => 'Aceasta va șterge rolul cu numele \':roleName\'.', + 'role_delete_users_assigned' => 'Acest rol are :userCount utilizatori asociați. Dacă vrei să migrezi utilizatorii din acest rol, selectează un nou rol mai jos.', + 'role_delete_no_migration' => "Nu migra utilizatorii", + 'role_delete_sure' => 'Ești sigur că vrei să ștergi acest rol?', + 'role_delete_success' => 'Rolul a fost șters', + 'role_edit' => 'Editează Rol', + 'role_details' => 'Detalii rol', + 'role_name' => 'Nume rol', + 'role_desc' => 'Scurtă descriere a rolului', + 'role_mfa_enforced' => 'Necesită autentificare multi-factor', + 'role_external_auth_id' => 'ID-uri externe de autentificare', + 'role_system' => 'Permisiuni de sistem', + 'role_manage_users' => 'Gestionare utilizatori', + 'role_manage_roles' => 'Gestionează roluri și permisiuni de rol', + 'role_manage_entity_permissions' => 'Gestionează permisiunile pentru toată cartea, capitolul și paginile', + 'role_manage_own_entity_permissions' => 'Gestionează permisiunile pe propria carte, capitol și pagini', + 'role_manage_page_templates' => 'Gestionează șabloanele de pagină', + 'role_access_api' => 'Accesează API sistem', + 'role_manage_settings' => 'Gestionează setările aplicației', + 'role_export_content' => 'Exportă conținut', + 'role_editor_change' => 'Schimbă editorul de pagină', + 'role_asset' => 'Permisiuni active', + 'roles_system_warning' => 'Fi conștient de faptul că accesul la oricare dintre cele trei permisiuni de mai sus poate permite unui utilizator să își modifice propriile privilegii sau privilegiile altor persoane din sistem. Atribuie doar roluri cu aceste permisiuni utilizatorilor de încredere.', + 'role_asset_desc' => 'Aceste permisiuni controlează accesul implicit la activele din sistem. Permisiunile pe Cărți, Capitole și Pagini vor suprascrie aceste permisiuni.', + 'role_asset_admins' => 'Administratorilor li se acordă automat acces la tot conținutul, dar aceste opțiuni pot afișa sau ascunde opțiunile UI.', + 'role_all' => 'Tot', + 'role_own' => 'Propriu', + 'role_controlled_by_asset' => 'Controlat de activele pe care sunt încărcate', + 'role_save' => 'Salvare rol', + 'role_update_success' => 'Rol actualizat cu succes', + 'role_users' => 'Utilizatori cu acest rol', + 'role_users_none' => 'Nici un utilizator nu este asociat acestui rol', + + // Users + 'users' => 'Utilizatori', + 'user_profile' => 'Profil utilizator', + 'users_add_new' => 'Adaugă utilizator nou', + 'users_search' => 'Căutare utilizatori', + 'users_latest_activity' => 'Ultima activitate', + 'users_details' => 'Detalii utilizator', + 'users_details_desc' => 'Setează un nume de afișat și o adresă de e-mail pentru acest utilizator. Adresa de e-mail va fi utilizată pentru autentificarea în aplicație.', + 'users_details_desc_no_email' => 'Setați un nume de afișat pentru acest utilizator, astfel încât alții să îl poată recunoaște.', + 'users_role' => 'Roluri utilizator', + 'users_role_desc' => 'Selectează rolurile cărora le va fi atribuit acest utilizator. Dacă un utilizator este atribuit mai multor roluri, permisiunile de la aceste roluri se vor stivui și vor primi toate abilitățile rolurilor atribuite.', + 'users_password' => 'Parolă utilizator', + 'users_password_desc' => 'Setează o parolă utilizată pentru autentificarea în aplicație. Aceasta trebuie să fie de cel puțin 8 caractere.', + 'users_send_invite_text' => 'Poți alege să trimiți acestui utilizator un e-mail de invitație care să îi permită să își seteze propria parolă, altfel îi poți seta tu parola.', + 'users_send_invite_option' => 'Trimite e-mail cu invitație utilizatorului', + 'users_external_auth_id' => 'ID autentificare externă', + 'users_external_auth_id_desc' => 'Acesta este ID-ul folosit pentru a potrivi acest utilizator atunci când comunică cu sistemul extern de autentificare.', + 'users_password_warning' => 'Completează mai jos numai dacă dorești schimbarea parolei.', + 'users_system_public' => 'Acest utilizator reprezintă orice utilizator invitat care vizitează instanța dvs. Nu poate fi folosit pentru a vă autentifica, dar este atribuit automat.', + 'users_delete' => 'Șterge utilizator', + 'users_delete_named' => 'Șterge utilizatorul :userName', + 'users_delete_warning' => 'Aceasta va șterge complet acest utilizator cu numele \':userName\' din sistem.', + 'users_delete_confirm' => 'Ești sigur că vrei să ștergi acest utilizator?', + 'users_migrate_ownership' => 'Migrare proprietate', + 'users_migrate_ownership_desc' => 'Selectează un utilizator aici dacă vrei ca un alt utilizator să devină proprietarul tuturor articolelor deținute în prezent de acest utilizator.', + 'users_none_selected' => 'Niciun utilizator selectat', + 'users_edit' => 'Editare utilizator', + 'users_edit_profile' => 'Editare profil', + 'users_avatar' => 'Avatar utilizator', + 'users_avatar_desc' => 'Selectează o imagine pentru a reprezenta acest utilizator. Aceasta ar trebui să fie un pătrat de aproximativ 256px.', + 'users_preferred_language' => 'Limba preferată', + 'users_preferred_language_desc' => 'Această opțiune va schimba limba utilizată pentru interfața de utilizare a aplicației. Acest lucru nu va afecta conținutul creat de utilizatori.', + 'users_social_accounts' => 'Conturi sociale', + 'users_social_accounts_info' => 'Aici poți conecta celelalte conturi pentru o autentificare mai rapidă și mai ușoară. Deconectarea unui cont aici nu revocă accesul autorizat anterior. Revocă accesul din setările profilului tău de pe contul social conectat.', + 'users_social_connect' => 'Conectare cont', + 'users_social_disconnect' => 'Deconectare cont', + 'users_social_connected' => ':socialAccount a fost atașat cu succes la profilul tău.', + 'users_social_disconnected' => 'Contul :socialAccount a fost deconectat cu succes de la profilul tău.', + 'users_api_tokens' => 'Token API', + 'users_api_tokens_none' => 'Nu au fost create token-uri API pentru acest utilizator', + 'users_api_tokens_create' => 'Creare token', + 'users_api_tokens_expires' => 'Expiră', + 'users_api_tokens_docs' => 'Documentație API', + 'users_mfa' => 'Autentificare multi-factor', + 'users_mfa_desc' => 'Configurare autentificarea multi-factor ca un nivel suplimentar de securitate pentru contul tău de utilizator.', + 'users_mfa_x_methods' => ':count metodă configurată|:count metode configurate', + 'users_mfa_configure' => 'Configurare metode', + + // API Tokens + 'user_api_token_create' => 'Creare token API', + 'user_api_token_name' => 'Nume', + 'user_api_token_name_desc' => 'Dă-i tokenului un nume lizibil ca un memento viitor al scopului propus.', + 'user_api_token_expiry' => 'Data expirării', + 'user_api_token_expiry_desc' => 'Setează o dată la care acest token expiră. După această dată, cererile făcute folosind acest token nu vor mai funcționa. Lăsând acest câmp necompletat se va stabili un termen de expirare de 100 de ani în viitor.', + 'user_api_token_create_secret_message' => 'Imediat după crearea acestui token, va fi generat și afișat un "ID" și "Secret". Secretul va fi afișat o singură dată, așa că fiți siguri să copiați valoarea într-un loc sigur și sigur înainte de a continua.', + 'user_api_token_create_success' => 'Token API creat cu succes', + 'user_api_token_update_success' => 'Token API actualizat cu succes', + 'user_api_token' => 'Token API', + 'user_api_token_id' => 'ID Token', + 'user_api_token_id_desc' => 'Acesta este un identificator de sistem needitabil generat pentru acest token, care va trebui furnizat în cereri API.', + 'user_api_token_secret' => 'Secret token', + 'user_api_token_secret_desc' => 'Acesta este un secret generat de sistem pentru acest token, care va trebui furnizat în cereri API. Acest lucru va fi afișat doar o singură dată, așa că copiază această valoare undeva în siguranță și securizat.', + 'user_api_token_created' => 'Token creat :timeAgo', + 'user_api_token_updated' => 'Token actualizat :timeAgo', + 'user_api_token_delete' => 'Șterge token', + 'user_api_token_delete_warning' => 'Acest lucru va șterge complet acest token API cu numele \':tokenName\' din sistem.', + 'user_api_token_delete_confirm' => 'Sigur dorești să ștergi acest token API?', + 'user_api_token_delete_success' => 'Token API șters cu succes', + + // Webhooks + 'webhooks' => 'Webhook-uri', + 'webhooks_create' => 'Creează un nou Webhook', + 'webhooks_none_created' => 'Nu au fost create webhook-uri.', + 'webhooks_edit' => 'Editare Webhook', + 'webhooks_save' => 'Salvează Webhook-ul', + 'webhooks_details' => 'Detalii Webhook', + 'webhooks_details_desc' => 'Furnizează un nume prietenos de utilizator și un punct de reper POST ca locație pentru datele webhook-ului care vor fi trimise.', + 'webhooks_events' => 'Evenimente Webhook', + 'webhooks_events_desc' => 'Selectează toate evenimentele care vor declanșa acest webhook pentru a fi apelate.', + 'webhooks_events_warning' => 'Ține cont că aceste evenimente vor fi declanșate pentru toate evenimentele selectate, chiar dacă sunt aplicate permisiuni personalizate. Asigură-te că utilizarea acestui webhook nu va expune conținut confidențial.', + 'webhooks_events_all' => 'Toate evenimentele de sistem', + 'webhooks_name' => 'Numele Webhook-ului', + 'webhooks_timeout' => 'Timeout cerere Webhook (secunde)', + 'webhooks_endpoint' => 'Endpoint Webhook', + 'webhooks_active' => 'Webhook activ', + 'webhook_events_table_header' => 'Evenimente', + 'webhooks_delete' => 'Șterge Webhook-ul', + 'webhooks_delete_warning' => 'Aceasta va șterge complet acest webhook, cu numele \':webhookName\', din sistem.', + 'webhooks_delete_confirm' => 'Ești sigur că vrei să ștergi acest webhook?', + 'webhooks_format_example' => 'Exemplu format Webhook', + 'webhooks_format_example_desc' => 'Datele Webhook sunt trimise sub forma unei cereri POST pentru endpointul configurat ca JSON conform formatului de mai jos. Proprietățile "elemente asociate" și "url" sunt opționale și vor depinde de tipul de eveniment declanșat.', + 'webhooks_status' => 'Starea Webhook-ului', + 'webhooks_last_called' => 'Ultima apelare:', + 'webhooks_last_errored' => 'Ultima eroare:', + 'webhooks_last_error_message' => 'Ultimul mesaj de eroare:', + + + //! If editing translations files directly please ignore this in all + //! languages apart from en. Content will be auto-copied from en. + //!//////////////////////////////// + 'language_select' => [ + 'en' => 'English', + 'ar' => 'العربية', + 'bg' => 'Bǎlgarski', + 'bs' => 'Bosanski', + 'ca' => 'Català', + 'cs' => 'Česky', + 'da' => 'Dansk', + 'de' => 'Deutsch (Sie)', + 'de_informal' => 'Deutsch (Du)', + 'es' => 'Español', + 'es_AR' => 'Español Argentina', + 'et' => 'Eesti keel', + 'eu' => 'Euskara', + 'fa' => 'فارسی', + 'fr' => 'Français', + 'he' => 'עברית', + 'hr' => 'Hrvatski', + 'hu' => 'Magyar', + 'id' => 'Bahasa Indonesia', + 'it' => 'Italian', + 'ja' => '日本語', + 'ko' => '한국어', + 'lt' => 'Lietuvių Kalba', + 'lv' => 'Latviešu Valoda', + 'nl' => 'Nederlands', + 'nb' => 'Norsk (Bokmål)', + 'pl' => 'Polski', + 'pt' => 'Português', + 'pt_BR' => 'Português do Brasil', + 'ru' => 'Русский', + 'sk' => 'Slovensky', + 'sl' => 'Slovenščina', + 'sv' => 'Svenska', + 'tr' => 'Türkçe', + 'uk' => 'Українська', + 'vi' => 'Tiếng Việt', + 'zh_CN' => '简体中文', + 'zh_TW' => '繁體中文', + ], + //!//////////////////////////////// +]; diff --git a/resources/lang/ro/validation.php b/resources/lang/ro/validation.php new file mode 100644 index 000000000..523943850 --- /dev/null +++ b/resources/lang/ro/validation.php @@ -0,0 +1,117 @@ + ':attribute trebuie să fie acceptat.', + 'active_url' => ':attribute nu este un URL valid.', + 'after' => ':attribute trebuie să fie o dată după :date.', + 'alpha' => ':attribute poate conține doar litere.', + 'alpha_dash' => ':attribute poate conține doar litere, numere, cratime și underscore.', + 'alpha_num' => ':attribute poate conține doar litere și cifre.', + 'array' => ':attribute trebuie să fie un array.', + 'backup_codes' => 'Codul furnizat nu este valid sau a fost deja folosit.', + 'before' => ':attribute trebuie să fie o dată înainte de :date.', + 'between' => [ + 'numeric' => ':attribute trebuie să fie între :min şi :max.', + 'file' => ':attribute trebuie să aibă între :min şi :max kiloocteţi.', + 'string' => ':attribute trebuie să aibă între :min şi :max caractere.', + 'array' => ':attribute trebuie să aibă între :min şi :max elemente.', + ], + 'boolean' => 'Câmpul :attribute trebuie să fie adevărat sau fals.', + 'confirmed' => 'Confirmarea :attribute nu se potrivește.', + 'date' => ':attribute nu este o dată validă.', + 'date_format' => ':attribute nu se potrivește cu formatul :format.', + 'different' => ':attribute și :other trebuie să fie diferite.', + 'digits' => ':attribute trebuie să aibă :digits cifre.', + 'digits_between' => ':attribute trebuie să aibă între :min şi :max cifre.', + 'email' => ':attribute trebuie să fie o adresă de e-mail validă.', + 'ends_with' => ':attribute trebuie să se termine cu una dintre următoarele: :values', + 'file' => ':attribute trebuie să fie furnizat ca un fişier valid.', + 'filled' => 'Câmpul :attribute este necesar.', + 'gt' => [ + 'numeric' => ':attribute trebuie să fie mai mare decât :value.', + 'file' => ':attribute trebuie să fie mai mare decât :value kilobytes.', + 'string' => ':attribute trebuie să fie mai mare decât :value caractere.', + 'array' => ':attribute trebuie să aibă mai mult de :value elemente.', + ], + 'gte' => [ + 'numeric' => ':attribute trebuie să fie mai mare sau egal cu :value.', + 'file' => ':attribute trebuie să fie mai mare sau egal cu :value kilobytes.', + 'string' => ':attribute trebuie să fie mai mare sau egal cu :value caractere.', + 'array' => ':attribute trebuie să aibă :value elemente sau mai multe.', + ], + 'exists' => 'Atributul :attribute selectat nu este valid.', + 'image' => ':attribute trebuie să fie o imagine.', + 'image_extension' => ':attribute trebuie să aibă o extensie validă și suportată.', + 'in' => ':attribute selectat nu este valid.', + 'integer' => ':attribute trebuie să fie un număr.', + 'ip' => ':attribute trebuie să fie o adresă IP validă.', + 'ipv4' => ':attribute trebuie să fie o adresă IPv4 validă.', + 'ipv6' => ':attribute trebuie să fie o adresă IPv6 validă.', + 'json' => ':attribute trebuie să fie un șir JSON valid.', + 'lt' => [ + 'numeric' => ':attribute trebuie să fie mai mic decât :value.', + 'file' => ':attribute trebuie să fie mai mic de :value kilobytes.', + 'string' => ':attribute trebuie să aibă mai puţin de :value caractere.', + 'array' => ':attribute trebuie să aibă mai puţin de :value elemente.', + ], + 'lte' => [ + 'numeric' => ':attribute trebuie să fie mai mic sau egal cu :value.', + 'file' => ':attribute trebuie să fie mai mic sau egal cu :value kilobytes.', + 'string' => ':attribute trebuie să fie mai mic sau egal cu :value caractere.', + 'array' => ':attribute nu trebuie să aibă mai mult de :value elemente.', + ], + 'max' => [ + 'numeric' => ':attribute nu poate fi mai mare de :max.', + 'file' => ':attribute nu poate fi mai mare de :max kilobytes.', + 'string' => ':attribute nu poate avea mai mult de :max caractere.', + 'array' => ':attribute nu poate avea mai mult de :max elemente.', + ], + 'mimes' => ':attribute trebuie să fie un fişier de tipul: :values.', + 'min' => [ + 'numeric' => ':attribute trebuie să aibă cel puțin :min.', + 'file' => ':attribute trebuie să aibă cel puțin :min kiloocteţi.', + 'string' => ':attribute trebuie să aibă cel puțin :min caractere.', + 'array' => ':attribute trebuie să aibă cel puțin :min elemente.', + ], + 'not_in' => 'Câmpul :attribute selectat nu este valid.', + 'not_regex' => 'Câmpul :attribute nu este valid.', + 'numeric' => ':attribute trebuie să fie un număr.', + 'regex' => ':attribute nu este valid.', + 'required' => ':attribute este necesar.', + 'required_if' => 'Câmpul :attribute este obligatoriu atunci când :other este :value.', + 'required_with' => 'Câmpul :attribute este necesar când :values este prezent.', + 'required_with_all' => 'Câmpul :attribute este necesar când :values este prezent.', + 'required_without' => 'Câmpul :attribute este obligatoriu atunci când :values nu este prezent.', + 'required_without_all' => 'Câmpul :attribute este necesar când niciuna dintre :values nu este prezentă.', + 'same' => ':attribute și :other trebuie să se potrivească.', + 'safe_url' => 'Este posibil ca link-ul furnizat să nu fie sigur.', + 'size' => [ + 'numeric' => ':attribute trebuie să fie :size.', + 'file' => ':attribute trebuie să aibă :size kilobiți.', + 'string' => ':attribute trebuie să aibă :size caractere.', + 'array' => 'Câmpul :attribute trebuie să aibă :size elemente.', + ], + 'string' => ':attribute trebuie să fie un șir de caractere.', + 'timezone' => ':attribute trebuie să fie o zonă validă.', + 'totp' => 'Codul furnizat nu este valid sau a expirat.', + 'unique' => ':attribute a fost deja folosit.', + 'url' => ':attribute nu este valid.', + 'uploaded' => 'Fişierul nu a putut fi încărcat. Serverul nu poate accepta fişiere de această dimensiune.', + + // Custom validation lines + 'custom' => [ + 'password-confirm' => [ + 'required_with' => 'Este necesară confirmarea parolei', + ], + ], + + // Custom validation attributes + 'attributes' => [], +]; diff --git a/resources/lang/ru/activities.php b/resources/lang/ru/activities.php index 53b936a19..a64f11117 100644 --- a/resources/lang/ru/activities.php +++ b/resources/lang/ru/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Книга успешно отсортирована', // Bookshelves - 'bookshelf_create' => 'создал полку', - 'bookshelf_create_notification' => 'Полка успешно создана', - 'bookshelf_create_from_book' => 'преобразовать книгу в полку', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Книга успешно преобразована в полку', - 'bookshelf_update' => 'обновил полку', - 'bookshelf_update_notification' => 'Полка успешно обновлена', - 'bookshelf_delete' => 'удалил полку', - 'bookshelf_delete_notification' => 'Полка успешно удалена', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" добавлено в избранное', diff --git a/resources/lang/ru/entities.php b/resources/lang/ru/entities.php index b33539ae4..a0190932d 100644 --- a/resources/lang/ru/entities.php +++ b/resources/lang/ru/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Обновлено :timeLength', 'meta_updated_name' => ':user обновил :timeLength', 'meta_owned_name' => 'Владелец :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Выбор объекта', 'entity_select_lack_permission' => 'У вас нет разрешения на выбор этого элемента', 'images' => 'Изображения', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Полка', 'shelves' => 'Полки', 'x_shelves' => ':count полка|:count полки|:count полок', - 'shelves_long' => 'Книжные полки', 'shelves_empty' => 'Полки не созданы', 'shelves_create' => 'Создать новую полку', 'shelves_popular' => 'Популярные полки', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Перетащите книги ниже, чтобы добавить их на эту полку', 'shelves_empty_contents' => 'На этой полке нет книг', 'shelves_edit_and_assign' => 'Изменить полку для привязки книг', - 'shelves_edit_named' => 'Редактировать полку :name', - 'shelves_edit' => 'Редактировать книжную полку', - 'shelves_delete' => 'Удалить книжную полку', - 'shelves_delete_named' => 'Удалить книжную полку :name', - 'shelves_delete_explain' => "Это приведет к удалению полки с именем ':name'. Привязанные книги удалены не будут.", - 'shelves_delete_confirmation' => 'Вы уверены, что хотите удалить эту полку?', - 'shelves_permissions' => 'Доступы к книжной полке', - 'shelves_permissions_updated' => 'Доступы к книжной полке обновлены', - 'shelves_permissions_active' => 'Действующие разрешения книжной полки', - 'shelves_permissions_cascade_warning' => 'Разрешения на полки не наследуются автоматически содержащимся в них книгам. Это происходит потому, что книга может находиться на нескольких полках. Однако разрешения могут быть установлены для книг полки с помощью опции, приведенной ниже.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Наследовать доступы книгам', 'shelves_copy_permissions' => 'Копировать доступы', - 'shelves_copy_permissions_explain' => 'Это применит текущие настройки доступов этой книжной полки ко всем книгам, содержащимся внутри. Перед активацией убедитесь, что все изменения в доступах этой книжной полки сохранены.', - 'shelves_copy_permission_success' => 'Доступы книжной полки скопированы для :count книг', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Книга', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Изменить содержание', 'pages_permissions_active' => 'Действующие разрешения на страницу', 'pages_initial_revision' => 'Первоначальное издание', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Новая страница', 'pages_editing_draft_notification' => 'В настоящее время вы редактируете черновик, который был сохранён :timeDiff.', 'pages_draft_edited_notification' => 'Эта страница была обновлена до этого момента. Рекомендуется отменить этот черновик.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'Вы можете преобразовать эту главу в новую книгу с тем же содержанием. Любые разрешения, установленные в этой главе, будут скопированы в новую книгу, но любые унаследованные разрешения из родительской книги не будут скопированы, что может привести к изменению контроля доступа.', 'convert_chapter' => 'Преобразовать главу', 'convert_chapter_confirm' => 'Вы уверены, что хотите преобразовать эту главу?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/ru/errors.php b/resources/lang/ru/errors.php index 7ea17aa72..019219e1c 100644 --- a/resources/lang/ru/errors.php +++ b/resources/lang/ru/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Объект не найден', - 'bookshelf_not_found' => 'Полка не найдена', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Книга не найдена', 'page_not_found' => 'Страница не найдена', 'chapter_not_found' => 'Глава не найдена', diff --git a/resources/lang/ru/settings.php b/resources/lang/ru/settings.php index 4da8e7cfa..5eaca38d2 100755 --- a/resources/lang/ru/settings.php +++ b/resources/lang/ru/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Поздравляем! Поскольку вы получили это письмо, электронная почта настроена правильно.', 'maint_recycle_bin_desc' => 'Удаленные полки, книги, главы и страницы отправляются в корзину, чтобы они могли быть восстановлены или удалены навсегда. Более старые элементы в корзине могут быть автоматически удалены через некоторое время в зависимости от системной конфигурации.', 'maint_recycle_bin_open' => 'Открыть корзину', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Корзина', diff --git a/resources/lang/sk/activities.php b/resources/lang/sk/activities.php index 94369ef4e..9524b68dd 100644 --- a/resources/lang/sk/activities.php +++ b/resources/lang/sk/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Kniha úspešne znovu zoradená', // Bookshelves - 'bookshelf_create' => 'vytvoril(a) knižnicu', - 'bookshelf_create_notification' => 'Knižnica úspešne vytvorená', - 'bookshelf_create_from_book' => 'kniha konvertovaná na poličku', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Kniha úspešne konvertovaná na poličku', - 'bookshelf_update' => 'aktualizoval(a) knižnicu', - 'bookshelf_update_notification' => 'Knižnica úspešne aktualizovaná', - 'bookshelf_delete' => 'odstránil(a) knižnicu', - 'bookshelf_delete_notification' => 'Knižnica úspešne odstránená', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" bol pridaný medzi obľúbené', diff --git a/resources/lang/sk/entities.php b/resources/lang/sk/entities.php index 39ab5014e..88e052a22 100644 --- a/resources/lang/sk/entities.php +++ b/resources/lang/sk/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Aktualizované :timeLength', 'meta_updated_name' => 'Aktualizované :timeLength používateľom :user', 'meta_owned_name' => 'Vlastník :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Entita vybraná', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Obrázky', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Polica', 'shelves' => 'Police', 'x_shelves' => ':count Shelf|:count Police', - 'shelves_long' => 'Poličky na knihy', 'shelves_empty' => 'Neboli vytvorené žiadne police', 'shelves_create' => 'Vytvoriť novú policu', 'shelves_popular' => 'Populárne police', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'Táto polica nemá priradené žiadne knihy', 'shelves_edit_and_assign' => 'Uprav policu a priraď knihy', - 'shelves_edit_named' => 'Upraviť poličku::name', - 'shelves_edit' => 'Upraviť policu', - 'shelves_delete' => 'Odstrániť knižnicu', - 'shelves_delete_named' => 'Odstrániť knižnicu :name', - 'shelves_delete_explain' => "Týmto vymažete policu s názvom ': name'. Obsahované knihy sa neodstránia.", - 'shelves_delete_confirmation' => 'Ste si istý, že chcete zmazať túto knižnicu?', - 'shelves_permissions' => 'Oprávnenia knižnice', - 'shelves_permissions_updated' => 'Oprávnenia knižnice aktualizované', - 'shelves_permissions_active' => 'Oprávnenia knižnice aktívne', - 'shelves_permissions_cascade_warning' => 'Povolenia na poličkách sa automaticky nepriraďujú k obsiahnutým knihám. Je to preto, že kniha môže existovať na viacerých poličkách. Povolenia však možno skopírovať do kníh pomocou možnosti uvedenej nižšie.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Kopírovať oprávnenia pre knihy', 'shelves_copy_permissions' => 'Kopírovať oprávnenia', - 'shelves_copy_permissions_explain' => 'Týmto sa použijú aktuálne nastavenia povolení tejto police na všetky knihy, ktoré obsahuje. Pred aktiváciou sa uistite, že všetky zmeny povolení tejto police boli uložené.', - 'shelves_copy_permission_success' => 'Oprávnenia knižnice boli skopírované {0}:count kníh|{1}:count kniha|[2,3,4]:count knihy|[5,*]:count kníh', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Kniha', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Upraviť obsah', 'pages_permissions_active' => 'Oprávnienia stránky aktívne', 'pages_initial_revision' => 'Prvé zverejnenie', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Nová stránka', 'pages_editing_draft_notification' => 'Práve upravujete koncept, ktorý bol naposledy uložený :timeDiff.', 'pages_draft_edited_notification' => 'Táto stránka bola odvtedy upravená. Odporúča sa odstrániť tento koncept.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/sk/errors.php b/resources/lang/sk/errors.php index 48aea409e..6230cc00a 100644 --- a/resources/lang/sk/errors.php +++ b/resources/lang/sk/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Entita nenájdená', - 'bookshelf_not_found' => 'Polička nenájdená', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Kniha nenájdená', 'page_not_found' => 'Stránka nenájdená', 'chapter_not_found' => 'Kapitola nenájdená', diff --git a/resources/lang/sk/settings.php b/resources/lang/sk/settings.php index b2481753b..841e6620d 100644 --- a/resources/lang/sk/settings.php +++ b/resources/lang/sk/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Gratulujeme! Keď ste dostali toto e-mailové upozornenie, zdá sa, že vaše nastavenia e-mailu sú nakonfigurované správne.', 'maint_recycle_bin_desc' => 'Vymazané police, knihy, kapitoly a strany sa odošlú do koša, aby sa dali obnoviť alebo natrvalo odstrániť. Staršie položky z koša môžu byť po chvíli automaticky odstránené v závislosti od konfigurácie systému.', 'maint_recycle_bin_open' => 'Otvoriť kôš', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Kôš', diff --git a/resources/lang/sl/activities.php b/resources/lang/sl/activities.php index 96ca48464..b0bf156cd 100644 --- a/resources/lang/sl/activities.php +++ b/resources/lang/sl/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Book successfully re-sorted', // Bookshelves - 'bookshelf_create' => 'created bookshelf', - 'bookshelf_create_notification' => 'Bookshelf successfully created', - 'bookshelf_create_from_book' => 'converted book to bookshelf', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf', - 'bookshelf_update' => 'knjižna polica posodobljena', - 'bookshelf_update_notification' => 'Bookshelf successfully updated', - 'bookshelf_delete' => 'knjižna polica izbrisana', - 'bookshelf_delete_notification' => 'Bookshelf successfully deleted', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" has been added to your favourites', diff --git a/resources/lang/sl/entities.php b/resources/lang/sl/entities.php index 73bc8797d..6e6d89734 100644 --- a/resources/lang/sl/entities.php +++ b/resources/lang/sl/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Posodobljeno :timeLength', 'meta_updated_name' => 'Posodobil :timeLength uporabnik :user', 'meta_owned_name' => 'V lasti :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Izbira entitete', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Slike', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Polica', 'shelves' => 'Police', 'x_shelves' => ':count Polica|:count Police', - 'shelves_long' => 'Knjižne police', 'shelves_empty' => 'Ustvarjena ni bila nobena polica', 'shelves_create' => 'Ustvari novo polico', 'shelves_popular' => 'Priljubljene police', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'Na tej polici ni nobene knjige', 'shelves_edit_and_assign' => 'Uredi knjižno polico za dodajanje knjig', - 'shelves_edit_named' => 'Uredi knjižno polico :name', - 'shelves_edit' => 'Uredi knjižno polico', - 'shelves_delete' => 'Izbriši knjižno polico', - 'shelves_delete_named' => 'Izbriši knjižno polico :name', - 'shelves_delete_explain' => "S tem boste izbrisali knjižno polico z nazivom ':name'. Vsebovane knjige ne bodo izbrisane.", - 'shelves_delete_confirmation' => 'Ali ste prepričani, da želite izbrisati ta knjižno polico?', - 'shelves_permissions' => 'Dovoljenja knjižnih polic', - 'shelves_permissions_updated' => 'Posodobljena dovoljenja knjižnih polic', - 'shelves_permissions_active' => 'Aktivna dovoljenja knjižnih polic', - 'shelves_permissions_cascade_warning' => 'Permissions on bookshelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Kopiraj dovoljenja na knjige', 'shelves_copy_permissions' => 'Dovoljenja kopiranja', - 'shelves_copy_permissions_explain' => 'To bo uveljavilo trenutne nastavitve dovoljenj na knjižni polici za vse knjige, ki jih vsebuje ta polica. Pred aktiviranjem zagotovite, da so shranjene vse spremembe dovoljenj te knjižne police.', - 'shelves_copy_permission_success' => 'Dovoljenja knjižne police kopirana na :count knjig', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Knjiga', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Uredi vsebino', 'pages_permissions_active' => 'Aktivna dovoljenja strani', 'pages_initial_revision' => 'Prvotno objavljeno', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Nova stran', 'pages_editing_draft_notification' => 'Trenutno urejate osnutek, ki je bil nazadnje shranjen :timeDiff.', 'pages_draft_edited_notification' => 'Ta stran je odtlej posodobljena. Priporočamo, da zavržete ta osnutek.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/sl/errors.php b/resources/lang/sl/errors.php index fcfddf505..0d2c10db6 100644 --- a/resources/lang/sl/errors.php +++ b/resources/lang/sl/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Ne najdem tega objekta', - 'bookshelf_not_found' => 'Knjižna polica ni najdena', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Knjiga ni najdena', 'page_not_found' => 'Stran ni najdena', 'chapter_not_found' => 'Poglavje ni najdeno', diff --git a/resources/lang/sl/settings.php b/resources/lang/sl/settings.php index 40c99f710..b7974c114 100644 --- a/resources/lang/sl/settings.php +++ b/resources/lang/sl/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Čestitke! Če ste prejeli e-poštno obvestilo so bile vaše e-poštne nastavitve pravilno konfigurirane.', 'maint_recycle_bin_desc' => 'Izbrisane police, knjige, poglavja in strani se pošljejo v koš, da jih je mogoče obnoviti ali trajno izbrisati. Starejše predmete v košu lahko čez nekaj časa samodejno odstranite, odvisno od konfiguracije sistema.', 'maint_recycle_bin_open' => 'Odpri koš', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Koš', diff --git a/resources/lang/sv/activities.php b/resources/lang/sv/activities.php index fbd5115ad..1d913b799 100644 --- a/resources/lang/sv/activities.php +++ b/resources/lang/sv/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Book successfully re-sorted', // Bookshelves - 'bookshelf_create' => 'created bookshelf', - 'bookshelf_create_notification' => 'Bookshelf successfully created', - 'bookshelf_create_from_book' => 'converted book to bookshelf', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf', - 'bookshelf_update' => 'uppdaterade hyllan', - 'bookshelf_update_notification' => 'Bookshelf successfully updated', - 'bookshelf_delete' => 'tog bort hyllan', - 'bookshelf_delete_notification' => 'Bookshelf successfully deleted', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" har lagts till i dina favoriter', diff --git a/resources/lang/sv/entities.php b/resources/lang/sv/entities.php index 474a61647..afa94c9ed 100644 --- a/resources/lang/sv/entities.php +++ b/resources/lang/sv/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Uppdaterad :timeLength', 'meta_updated_name' => 'Uppdaterad :timeLength av :user', 'meta_owned_name' => 'Ägs av :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Välj enhet', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Bilder', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Hylla', 'shelves' => 'Hyllor', 'x_shelves' => ':count hylla|:count hyllor', - 'shelves_long' => 'Bokhyllor', 'shelves_empty' => 'Du har inte skapat någon hylla', 'shelves_create' => 'Skapa ny hylla', 'shelves_popular' => 'Populära hyllor', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'Denna hylla har inga böcker än', 'shelves_edit_and_assign' => 'Redigera hyllan för att lägga till böcker', - 'shelves_edit_named' => 'Ändra hyllan :name', - 'shelves_edit' => 'Ändra bokhylla', - 'shelves_delete' => 'Radera bokhylla', - 'shelves_delete_named' => 'Radera bokhyllan :name', - 'shelves_delete_explain' => "Detta kommer radera bokhyllan ':name'. Böckerna på hyllan kommer finnas kvar.", - 'shelves_delete_confirmation' => 'Är du säker på att du vill radera hyllan?', - 'shelves_permissions' => 'Bokhyllerättigheter', - 'shelves_permissions_updated' => 'Bokhyllerättigheterna har ändrats', - 'shelves_permissions_active' => 'Bokhyllerättigheterna är aktiva', - 'shelves_permissions_cascade_warning' => 'Permissions on bookshelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Kopiera rättigheter till böcker', 'shelves_copy_permissions' => 'Kopiera rättigheter', - 'shelves_copy_permissions_explain' => 'Detta kommer kopiera hyllans rättigheter till alla böcker på den. Se till att du har sparat alla ändringar innan du går vidare.', - 'shelves_copy_permission_success' => 'Hyllans rättigheter har kopierats till :count böcker', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Bok', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Redigera innehåll', 'pages_permissions_active' => 'Anpassade rättigheter är i bruk', 'pages_initial_revision' => 'Första publicering', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Ny sida', 'pages_editing_draft_notification' => 'Du redigerar just nu ett utkast som senast sparades :timeDiff.', 'pages_draft_edited_notification' => 'Denna sida har uppdaterats sen dess. Vi rekommenderar att du förkastar dina ändringar.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/sv/errors.php b/resources/lang/sv/errors.php index 28dff2559..482fbc21f 100644 --- a/resources/lang/sv/errors.php +++ b/resources/lang/sv/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Innehållet hittades inte', - 'bookshelf_not_found' => 'Hyllan hittades inte', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Boken hittades inte', 'page_not_found' => 'Sidan hittades inte', 'chapter_not_found' => 'Kapitlet hittades inte', diff --git a/resources/lang/sv/settings.php b/resources/lang/sv/settings.php index 57d01123f..36ec995d1 100644 --- a/resources/lang/sv/settings.php +++ b/resources/lang/sv/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Grattis! Eftersom du fick detta e-postmeddelande verkar dina e-postinställningar vara korrekt konfigurerade.', 'maint_recycle_bin_desc' => 'Borttagna hyllor, böcker, kapitel & sidor skickas till papperskorgen så att de kan återställas eller raderas permanent. Äldre objekt i papperskorgen kan automatiskt tas bort efter ett tag beroende på systemkonfiguration.', 'maint_recycle_bin_open' => 'Öppna papperskorgen', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Papperskorgen', diff --git a/resources/lang/tr/activities.php b/resources/lang/tr/activities.php index d2b6f77b4..6608620f2 100644 --- a/resources/lang/tr/activities.php +++ b/resources/lang/tr/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Kitap başarıyla yeniden sıralandı', // Bookshelves - 'bookshelf_create' => 'kitaplık oluşturuldu', - 'bookshelf_create_notification' => 'Kitaplık başarıyla oluşturuldu', - 'bookshelf_create_from_book' => 'converted book to bookshelf', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf', - 'bookshelf_update' => 'kitaplığı güncelledi', - 'bookshelf_update_notification' => 'Kitaplık başarıyla güncellendi', - 'bookshelf_delete' => 'kitaplığı sildi', - 'bookshelf_delete_notification' => 'Kitaplık başarıyla silindi', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" favorilerinize eklendi', diff --git a/resources/lang/tr/entities.php b/resources/lang/tr/entities.php index bcb02092f..30cd221e3 100644 --- a/resources/lang/tr/entities.php +++ b/resources/lang/tr/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => ':timeLength güncellendi', 'meta_updated_name' => ':user tarafından :timeLength güncellendi', 'meta_owned_name' => 'Owned by :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Öge Seçimi', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Görseller', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Kitaplık', 'shelves' => 'Kitaplıklar', 'x_shelves' => ':count Kitaplık|:count Kitaplık', - 'shelves_long' => 'Kitaplıklar', 'shelves_empty' => 'Hiç kitaplık oluşturulmamış', 'shelves_create' => 'Yeni Kitaplık Oluştur', 'shelves_popular' => 'Popüler Kitaplıklar', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'Bu kitaplıkta hiç kitap bulunamadı', 'shelves_edit_and_assign' => 'Kitap eklemek için kitaplığı düzenleyin', - 'shelves_edit_named' => ':name Kitaplığını Düzenle', - 'shelves_edit' => 'Kitaplığı Düzenle', - 'shelves_delete' => 'Kitaplığı Sil', - 'shelves_delete_named' => ':name Kitaplığını Sil', - 'shelves_delete_explain' => "Bu işlem ':name' kitaplığını silecektir ancak içerdiği kitaplara dokunulmayacaktır.", - 'shelves_delete_confirmation' => 'Bu kitaplığı silmek istediğinize emin misiniz?', - 'shelves_permissions' => 'Kitaplık İzinleri', - 'shelves_permissions_updated' => 'Kitaplık İzinleri Güncellendi', - 'shelves_permissions_active' => 'Kitaplık İzinleri Aktif', - 'shelves_permissions_cascade_warning' => 'Permissions on bookshelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'İzinleri Kitaplara Kopyala', 'shelves_copy_permissions' => 'İzinleri Kopyala', - 'shelves_copy_permissions_explain' => 'Bu işlem sonucunda kitaplığınızın izinleri, içerdiği kitaplara da aynen uygulanır. Aktifleştirmeden önce bu kitaplığa ait izinleri kaydettiğinizden emin olun.', - 'shelves_copy_permission_success' => 'Kitaplık izinleri :count adet kitaba kopyalandı', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Kitap', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'İçeriği Düzenle', 'pages_permissions_active' => 'Sayfa İzinleri Aktif', 'pages_initial_revision' => 'İlk yayın', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Yeni Sayfa', 'pages_editing_draft_notification' => 'Şu anda en son :timeDiff tarihinde kaydedilmiş olan taslağı düzenliyorsunuz.', 'pages_draft_edited_notification' => 'Bu sayfa o zamandan bu zamana güncellenmiş, bu nedenle bu taslağı yok saymanız önerilir.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/tr/errors.php b/resources/lang/tr/errors.php index 2b1ac4c64..5a4669efe 100644 --- a/resources/lang/tr/errors.php +++ b/resources/lang/tr/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Öge bulunamadı', - 'bookshelf_not_found' => 'Kitaplık bulunamadı', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Kitap bulunamadı', 'page_not_found' => 'Sayfa bulunamadı', 'chapter_not_found' => 'Bölüm bulunamadı', diff --git a/resources/lang/tr/settings.php b/resources/lang/tr/settings.php index fbc78cdce..e12d60f69 100755 --- a/resources/lang/tr/settings.php +++ b/resources/lang/tr/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Tebrikler! Eğer bu e-posta bildirimini alıyorsanız, e-posta ayarlarınız doğru bir şekilde ayarlanmış demektir.', 'maint_recycle_bin_desc' => 'Silinen raflar, kitaplar, bölümler ve sayfalar geri dönüşüm kutusuna gönderilir, böylece geri yüklenebilir veya kalıcı olarak silinebilir. Geri dönüşüm kutusundaki daha eski öğeler, sistem yapılandırmasına bağlı olarak bir süre sonra otomatik olarak kaldırılabilir.', 'maint_recycle_bin_open' => 'Geri Dönüşüm Kutusunu Aç', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Geri Dönüşüm Kutusu', diff --git a/resources/lang/uk/activities.php b/resources/lang/uk/activities.php index a4f79fa4c..eab01162b 100644 --- a/resources/lang/uk/activities.php +++ b/resources/lang/uk/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Книгу успішно відновлено', // Bookshelves - 'bookshelf_create' => 'створив книжкову полицю', - 'bookshelf_create_notification' => 'Книжкову полицю успішно створено', - 'bookshelf_create_from_book' => 'конвертувати книгу на книжкову полицю', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Книжку успішно конвертовано на полицю', - 'bookshelf_update' => 'оновив книжкову полицю', - 'bookshelf_update_notification' => 'Книжкову полицю успішно оновлено', - 'bookshelf_delete' => 'видалив книжкову полицю', - 'bookshelf_delete_notification' => 'Книжкову полицю успішно видалено', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":ім\'я" було додане до ваших улюлених', diff --git a/resources/lang/uk/entities.php b/resources/lang/uk/entities.php index d285eac3f..962eb3d9f 100644 --- a/resources/lang/uk/entities.php +++ b/resources/lang/uk/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Оновлено :timeLength', 'meta_updated_name' => ':user оновив :timeLength', 'meta_owned_name' => 'Власник :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Вибір об\'єкта', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Зображення', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Полиця', 'shelves' => 'Полиці', 'x_shelves' => ':count Полиця|:count Полиць', - 'shelves_long' => 'Книжкові полиці', 'shelves_empty' => 'Жодних полиць не було створено', 'shelves_create' => 'Створити нову полицю', 'shelves_popular' => 'Популярні полиці', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'Ця полиця не має призначених їй книг', 'shelves_edit_and_assign' => 'Редагувати полицю для присвоєння книг', - 'shelves_edit_named' => 'Редагувати книжкову полицю :name', - 'shelves_edit' => 'Редагувати книжкову полицю', - 'shelves_delete' => 'Видалити книжкову полицю', - 'shelves_delete_named' => 'Видалити книжкову полицю :name', - 'shelves_delete_explain' => "Це дозволить видалити книжкову полицю з назвою ':name'. Книги не будуть видалені.", - 'shelves_delete_confirmation' => 'Ви впевнені, що хочете видалити цю книжкову полицю?', - 'shelves_permissions' => 'Дозволи на книжкову полицю', - 'shelves_permissions_updated' => 'Дозволи на книжкову полицю оновлено', - 'shelves_permissions_active' => 'Діючі дозволи на книжкову полицю', - 'shelves_permissions_cascade_warning' => 'Дозволи на поличках не потрапляють автоматично каскадом до книг. Це тому, що книга може існувати на кілька полиць. Дозволи, однак можна скопіювати до дочірніх книг, використовуючи нижченаведену опцію.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Копіювати дозволи на книги', 'shelves_copy_permissions' => 'Копіювати дозволи', - 'shelves_copy_permissions_explain' => 'Це застосовує поточні налаштування дозволів цієї книжкової полиці до всіх книг, що містяться всередині. Перш ніж активувати, переконайтесь що будь-які зміни дозволів цієї книжкової полиці були збережені.', - 'shelves_copy_permission_success' => 'Дозволи книжкової полиці скопійовано на :count книг', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Книга', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Редагувати вміст', 'pages_permissions_active' => 'Активні дозволи сторінки', 'pages_initial_revision' => 'Початкова публікація', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Нова сторінка', 'pages_editing_draft_notification' => 'Ви наразі редагуєте чернетку, що була збережена останньою :timeDiff.', 'pages_draft_edited_notification' => 'З того часу ця сторінка була оновлена. Рекомендуємо відмовитися від цього проекту.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'Ви можете конвертувати цей розділ в нову книгу з одним контентом. Будь-які дозволи, встановлені на цьому розділі, будуть скопійовані в нову книгу, але будь-які успадковані дозволи, з батьківської книги не буде скопійований, що може призвести до зміни контролю доступу.', 'convert_chapter' => 'Перетворити розділ', 'convert_chapter_confirm' => 'Ви впевнені, що хочете конвертувати цей розділ?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/uk/errors.php b/resources/lang/uk/errors.php index ee99e3954..72a7fd4c0 100644 --- a/resources/lang/uk/errors.php +++ b/resources/lang/uk/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Об\'єкт не знайдено', - 'bookshelf_not_found' => 'Книжкова полиця не знайдена', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Книга не знайдена', 'page_not_found' => 'Сторінку не знайдено', 'chapter_not_found' => 'Розділ не знайдено', diff --git a/resources/lang/uk/settings.php b/resources/lang/uk/settings.php index 946a0c027..5a454296b 100644 --- a/resources/lang/uk/settings.php +++ b/resources/lang/uk/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Вітаємо! Оскільки ви отримали цього листа, поштова скринька налаштована правильно.', 'maint_recycle_bin_desc' => 'Видалені полиці, книги, розділи та сторінки попадають кошик, щоб їх можна було відновити або видалити остаточно. Старіші елементи з кошика можна автоматично видаляти через деякий час, залежно від налаштувань системи.', 'maint_recycle_bin_open' => 'Відкрити кошик', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Кошик', diff --git a/resources/lang/uz/activities.php b/resources/lang/uz/activities.php index 85ab801f4..31de6af35 100644 --- a/resources/lang/uz/activities.php +++ b/resources/lang/uz/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Kitob muvaffaqiyatli qayta tartiblandi', // Bookshelves - 'bookshelf_create' => 'yaratilgan kitobjavon', - 'bookshelf_create_notification' => 'Kitobjavon muvaffaqiyatli yaratildi', - 'bookshelf_create_from_book' => 'converted book to bookshelf', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf', - 'bookshelf_update' => 'yangilangan kitobjavob', - 'bookshelf_update_notification' => 'Kitobjavon muvaffaqiyatli yangilandi', - 'bookshelf_delete' => 'o\'chirilgan kitobjavon', - 'bookshelf_delete_notification' => 'Kitobjavon muvaffaqiyatli o\'chirildi', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" sevimlilaringizga qo\'shildi', diff --git a/resources/lang/uz/entities.php b/resources/lang/uz/entities.php index c8f258ffd..7ca01e145 100644 --- a/resources/lang/uz/entities.php +++ b/resources/lang/uz/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => ':timeLength da yangilangan', 'meta_updated_name' => ':user tomonidan :timeLength da yangilangan', 'meta_owned_name' => 'Egasi :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Entity Select', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Rasmlar', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Shelf', 'shelves' => 'Shelves', 'x_shelves' => ':count Shelf|:count Shelves', - 'shelves_long' => 'Bookshelves', 'shelves_empty' => 'No shelves have been created', 'shelves_create' => 'Create New Shelf', 'shelves_popular' => 'Popular Shelves', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'This shelf has no books assigned to it', 'shelves_edit_and_assign' => 'Edit shelf to assign books', - 'shelves_edit_named' => 'Edit Bookshelf :name', - 'shelves_edit' => 'Edit Bookshelf', - 'shelves_delete' => 'Delete Bookshelf', - 'shelves_delete_named' => 'Delete Bookshelf :name', - 'shelves_delete_explain' => "This will delete the bookshelf with the name ':name'. Contained books will not be deleted.", - 'shelves_delete_confirmation' => 'Are you sure you want to delete this bookshelf?', - 'shelves_permissions' => 'Bookshelf Permissions', - 'shelves_permissions_updated' => 'Bookshelf Permissions Updated', - 'shelves_permissions_active' => 'Bookshelf Permissions Active', - 'shelves_permissions_cascade_warning' => 'Permissions on bookshelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Copy Permissions to Books', 'shelves_copy_permissions' => 'Copy Permissions', - '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_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Book', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Edit Content', 'pages_permissions_active' => 'Page Permissions Active', 'pages_initial_revision' => 'Initial publish', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'New Page', 'pages_editing_draft_notification' => 'You are currently editing a draft that was last saved :timeDiff.', 'pages_draft_edited_notification' => 'This page has been updated by since that time. It is recommended that you discard this draft.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/uz/errors.php b/resources/lang/uz/errors.php index f023b6bdf..52f96cbe7 100644 --- a/resources/lang/uz/errors.php +++ b/resources/lang/uz/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Entity not found', - 'bookshelf_not_found' => 'Bookshelf not found', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Book not found', 'page_not_found' => 'Page not found', 'chapter_not_found' => 'Chapter not found', diff --git a/resources/lang/uz/settings.php b/resources/lang/uz/settings.php index 3bfe70bc4..9dbd96c5a 100644 --- a/resources/lang/uz/settings.php +++ b/resources/lang/uz/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Congratulations! As you received this email notification, your email settings seem to be configured properly.', 'maint_recycle_bin_desc' => 'Deleted shelves, books, chapters & pages are sent to the recycle bin so they can be restored or permanently deleted. Older items in the recycle bin may be automatically removed after a while depending on system configuration.', 'maint_recycle_bin_open' => 'Open Recycle Bin', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Recycle Bin', diff --git a/resources/lang/vi/activities.php b/resources/lang/vi/activities.php index eb51cd00e..56f3406b3 100644 --- a/resources/lang/vi/activities.php +++ b/resources/lang/vi/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => 'Sách đã được sắp xếp lại thành công', // Bookshelves - 'bookshelf_create' => 'đã tạo giá sách', - 'bookshelf_create_notification' => 'Giá sách đã được tạo thành công', - 'bookshelf_create_from_book' => 'converted book to bookshelf', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf', - 'bookshelf_update' => 'cập nhật giá sách', - 'bookshelf_update_notification' => 'Giá sách đã được cập nhật thành công', - 'bookshelf_delete' => 'đã xóa giá sách', - 'bookshelf_delete_notification' => 'Giá sách đã được xóa thành công', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" đã được thêm vào danh sách yêu thích của bạn', diff --git a/resources/lang/vi/entities.php b/resources/lang/vi/entities.php index 3beeb667b..a8cc8b58e 100644 --- a/resources/lang/vi/entities.php +++ b/resources/lang/vi/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => 'Được cập nhật :timeLength', 'meta_updated_name' => 'Được cập nhật :timeLength bởi :user', 'meta_owned_name' => 'Được sở hữu bởi :user', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => 'Chọn thực thể', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => 'Ảnh', @@ -77,7 +78,6 @@ return [ 'shelf' => 'Giá', 'shelves' => 'Giá', 'x_shelves' => ':count Giá |:count Giá', - 'shelves_long' => 'Giá sách', 'shelves_empty' => 'Không có giá nào được tạo', 'shelves_create' => 'Tạo Giá mới', 'shelves_popular' => 'Các Giá phổ biến', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => 'Giá này không có sách nào', 'shelves_edit_and_assign' => 'Chỉnh sửa kệ để gán sách', - 'shelves_edit_named' => 'Chỉnh sửa kệ sách :name', - 'shelves_edit' => 'Chỉnh sửa kệ sách', - 'shelves_delete' => 'Xóa kệ sách', - 'shelves_delete_named' => 'Xóa kệ sách :name', - 'shelves_delete_explain' => "Chức năng này sẽ xóa kệ sách với tên ':name'. Các sách chứa trong nó sẽ không bị xóa.", - 'shelves_delete_confirmation' => 'Bạn có chắc chắn muốn xóa kệ sách này?', - 'shelves_permissions' => 'Các quyền đối với kệ sách', - 'shelves_permissions_updated' => 'Các quyền với kệ sách đã được cập nhật', - 'shelves_permissions_active' => 'Đang bật các quyền hạn từ Kệ sách', - 'shelves_permissions_cascade_warning' => 'Các quyền trên giá sách sẽ không được tự động gán cho các sách trên đó. Vì một quyển sách có thể tồn tại trên nhiều giá sách. Các quyền có thể được sao chép xuống các quyển sách sử dụng tuỳ chọn dưới đây.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => 'Sao chép các quyền cho sách', 'shelves_copy_permissions' => 'Sao chép các quyền', - 'shelves_copy_permissions_explain' => 'Điều này sẽ áp dụng các cài đặt quyền của giá sách hiện tại với tất cả các cuốn sách bên trong. Trước khi kích hoạt, đảm bảo bất cứ thay đổi liên quan đến quyền của giá sách này đã được lưu.', - 'shelves_copy_permission_success' => 'Các quyền của giá sách đã được sao chép tới :count quyển sách', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => 'Sách', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => 'Soạn thảo Nội dung', 'pages_permissions_active' => 'Đang bật các quyền hạn từ Trang', 'pages_initial_revision' => 'Đăng bài mở đầu', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => 'Trang mới', 'pages_editing_draft_notification' => 'Bạn hiện đang chỉnh sửa một bản nháp được lưu cách đây :timeDiff.', 'pages_draft_edited_notification' => 'Trang này đã được cập nhật từ lúc đó. Bạn nên loại bỏ bản nháp này.', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/vi/errors.php b/resources/lang/vi/errors.php index aff45258b..e731595f3 100644 --- a/resources/lang/vi/errors.php +++ b/resources/lang/vi/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => 'Không tìm thấy thực thể', - 'bookshelf_not_found' => 'Không tìm thấy giá sách', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => 'Không tìm thấy sách', 'page_not_found' => 'Không tìm thấy trang', 'chapter_not_found' => 'Không tìm thấy chương', diff --git a/resources/lang/vi/settings.php b/resources/lang/vi/settings.php index 0c7992f7a..77eb39272 100644 --- a/resources/lang/vi/settings.php +++ b/resources/lang/vi/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => 'Chúc mừng! Khi bạn nhận được email thông báo này, cài đặt email của bạn có vẻ đã được cấu hình đúng.', 'maint_recycle_bin_desc' => 'Deleted shelves, books, chapters & pages are sent to the recycle bin so they can be restored or permanently deleted. Older items in the recycle bin may be automatically removed after a while depending on system configuration.', 'maint_recycle_bin_open' => 'Mở Thùng Rác', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => 'Thùng Rác', diff --git a/resources/lang/zh_CN/activities.php b/resources/lang/zh_CN/activities.php index 59eff434c..a0b717cc2 100644 --- a/resources/lang/zh_CN/activities.php +++ b/resources/lang/zh_CN/activities.php @@ -6,46 +6,46 @@ return [ // Pages - 'page_create' => '创建了页面', - 'page_create_notification' => '页面已成功创建', - 'page_update' => '更新了页面', - 'page_update_notification' => '页面已成功更新', - 'page_delete' => '删除了页面', - 'page_delete_notification' => '页面已成功删除', - 'page_restore' => '恢复了页面', - 'page_restore_notification' => '页面已成功恢复', - 'page_move' => '移动了页面', + 'page_create' => '页面已创建', + 'page_create_notification' => '页面创建成功', + 'page_update' => '页面已更新', + 'page_update_notification' => '页面更新成功', + 'page_delete' => '页面已删除', + 'page_delete_notification' => '页面删除成功', + 'page_restore' => '页面已恢复', + 'page_restore_notification' => '页面恢复成功', + 'page_move' => '页面已移动', // Chapters - 'chapter_create' => '创建了章节', - 'chapter_create_notification' => '章节已成功创建', - 'chapter_update' => '更新了章节', - 'chapter_update_notification' => '章节已成功更新', - 'chapter_delete' => '删除了章节', - 'chapter_delete_notification' => '章节已成功删除', - 'chapter_move' => '移动了章节', + 'chapter_create' => '章节已创建', + 'chapter_create_notification' => '章节创建成功', + 'chapter_update' => '章节已更新', + 'chapter_update_notification' => '章节更新成功', + 'chapter_delete' => '章节已删除', + 'chapter_delete_notification' => '章节删除成功', + 'chapter_move' => '章节已移动', // Books - 'book_create' => '创建了图书', - 'book_create_notification' => '图书已成功创建', + 'book_create' => '图书已创建', + 'book_create_notification' => '成功创建图书', 'book_create_from_chapter' => '将章节转换为图书', 'book_create_from_chapter_notification' => '章节已成功转换为图书', - 'book_update' => '更新了图书', - 'book_update_notification' => '图书已成功更新', - 'book_delete' => '删除了图书', - 'book_delete_notification' => '图书已成功删除', - 'book_sort' => '排序了图书', - 'book_sort_notification' => '图书已成功重新排序', + 'book_update' => '图书已更新', + 'book_update_notification' => '图书更新成功', + 'book_delete' => '图书已删除', + 'book_delete_notification' => '图书删除成功', + 'book_sort' => '图书已排序', + 'book_sort_notification' => '图书重新排序成功', // Bookshelves - 'bookshelf_create' => '创建了书架', - 'bookshelf_create_notification' => '书架已成功创建', + 'bookshelf_create' => '书架已创建', + 'bookshelf_create_notification' => '书架创建成功', 'bookshelf_create_from_book' => '将图书转换为书架', 'bookshelf_create_from_book_notification' => '图书已成功转换为书架', - 'bookshelf_update' => '更新了书架', - 'bookshelf_update_notification' => '书架已成功更新', - 'bookshelf_delete' => '删除了书架', - 'bookshelf_delete_notification' => '书架已成功删除', + 'bookshelf_update' => '书架已更新', + 'bookshelf_update_notification' => '书架更新成功', + 'bookshelf_delete' => '书架已删除', + 'bookshelf_delete_notification' => '书架删除成功', // Favourites 'favourite_add_notification' => '":name" 已添加到您的收藏', @@ -56,16 +56,16 @@ return [ 'mfa_remove_method_notification' => '多重身份认证已成功移除', // Webhooks - 'webhook_create' => '创建了 webhook', - 'webhook_create_notification' => 'Webhook 已成功创建', - 'webhook_update' => '更新了 webhook', - 'webhook_update_notification' => 'Webhook 已成功更新', - 'webhook_delete' => '删除了 webhook', - 'webhook_delete_notification' => 'Webhook 已成功删除', + 'webhook_create' => 'Webhook 已创建', + 'webhook_create_notification' => 'Webhook 创建成功', + 'webhook_update' => 'Webhook 已更新', + 'webhook_update_notification' => 'Webhook 更新成功', + 'webhook_delete' => 'Webhook 已删除', + 'webhook_delete_notification' => 'Webhook 删除成功', // Users 'user_update_notification' => '用户更新成功', - 'user_delete_notification' => '已成功移除用户', + 'user_delete_notification' => '成功移除用户', // Other 'commented_on' => '评论', diff --git a/resources/lang/zh_CN/entities.php b/resources/lang/zh_CN/entities.php index 0718ac1a9..02b39f371 100644 --- a/resources/lang/zh_CN/entities.php +++ b/resources/lang/zh_CN/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => '更新于 :timeLength', 'meta_updated_name' => '由 :user 更新于 :timeLength', 'meta_owned_name' => '拥有者 :user', + 'meta_reference_page_count' => '被 1 个页面引用|被 :count 个页面引用', 'entity_select' => '选择项目', 'entity_select_lack_permission' => '您没有选择此项目所需的权限', 'images' => '图片', @@ -77,7 +78,6 @@ return [ 'shelf' => '书架', 'shelves' => '书架', 'x_shelves' => ':count 书架|:count 书架', - 'shelves_long' => '书架', 'shelves_empty' => '当前未创建书架', 'shelves_create' => '创建新书架', 'shelves_popular' => '热门书架', @@ -95,16 +95,16 @@ return [ 'shelves_edit' => '编辑书架', 'shelves_delete' => '删除书架', 'shelves_delete_named' => '删除书架 :name', - 'shelves_delete_explain' => "此操作将删除书架 ':name'。 其中包含的图书不会被删除。", + 'shelves_delete_explain' => "此操作将删除书架 ”:name”。书架中的图书不会被删除。", 'shelves_delete_confirmation' => '您确定要删除此书架吗?', 'shelves_permissions' => '书架权限', 'shelves_permissions_updated' => '书架权限已更新', - 'shelves_permissions_active' => '书架权限激活', - 'shelves_permissions_cascade_warning' => '书架上的权限不会自动应用到书架里的书。这是因为书可以在多个书架上存在。使用下面的选项可以将权限复制到书架里的书上。', + 'shelves_permissions_active' => '书架权限已启用', + 'shelves_permissions_cascade_warning' => '书架上的权限不会自动应用到书架里的图书上,这是因为图书可以在多个书架上存在。使用下面的选项可以将权限复制到书架里的图书上。', 'shelves_copy_permissions_to_books' => '将权限复制到图书', 'shelves_copy_permissions' => '复制权限', - 'shelves_copy_permissions_explain' => '这会将此书架的当前权限设置应用于其中包含的所有图书。 在激活之前,请确保已保存对此书架权限的任何更改。', - 'shelves_copy_permission_success' => '书架权限复制到图书 :count ', + 'shelves_copy_permissions_explain' => '此操作会将此书架的当前权限设置应用于其中包含的所有图书上。 启用前请确保已保存对此书架权限的任何更改。', + 'shelves_copy_permission_success' => '书架权限已复制到 :count 本图书上', // Books 'book' => '图书', @@ -120,7 +120,7 @@ return [ 'books_create' => '创建图书', 'books_delete' => '删除图书', 'books_delete_named' => '删除图书「:bookName」', - 'books_delete_explain' => '这将删除图书「:bookName」。所有的章节和页面都会被删除。', + 'books_delete_explain' => '此操作将删除图书 “:bookName”。图书中的所有的章节和页面都会被删除。', 'books_delete_confirmation' => '您确定要删除此图书吗?', 'books_edit' => '编辑图书', 'books_edit_named' => '编辑图书「:bookName」', @@ -132,7 +132,7 @@ return [ 'books_empty_create_page' => '创建页面', 'books_empty_sort_current_book' => '排序当前图书', 'books_empty_add_chapter' => '添加章节', - 'books_permissions_active' => '有效的图书权限', + 'books_permissions_active' => '图书权限已启用', 'books_search_this' => '搜索这本书', 'books_navigation' => '图书导航', 'books_sort' => '排序图书内容', @@ -156,7 +156,7 @@ return [ 'chapters_create' => '创建章节', 'chapters_delete' => '删除章节', 'chapters_delete_named' => '删除章节「:chapterName」', - 'chapters_delete_explain' => '这将删除名为“:chapterName”的章节。本章节中存在的所有页面也将被删除。', + 'chapters_delete_explain' => '此操作将删除章节 “:chapterName”。章节中的所有页面都会被删除。', 'chapters_delete_confirm' => '您确定要删除此章节吗?', 'chapters_edit' => '编辑章节', 'chapters_edit_named' => '编辑章节「:chapterName」', @@ -168,7 +168,7 @@ return [ 'chapters_copy_success' => '章节已成功复制', 'chapters_permissions' => '章节权限', 'chapters_empty' => '本章目前没有页面。', - 'chapters_permissions_active' => '有效的章节权限', + 'chapters_permissions_active' => '章节权限已启用', 'chapters_permissions_success' => '章节权限已更新', 'chapters_search_this' => '从本章节搜索', 'chapter_sort_book' => '排序图书', @@ -246,18 +246,19 @@ return [ 'pages_revisions_none' => '此页面没有修订', 'pages_copy_link' => '复制链接', 'pages_edit_content_link' => '编辑内容', - 'pages_permissions_active' => '有效的页面权限', + 'pages_permissions_active' => '页面权限已启用', 'pages_initial_revision' => '初始发布', + 'pages_references_update_revision' => '系统自动更新的内部链接', 'pages_initial_name' => '新页面', 'pages_editing_draft_notification' => '您正在编辑在 :timeDiff 内保存的草稿.', 'pages_draft_edited_notification' => '此后,此页面已经被更新,建议您放弃此草稿。', 'pages_draft_page_changed_since_creation' => '这个页面在您的草稿创建后被其他用户更新了,您目前的草稿不包含新的内容。建议您放弃此草稿,或是注意不要覆盖新的页面更改。', 'pages_draft_edit_active' => [ - 'start_a' => ':count位用户正在编辑此页面', - 'start_b' => '用户“:userName”已经开始编辑此页面', + 'start_a' => ':count 位用户已开始编辑此页面', + 'start_b' => '用户 “:userName” 已经开始编辑此页面', 'time_a' => '自页面上次更新以来', - 'time_b' => '在最近:minCount分钟', - 'message' => ':time,:start。注意不要覆盖对方的更新!', + 'time_b' => '在最近 :minCount 分钟', + 'message' => ':time :start。注意不要覆盖他人的更新!', ], 'pages_draft_discarded' => '草稿已丢弃,编辑器已更新到当前页面内容。', 'pages_specific' => '具体页面', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => '您可以将此章节转换为具有相同内容的新图书。此章节中设置的任何权限都将复制到新图书上,但从父图书继承的任何权限都不会被复制,这可能会导致访问控制发生变化。', 'convert_chapter' => '转换章节', 'convert_chapter_confirm' => '您确定要转换此章节吗?', + + // References + 'references' => '引用', + 'references_none' => '没有跟踪到对此项目的引用。', + 'references_to_desc' => '下面显示的是系统中所有已知链接到这个项目的页面。', ]; diff --git a/resources/lang/zh_CN/errors.php b/resources/lang/zh_CN/errors.php index b1028277c..66ee79a17 100644 --- a/resources/lang/zh_CN/errors.php +++ b/resources/lang/zh_CN/errors.php @@ -86,7 +86,7 @@ return [ // Error pages '404_page_not_found' => '无法找到页面', 'sorry_page_not_found' => '对不起,无法找到您想访问的页面。', - 'sorry_page_not_found_permission_warning' => '您可能没有查看权限。', + 'sorry_page_not_found_permission_warning' => '如果您确认这个页面存在,则代表您可能没有查看权限。', 'image_not_found' => '未找到图片', 'image_not_found_subtitle' => '对不起,无法找到您想访问的图片。', 'image_not_found_details' => '原本放在这里的图片已被删除。', @@ -98,7 +98,7 @@ return [ // API errors 'api_no_authorization_found' => '未在请求中找到授权令牌', 'api_bad_authorization_format' => '已在请求中找到授权令牌,但格式貌似不正确', - 'api_user_token_not_found' => '未能找到所匹配的API提供的授权令牌', + 'api_user_token_not_found' => '未找到与提供的授权令牌匹配的 API 令牌', 'api_incorrect_token_secret' => '给已给出的API所提供的密钥不正确', 'api_user_no_api_permission' => '使用过的 API 令牌的所有者没有进行API 调用的权限', 'api_user_token_expired' => '所使用的身份令牌已过期', diff --git a/resources/lang/zh_CN/settings.php b/resources/lang/zh_CN/settings.php index f769bdc52..c68924f8d 100755 --- a/resources/lang/zh_CN/settings.php +++ b/resources/lang/zh_CN/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => '恭喜!您收到了此邮件通知,您的电子邮件设置看起来已配置正确。', 'maint_recycle_bin_desc' => '被删除的书架、书籍、章节和页面会被存入回收站,您可以还原或永久删除它们。回收站中较旧的项目可能会在系统设置的一段时间后被自动删除。', 'maint_recycle_bin_open' => '打开回收站', + 'maint_regen_references' => '重新生成引用', + 'maint_regen_references_desc' => '此操作将重建数据库中的跨项目引用索引。这通常是自动处理的,但可能有助于索引旧内容或通过非官方方法添加的内容。', + 'maint_regen_references_success' => '引用索引已重新生成!', + 'maint_timeout_command_note' => '注意:执行此操作需要一些时间,这可能会导致在某些 Web 环境中出现超时问题。作为替代方案,此操作也可以在终端中执行。', // Recycle Bin 'recycle_bin' => '回收站', @@ -146,16 +150,16 @@ return [ 'role_system' => '系统权限', 'role_manage_users' => '管理用户', 'role_manage_roles' => '管理角色与角色权限', - 'role_manage_entity_permissions' => '管理所有图书,章节和页面的权限', - 'role_manage_own_entity_permissions' => '管理自己的图书,章节和页面的权限', + 'role_manage_entity_permissions' => '管理所有图书、章节和页面的权限', + 'role_manage_own_entity_permissions' => '管理自己的图书、章节和页面的权限', 'role_manage_page_templates' => '管理页面模板', 'role_access_api' => '访问系统 API', - 'role_manage_settings' => '管理App设置', + 'role_manage_settings' => '管理 App 设置', 'role_export_content' => '导出内容', 'role_editor_change' => '更改页面编辑器', 'role_asset' => '资源许可', - 'roles_system_warning' => '请注意,拥有上述三个权限中的任何一个都可以允许用户更改自己的权限或系统中其他人的权限。 请只将拥有这些权限的角色分配给你信任的用户。', - 'role_asset_desc' => '对系统内资源的默认访问许可将由这些权限控制。单独设置在书籍,章节和页面上的权限将覆盖这里的权限设定。', + 'roles_system_warning' => '请注意,拥有以上三个权限中的任何一个都会允许用户更改自己的权限或系统中其他人的权限。 请只将拥有这些权限的角色分配给你信任的用户。', + 'role_asset_desc' => '对系统内资源的默认访问许可将由这些权限控制。单独设置在书籍、章节和页面上的权限将覆盖这里的权限设定。', 'role_asset_admins' => '管理员可自动获得对所有内容的访问权限,但这些选项可能会显示或隐藏UI选项。', 'role_all' => '全部的', 'role_own' => '拥有的', diff --git a/resources/lang/zh_TW/activities.php b/resources/lang/zh_TW/activities.php index 69639cbb6..d2e6e06b1 100644 --- a/resources/lang/zh_TW/activities.php +++ b/resources/lang/zh_TW/activities.php @@ -38,14 +38,14 @@ return [ 'book_sort_notification' => '書本已重新排序成功', // Bookshelves - 'bookshelf_create' => '已建立書架', - 'bookshelf_create_notification' => '書架已建立成功', - 'bookshelf_create_from_book' => 'converted book to bookshelf', + 'bookshelf_create' => 'created shelf', + 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'Book successfully converted to a shelf', - 'bookshelf_update' => '已更新書架', - 'bookshelf_update_notification' => '書架已更新成功', - 'bookshelf_delete' => '已刪除書架', - 'bookshelf_delete_notification' => '書架已刪除成功', + 'bookshelf_update' => 'updated shelf', + 'bookshelf_update_notification' => 'Shelf successfully updated', + 'bookshelf_delete' => 'deleted shelf', + 'bookshelf_delete_notification' => 'Shelf successfully deleted', // Favourites 'favourite_add_notification' => '":name" 已加入到你的最愛', diff --git a/resources/lang/zh_TW/entities.php b/resources/lang/zh_TW/entities.php index 73c738792..574227287 100644 --- a/resources/lang/zh_TW/entities.php +++ b/resources/lang/zh_TW/entities.php @@ -23,6 +23,7 @@ return [ 'meta_updated' => '更新於 :timeLength', 'meta_updated_name' => '由 :user 更新於 :timeLength', 'meta_owned_name' => ':user 所擁有', + 'meta_reference_page_count' => 'Referenced on 1 page|Referenced on :count pages', 'entity_select' => '選取項目', 'entity_select_lack_permission' => 'You don\'t have the required permissions to select this item', 'images' => '圖片', @@ -77,7 +78,6 @@ return [ 'shelf' => '書架', 'shelves' => '書架', 'x_shelves' => ':count 書架 | :count 章節', - 'shelves_long' => '書架', 'shelves_empty' => '尚未建立書架', 'shelves_create' => '建立新書架', 'shelves_popular' => '熱門書架', @@ -91,20 +91,20 @@ return [ 'shelves_drag_books' => 'Drag books below to add them to this shelf', 'shelves_empty_contents' => '此書架沒有分配任何書本', 'shelves_edit_and_assign' => '編輯書架以分配書本', - 'shelves_edit_named' => '編輯書架 :name', - 'shelves_edit' => '編輯書架', - 'shelves_delete' => '刪除書架', - 'shelves_delete_named' => '刪除書架 :name', - 'shelves_delete_explain' => "這將刪除名為「:name」的書架。但其中的書本不會被刪除。", - 'shelves_delete_confirmation' => '您確定要刪除此書架嗎?', - 'shelves_permissions' => '書架權限', - 'shelves_permissions_updated' => '書架權限已更新', - 'shelves_permissions_active' => '書架權限已啟用', - 'shelves_permissions_cascade_warning' => 'Permissions on bookshelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', + 'shelves_edit_named' => 'Edit Shelf :name', + 'shelves_edit' => 'Edit Shelf', + 'shelves_delete' => 'Delete Shelf', + 'shelves_delete_named' => 'Delete Shelf :name', + 'shelves_delete_explain' => "This will delete the shelf with the name ':name'. Contained books will not be deleted.", + 'shelves_delete_confirmation' => 'Are you sure you want to delete this shelf?', + 'shelves_permissions' => 'Shelf Permissions', + 'shelves_permissions_updated' => 'Shelf Permissions Updated', + 'shelves_permissions_active' => 'Shelf Permissions Active', + 'shelves_permissions_cascade_warning' => 'Permissions on shelves do not automatically cascade to contained books. This is because a book can exist on multiple shelves. Permissions can however be copied down to child books using the option found below.', 'shelves_copy_permissions_to_books' => '將權限複製到書本', 'shelves_copy_permissions' => '複製權限', - 'shelves_copy_permissions_explain' => '這會將此書架目前的權限設定套用到所有包含的書本上。在啟用前,請確認您已儲存任何對此書架權限的變更。', - 'shelves_copy_permission_success' => '已將書架的權限複製到 :count 本書上', + 'shelves_copy_permissions_explain' => 'This will apply the current permission settings of this shelf to all books contained within. Before activating, ensure any changes to the permissions of this shelf have been saved.', + 'shelves_copy_permission_success' => 'Shelf permissions copied to :count books', // Books 'book' => '書本', @@ -248,6 +248,7 @@ return [ 'pages_edit_content_link' => '編輯內容', 'pages_permissions_active' => '頁面權限已啟用', 'pages_initial_revision' => '初次發布', + 'pages_references_update_revision' => 'System auto-update of internal links', 'pages_initial_name' => '新頁面', 'pages_editing_draft_notification' => '您正在編輯最後儲存為 :timeDiff 的草稿。', 'pages_draft_edited_notification' => '此頁面已經被更新過。建議您放棄此草稿。', @@ -331,7 +332,7 @@ return [ 'comments' => '評論', 'comment_add' => '新增評論', 'comment_placeholder' => '在這裡評論', - 'comment_count' => '{0} 無評論 |{1} :count 則評論 | [2,*] :count 則評論', + 'comment_count' => '{0} 無評論 |{1} :count 則評論 |[2,*] :count 則評論', 'comment_save' => '儲存評論', 'comment_saving' => '正在儲存評論……', 'comment_deleting' => '正在刪除評論……', @@ -369,4 +370,9 @@ return [ 'convert_to_book_desc' => 'You can convert this chapter to a new book with the same contents. Any permissions set on this chapter will be copied to the new book but any inherited permissions, from the parent book, will not be copied which could lead to a change of access control.', 'convert_chapter' => 'Convert Chapter', 'convert_chapter_confirm' => 'Are you sure you want to convert this chapter?', + + // References + 'references' => 'References', + 'references_none' => 'There are no tracked references to this item.', + 'references_to_desc' => 'Shown below are all the known pages in the system that link to this item.', ]; diff --git a/resources/lang/zh_TW/errors.php b/resources/lang/zh_TW/errors.php index 2a4483054..c6644dd1c 100644 --- a/resources/lang/zh_TW/errors.php +++ b/resources/lang/zh_TW/errors.php @@ -58,7 +58,7 @@ return [ // Entities 'entity_not_found' => '找不到實體', - 'bookshelf_not_found' => '找不到書架', + 'bookshelf_not_found' => 'Shelf not found', 'book_not_found' => '找不到書本', 'page_not_found' => '找不到頁面', 'chapter_not_found' => '找不到章節', diff --git a/resources/lang/zh_TW/settings.php b/resources/lang/zh_TW/settings.php index 5fcc4bc33..23f9eb0c6 100644 --- a/resources/lang/zh_TW/settings.php +++ b/resources/lang/zh_TW/settings.php @@ -89,6 +89,10 @@ return [ 'maint_send_test_email_mail_text' => '恭喜!您收到這封電子郵件通知時,代表您的電子郵件設定已正確設定。', 'maint_recycle_bin_desc' => '刪除的書架、書本、章節與頁面將會被傳送到回收桶,這樣仍可以還原或永久刪除。回收桶中較舊的項目可能會在一段時間後自動移除,取決於您的系統設定。', 'maint_recycle_bin_open' => '開啟回收桶', + 'maint_regen_references' => 'Regenerate References', + 'maint_regen_references_desc' => 'This action will rebuild the cross-item reference index within the database. This is usually handled automatically but this action can be useful to index old content or content added via unofficial methods.', + 'maint_regen_references_success' => 'Reference index has been regenerated!', + 'maint_timeout_command_note' => 'Note: This action can take time to run, which can lead to timeout issues in some web environments. As an alternative, this action be performed using a terminal command.', // Recycle Bin 'recycle_bin' => '資源回收桶', From ee1e9366601d5cb9d2dd981b272341039d4f2fb9 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Mon, 5 Sep 2022 13:18:37 +0100 Subject: [PATCH 33/45] Applied styleci changes, updated composer deps --- app/Http/Middleware/Localization.php | 1 - app/Util/LanguageManager.php | 8 +- composer.lock | 152 ++++++++++++++------------- tests/Entity/PageRevisionTest.php | 1 - 4 files changed, 81 insertions(+), 81 deletions(-) diff --git a/app/Http/Middleware/Localization.php b/app/Http/Middleware/Localization.php index d8bb296fc..3a2dd2190 100644 --- a/app/Http/Middleware/Localization.php +++ b/app/Http/Middleware/Localization.php @@ -44,5 +44,4 @@ class Localization return $next($request); } - } diff --git a/app/Util/LanguageManager.php b/app/Util/LanguageManager.php index ff860c83d..c33c73ad5 100644 --- a/app/Util/LanguageManager.php +++ b/app/Util/LanguageManager.php @@ -7,7 +7,7 @@ use Illuminate\Http\Request; class LanguageManager { /** - * Array of right-to-left language options + * Array of right-to-left language options. */ protected array $rtlLanguages = ['ar', 'fa', 'he']; @@ -15,7 +15,7 @@ class LanguageManager * Map of BookStack language names to best-estimate ISO and windows locale names. * Locales can often be found by running `locale -a` on a linux system. * Windows locales can be found at: - * https://docs.microsoft.com/en-us/cpp/c-runtime-library/language-strings?view=msvc-170 + * https://docs.microsoft.com/en-us/cpp/c-runtime-library/language-strings?view=msvc-170. * * @var array */ @@ -121,10 +121,10 @@ class LanguageManager $isoLang ? $isoLang . '.utf8' : false, $isoLang ?: false, $isoLang ? str_replace('_', '-', $isoLang) : false, - $this->localeMap[$language]['windows'] ?? false, + $this->localeMap[$language]['windows'] ?? false, $language, ]); setlocale(LC_TIME, ...$locales); } -} \ No newline at end of file +} diff --git a/composer.lock b/composer.lock index f869d997a..6f9ed25cc 100644 --- a/composer.lock +++ b/composer.lock @@ -58,16 +58,16 @@ }, { "name": "aws/aws-sdk-php", - "version": "3.234.4", + "version": "3.235.1", "source": { "type": "git", "url": "https://github.com/aws/aws-sdk-php.git", - "reference": "8d56ddb99632200273bb933cbf82b758ab9cde2a" + "reference": "2025db05c7dd22ae414857dadd49207f64c2fc74" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/8d56ddb99632200273bb933cbf82b758ab9cde2a", - "reference": "8d56ddb99632200273bb933cbf82b758ab9cde2a", + "url": "https://api.github.com/repos/aws/aws-sdk-php/zipball/2025db05c7dd22ae414857dadd49207f64c2fc74", + "reference": "2025db05c7dd22ae414857dadd49207f64c2fc74", "shasum": "" }, "require": { @@ -144,9 +144,9 @@ "support": { "forum": "https://forums.aws.amazon.com/forum.jspa?forumID=80", "issues": "https://github.com/aws/aws-sdk-php/issues", - "source": "https://github.com/aws/aws-sdk-php/tree/3.234.4" + "source": "https://github.com/aws/aws-sdk-php/tree/3.235.1" }, - "time": "2022-08-26T18:20:48+00:00" + "time": "2022-09-02T18:18:19+00:00" }, { "name": "bacon/bacon-qr-code", @@ -559,16 +559,16 @@ }, { "name": "doctrine/dbal", - "version": "3.4.2", + "version": "3.4.3", "source": { "type": "git", "url": "https://github.com/doctrine/dbal.git", - "reference": "22de295f10edbe00df74f517612f1fbd711131e2" + "reference": "a24b89d663d8f261199bc0a91c48016042ebda85" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/doctrine/dbal/zipball/22de295f10edbe00df74f517612f1fbd711131e2", - "reference": "22de295f10edbe00df74f517612f1fbd711131e2", + "url": "https://api.github.com/repos/doctrine/dbal/zipball/a24b89d663d8f261199bc0a91c48016042ebda85", + "reference": "a24b89d663d8f261199bc0a91c48016042ebda85", "shasum": "" }, "require": { @@ -581,8 +581,8 @@ "psr/log": "^1|^2|^3" }, "require-dev": { - "doctrine/coding-standard": "9.0.0", - "jetbrains/phpstorm-stubs": "2022.1", + "doctrine/coding-standard": "10.0.0", + "jetbrains/phpstorm-stubs": "2022.2", "phpstan/phpstan": "1.8.2", "phpstan/phpstan-strict-rules": "^1.3", "phpunit/phpunit": "9.5.21", @@ -650,7 +650,7 @@ ], "support": { "issues": "https://github.com/doctrine/dbal/issues", - "source": "https://github.com/doctrine/dbal/tree/3.4.2" + "source": "https://github.com/doctrine/dbal/tree/3.4.3" }, "funding": [ { @@ -666,7 +666,7 @@ "type": "tidelift" } ], - "time": "2022-08-21T14:21:06+00:00" + "time": "2022-08-28T17:26:36+00:00" }, { "name": "doctrine/deprecations", @@ -1965,25 +1965,26 @@ }, { "name": "laravel/serializable-closure", - "version": "v1.2.0", + "version": "v1.2.1", "source": { "type": "git", "url": "https://github.com/laravel/serializable-closure.git", - "reference": "09f0e9fb61829f628205b7c94906c28740ff9540" + "reference": "d78fd36ba031a1a695ea5a406f29996948d7011b" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/09f0e9fb61829f628205b7c94906c28740ff9540", - "reference": "09f0e9fb61829f628205b7c94906c28740ff9540", + "url": "https://api.github.com/repos/laravel/serializable-closure/zipball/d78fd36ba031a1a695ea5a406f29996948d7011b", + "reference": "d78fd36ba031a1a695ea5a406f29996948d7011b", "shasum": "" }, "require": { "php": "^7.3|^8.0" }, "require-dev": { - "pestphp/pest": "^1.18", - "phpstan/phpstan": "^0.12.98", - "symfony/var-dumper": "^5.3" + "nesbot/carbon": "^2.61", + "pestphp/pest": "^1.21.3", + "phpstan/phpstan": "^1.8.2", + "symfony/var-dumper": "^5.4.11" }, "type": "library", "extra": { @@ -2020,7 +2021,7 @@ "issues": "https://github.com/laravel/serializable-closure/issues", "source": "https://github.com/laravel/serializable-closure" }, - "time": "2022-05-16T17:09:47+00:00" + "time": "2022-08-26T15:25:27+00:00" }, { "name": "laravel/socialite", @@ -2997,16 +2998,16 @@ }, { "name": "nesbot/carbon", - "version": "2.62.0", + "version": "2.62.1", "source": { "type": "git", "url": "https://github.com/briannesbitt/Carbon.git", - "reference": "7507aec3d626797ce2123cf6c6556683be22b5f8" + "reference": "01bc4cdefe98ef58d1f9cb31bdbbddddf2a88f7a" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/7507aec3d626797ce2123cf6c6556683be22b5f8", - "reference": "7507aec3d626797ce2123cf6c6556683be22b5f8", + "url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/01bc4cdefe98ef58d1f9cb31bdbbddddf2a88f7a", + "reference": "01bc4cdefe98ef58d1f9cb31bdbbddddf2a88f7a", "shasum": "" }, "require": { @@ -3095,20 +3096,20 @@ "type": "tidelift" } ], - "time": "2022-08-28T19:48:05+00:00" + "time": "2022-09-02T07:48:13+00:00" }, { "name": "nikic/php-parser", - "version": "v4.14.0", + "version": "v4.15.1", "source": { "type": "git", "url": "https://github.com/nikic/PHP-Parser.git", - "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1" + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/34bea19b6e03d8153165d8f30bba4c3be86184c1", - "reference": "34bea19b6e03d8153165d8f30bba4c3be86184c1", + "url": "https://api.github.com/repos/nikic/PHP-Parser/zipball/0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", + "reference": "0ef6c55a3f47f89d7a374e6f835197a0b5fcf900", "shasum": "" }, "require": { @@ -3149,9 +3150,9 @@ ], "support": { "issues": "https://github.com/nikic/PHP-Parser/issues", - "source": "https://github.com/nikic/PHP-Parser/tree/v4.14.0" + "source": "https://github.com/nikic/PHP-Parser/tree/v4.15.1" }, - "time": "2022-05-31T20:59:12+00:00" + "time": "2022-09-04T07:30:47+00:00" }, { "name": "onelogin/php-saml", @@ -3558,16 +3559,16 @@ }, { "name": "phpseclib/phpseclib", - "version": "3.0.14", + "version": "3.0.15", "source": { "type": "git", "url": "https://github.com/phpseclib/phpseclib.git", - "reference": "2f0b7af658cbea265cbb4a791d6c29a6613f98ef" + "reference": "c96e250238e88bf1040e9f7715efab1d6bc7f622" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/2f0b7af658cbea265cbb4a791d6c29a6613f98ef", - "reference": "2f0b7af658cbea265cbb4a791d6c29a6613f98ef", + "url": "https://api.github.com/repos/phpseclib/phpseclib/zipball/c96e250238e88bf1040e9f7715efab1d6bc7f622", + "reference": "c96e250238e88bf1040e9f7715efab1d6bc7f622", "shasum": "" }, "require": { @@ -3579,6 +3580,7 @@ "phpunit/phpunit": "*" }, "suggest": { + "ext-dom": "Install the DOM extension to load XML formatted public keys.", "ext-gmp": "Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.", "ext-libsodium": "SSH2/SFTP can make use of some algorithms provided by the libsodium-php extension.", "ext-mcrypt": "Install the Mcrypt extension in order to speed up a few other cryptographic operations.", @@ -3647,7 +3649,7 @@ ], "support": { "issues": "https://github.com/phpseclib/phpseclib/issues", - "source": "https://github.com/phpseclib/phpseclib/tree/3.0.14" + "source": "https://github.com/phpseclib/phpseclib/tree/3.0.15" }, "funding": [ { @@ -3663,7 +3665,7 @@ "type": "tidelift" } ], - "time": "2022-04-04T05:15:45+00:00" + "time": "2022-09-02T17:05:08+00:00" }, { "name": "pragmarx/google2fa", @@ -4667,22 +4669,22 @@ }, { "name": "socialiteproviders/manager", - "version": "v4.1.0", + "version": "v4.2.0", "source": { "type": "git", "url": "https://github.com/SocialiteProviders/Manager.git", - "reference": "4e63afbd26dc45ff263591de2a0970436a6a0bf9" + "reference": "738276dfbc2b68a9145db7b3df1588d53db528a1" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/SocialiteProviders/Manager/zipball/4e63afbd26dc45ff263591de2a0970436a6a0bf9", - "reference": "4e63afbd26dc45ff263591de2a0970436a6a0bf9", + "url": "https://api.github.com/repos/SocialiteProviders/Manager/zipball/738276dfbc2b68a9145db7b3df1588d53db528a1", + "reference": "738276dfbc2b68a9145db7b3df1588d53db528a1", "shasum": "" }, "require": { "illuminate/support": "^6.0 || ^7.0 || ^8.0 || ^9.0", - "laravel/socialite": "~4.0 || ~5.0", - "php": "^7.2 || ^8.0" + "laravel/socialite": "~5.0", + "php": "^7.4 || ^8.0" }, "require-dev": { "mockery/mockery": "^1.2", @@ -4737,7 +4739,7 @@ "issues": "https://github.com/socialiteproviders/manager/issues", "source": "https://github.com/socialiteproviders/manager" }, - "time": "2022-01-23T22:40:23+00:00" + "time": "2022-09-02T10:20:10+00:00" }, { "name": "socialiteproviders/microsoft-azure", @@ -8957,16 +8959,16 @@ }, { "name": "phpstan/phpstan", - "version": "1.8.2", + "version": "1.8.4", "source": { "type": "git", "url": "https://github.com/phpstan/phpstan.git", - "reference": "c53312ecc575caf07b0e90dee43883fdf90ca67c" + "reference": "eed4c9da531f6ebb4787235b6fb486e2c20f34e5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/phpstan/phpstan/zipball/c53312ecc575caf07b0e90dee43883fdf90ca67c", - "reference": "c53312ecc575caf07b0e90dee43883fdf90ca67c", + "url": "https://api.github.com/repos/phpstan/phpstan/zipball/eed4c9da531f6ebb4787235b6fb486e2c20f34e5", + "reference": "eed4c9da531f6ebb4787235b6fb486e2c20f34e5", "shasum": "" }, "require": { @@ -8990,9 +8992,13 @@ "MIT" ], "description": "PHPStan - PHP Static Analysis Tool", + "keywords": [ + "dev", + "static analysis" + ], "support": { "issues": "https://github.com/phpstan/phpstan/issues", - "source": "https://github.com/phpstan/phpstan/tree/1.8.2" + "source": "https://github.com/phpstan/phpstan/tree/1.8.4" }, "funding": [ { @@ -9003,29 +9009,25 @@ "url": "https://github.com/phpstan", "type": "github" }, - { - "url": "https://www.patreon.com/phpstan", - "type": "patreon" - }, { "url": "https://tidelift.com/funding/github/packagist/phpstan/phpstan", "type": "tidelift" } ], - "time": "2022-07-20T09:57:31+00:00" + "time": "2022-09-03T13:08:04+00:00" }, { "name": "phpunit/php-code-coverage", - "version": "9.2.16", + "version": "9.2.17", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/php-code-coverage.git", - "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073" + "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/2593003befdcc10db5e213f9f28814f5aa8ac073", - "reference": "2593003befdcc10db5e213f9f28814f5aa8ac073", + "url": "https://api.github.com/repos/sebastianbergmann/php-code-coverage/zipball/aa94dc41e8661fe90c7316849907cba3007b10d8", + "reference": "aa94dc41e8661fe90c7316849907cba3007b10d8", "shasum": "" }, "require": { @@ -9081,7 +9083,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/php-code-coverage/issues", - "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.16" + "source": "https://github.com/sebastianbergmann/php-code-coverage/tree/9.2.17" }, "funding": [ { @@ -9089,7 +9091,7 @@ "type": "github" } ], - "time": "2022-08-20T05:26:47+00:00" + "time": "2022-08-30T12:24:04+00:00" }, { "name": "phpunit/php-file-iterator", @@ -9334,16 +9336,16 @@ }, { "name": "phpunit/phpunit", - "version": "9.5.23", + "version": "9.5.24", "source": { "type": "git", "url": "https://github.com/sebastianbergmann/phpunit.git", - "reference": "888556852e7e9bbeeedb9656afe46118765ade34" + "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/888556852e7e9bbeeedb9656afe46118765ade34", - "reference": "888556852e7e9bbeeedb9656afe46118765ade34", + "url": "https://api.github.com/repos/sebastianbergmann/phpunit/zipball/d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", + "reference": "d0aa6097bef9fd42458a9b3c49da32c6ce6129c5", "shasum": "" }, "require": { @@ -9372,7 +9374,7 @@ "sebastian/global-state": "^5.0.1", "sebastian/object-enumerator": "^4.0.3", "sebastian/resource-operations": "^3.0.3", - "sebastian/type": "^3.0", + "sebastian/type": "^3.1", "sebastian/version": "^3.0.2" }, "suggest": { @@ -9416,7 +9418,7 @@ ], "support": { "issues": "https://github.com/sebastianbergmann/phpunit/issues", - "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.23" + "source": "https://github.com/sebastianbergmann/phpunit/tree/9.5.24" }, "funding": [ { @@ -9428,7 +9430,7 @@ "type": "github" } ], - "time": "2022-08-22T14:01:36+00:00" + "time": "2022-08-30T07:42:16+00:00" }, { "name": "react/promise", @@ -10536,16 +10538,16 @@ }, { "name": "seld/phar-utils", - "version": "1.2.0", + "version": "1.2.1", "source": { "type": "git", "url": "https://github.com/Seldaek/phar-utils.git", - "reference": "9f3452c93ff423469c0d56450431562ca423dcee" + "reference": "ea2f4014f163c1be4c601b9b7bd6af81ba8d701c" }, "dist": { "type": "zip", - "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/9f3452c93ff423469c0d56450431562ca423dcee", - "reference": "9f3452c93ff423469c0d56450431562ca423dcee", + "url": "https://api.github.com/repos/Seldaek/phar-utils/zipball/ea2f4014f163c1be4c601b9b7bd6af81ba8d701c", + "reference": "ea2f4014f163c1be4c601b9b7bd6af81ba8d701c", "shasum": "" }, "require": { @@ -10578,9 +10580,9 @@ ], "support": { "issues": "https://github.com/Seldaek/phar-utils/issues", - "source": "https://github.com/Seldaek/phar-utils/tree/1.2.0" + "source": "https://github.com/Seldaek/phar-utils/tree/1.2.1" }, - "time": "2021-12-10T11:20:11+00:00" + "time": "2022-08-31T10:31:18+00:00" }, { "name": "seld/signal-handler", diff --git a/tests/Entity/PageRevisionTest.php b/tests/Entity/PageRevisionTest.php index 01252eda9..5ddad8441 100644 --- a/tests/Entity/PageRevisionTest.php +++ b/tests/Entity/PageRevisionTest.php @@ -9,7 +9,6 @@ use Tests\TestCase; class PageRevisionTest extends TestCase { - public function test_revision_links_visible_to_viewer() { /** @var Page $page */ From 2d7552aa09f41d019b40de31763ae104ca64f8a4 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Mon, 5 Sep 2022 13:33:05 +0100 Subject: [PATCH 34/45] Addressed setlocale issue caught by phpstan setlocale could be called with no second param if the language given to the modified function was empty. --- app/Util/LanguageManager.php | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/Util/LanguageManager.php b/app/Util/LanguageManager.php index c33c73ad5..33ec0e3a9 100644 --- a/app/Util/LanguageManager.php +++ b/app/Util/LanguageManager.php @@ -113,7 +113,7 @@ class LanguageManager * Set the system date locale for localized date formatting. * Will try both the standard locale name and the UTF8 variant. */ - public function setPhpDateTimeLocale(string $language) + public function setPhpDateTimeLocale(string $language): void { $isoLang = $this->localeMap[$language]['iso'] ?? false; @@ -125,6 +125,8 @@ class LanguageManager $language, ]); - setlocale(LC_TIME, ...$locales); + if (!empty($locales)) { + setlocale(LC_TIME, ...$locales); + } } } From b698bb0e07689feeb7b80e958bfffa5cf4602423 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Mon, 5 Sep 2022 15:06:47 +0100 Subject: [PATCH 35/45] Wrapped wysiwyg drawing change in editor transaction To make the content changes made a undoable transaction that is picked up as a change. From my testing, should address #3682 --- resources/js/wysiwyg/plugin-drawio.js | 22 ++++++++++++++-------- 1 file changed, 14 insertions(+), 8 deletions(-) diff --git a/resources/js/wysiwyg/plugin-drawio.js b/resources/js/wysiwyg/plugin-drawio.js index 54a160921..64ef1fffb 100644 --- a/resources/js/wysiwyg/plugin-drawio.js +++ b/resources/js/wysiwyg/plugin-drawio.js @@ -18,11 +18,13 @@ function showDrawingManager(mceEditor, selectedNode = null) { // Show image manager window.ImageManager.show(function (image) { if (selectedNode) { - let imgElem = selectedNode.querySelector('img'); - pageEditor.dom.setAttrib(imgElem, 'src', image.url); - pageEditor.dom.setAttrib(selectedNode, 'drawio-diagram', image.id); + const imgElem = selectedNode.querySelector('img'); + pageEditor.undoManager.transact(function () { + pageEditor.dom.setAttrib(imgElem, 'src', image.url); + pageEditor.dom.setAttrib(selectedNode, 'drawio-diagram', image.id); + }); } else { - let imgHTML = `
`; + const imgHTML = `
`; pageEditor.insertContent(imgHTML); } }, 'drawio'); @@ -53,8 +55,10 @@ async function updateContent(pngData) { let imgElem = currentNode.querySelector('img'); try { const img = await DrawIO.upload(pngData, options.pageId); - pageEditor.dom.setAttrib(imgElem, 'src', img.url); - pageEditor.dom.setAttrib(currentNode, 'drawio-diagram', img.id); + pageEditor.undoManager.transact(function () { + pageEditor.dom.setAttrib(imgElem, 'src', img.url); + pageEditor.dom.setAttrib(currentNode, 'drawio-diagram', img.id); + }); } catch (err) { handleUploadError(err); } @@ -66,8 +70,10 @@ async function updateContent(pngData) { DrawIO.close(); try { const img = await DrawIO.upload(pngData, options.pageId); - pageEditor.dom.setAttrib(id, 'src', img.url); - pageEditor.dom.get(id).parentNode.setAttribute('drawio-diagram', img.id); + pageEditor.undoManager.transact(function () { + pageEditor.dom.setAttrib(id, 'src', img.url); + pageEditor.dom.get(id).parentNode.setAttribute('drawio-diagram', img.id); + }); } catch (err) { pageEditor.dom.remove(id); handleUploadError(err); From fbef0d06f2d61030183d5b85a49620f4d23717b1 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Mon, 5 Sep 2022 15:52:12 +0100 Subject: [PATCH 36/45] Added permission visiblity control to image-delete button Includes test to cover. For #3697 --- .../Controllers/Images/ImageController.php | 9 +++---- .../pages/parts/image-manager-form.blade.php | 4 ++- tests/Uploads/ImageTest.php | 26 +++++++++++++++++++ 3 files changed, 32 insertions(+), 7 deletions(-) diff --git a/app/Http/Controllers/Images/ImageController.php b/app/Http/Controllers/Images/ImageController.php index b5bc840a1..4b0ba8b45 100644 --- a/app/Http/Controllers/Images/ImageController.php +++ b/app/Http/Controllers/Images/ImageController.php @@ -14,12 +14,9 @@ use Illuminate\Validation\ValidationException; class ImageController extends Controller { - protected $imageRepo; - protected $imageService; - - /** - * ImageController constructor. - */ + protected ImageRepo $imageRepo; + protected ImageService $imageService; + public function __construct(ImageRepo $imageRepo, ImageService $imageService) { $this->imageRepo = $imageRepo; diff --git a/resources/views/pages/parts/image-manager-form.blade.php b/resources/views/pages/parts/image-manager-form.blade.php index 81041fcac..aa21e31bb 100644 --- a/resources/views/pages/parts/image-manager-form.blade.php +++ b/resources/views/pages/parts/image-manager-form.blade.php @@ -20,10 +20,12 @@
- + @endif
\ No newline at end of file diff --git a/tests/Permissions/RolesTest.php b/tests/Permissions/RolesTest.php index 3604a3cac..b992bfecc 100644 --- a/tests/Permissions/RolesTest.php +++ b/tests/Permissions/RolesTest.php @@ -163,6 +163,14 @@ class RolesTest extends TestCase $this->assertEquals($this->user->id, $roleA->users()->first()->id); } + public function test_image_view_notice_shown_on_role_form() + { + /** @var Role $role */ + $role = Role::query()->first(); + $this->asAdmin()->get("/settings/roles/{$role->id}") + ->assertSee('Actual access of uploaded image files will be dependant upon system image storage option'); + } + public function test_copy_role_button_shown() { /** @var Role $role */ From 623ccd4cfa5c9a283c5ac52ac89a8685f80d1628 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Tue, 6 Sep 2022 17:41:32 +0100 Subject: [PATCH 41/45] Removed old thai files, added romanian as lang option Also applied styleci changes --- app/Config/app.php | 2 +- app/Entities/Tools/PageContent.php | 2 +- .../Controllers/Images/ImageController.php | 2 +- app/Util/LanguageManager.php | 1 + resources/lang/en/settings.php | 1 + resources/lang/th/activities.php | 48 --- resources/lang/th/auth.php | 75 ----- resources/lang/th/common.php | 80 ----- resources/lang/th/components.php | 34 -- resources/lang/th/entities.php | 316 ------------------ resources/lang/th/errors.php | 102 ------ resources/lang/th/pagination.php | 12 - resources/lang/th/passwords.php | 15 - resources/lang/th/settings.php | 229 ------------- resources/lang/th/validation.php | 113 ------- tests/Auth/OidcTest.php | 4 +- tests/ThemeTest.php | 1 + 17 files changed, 8 insertions(+), 1029 deletions(-) delete mode 100644 resources/lang/th/activities.php delete mode 100644 resources/lang/th/auth.php delete mode 100644 resources/lang/th/common.php delete mode 100644 resources/lang/th/components.php delete mode 100644 resources/lang/th/entities.php delete mode 100644 resources/lang/th/errors.php delete mode 100644 resources/lang/th/pagination.php delete mode 100644 resources/lang/th/passwords.php delete mode 100644 resources/lang/th/settings.php delete mode 100644 resources/lang/th/validation.php diff --git a/app/Config/app.php b/app/Config/app.php index ad0b1db0d..738aacdbc 100644 --- a/app/Config/app.php +++ b/app/Config/app.php @@ -75,7 +75,7 @@ return [ 'locale' => env('APP_LANG', 'en'), // Locales available - 'locales' => ['en', 'ar', 'bg', 'bs', 'ca', 'cs', 'cy', 'da', 'de', 'de_informal', 'es', 'es_AR', 'et', 'eu', 'fa', 'fr', 'he', 'hr', 'hu', 'id', 'it', 'ja', 'ko', 'lt', 'lv', 'nl', 'nb', 'pt', 'pt_BR', 'sk', 'sl', 'sv', 'pl', 'ru', 'th', 'tr', 'uk', 'uz', 'vi', 'zh_CN', 'zh_TW'], + 'locales' => ['en', 'ar', 'bg', 'bs', 'ca', 'cs', 'cy', 'da', 'de', 'de_informal', 'es', 'es_AR', 'et', 'eu', 'fa', 'fr', 'he', 'hr', 'hu', 'id', 'it', 'ja', 'ko', 'lt', 'lv', 'nl', 'nb', 'pt', 'pt_BR', 'sk', 'sl', 'sv', 'pl', 'ro', 'ru', 'tr', 'uk', 'uz', 'vi', 'zh_CN', 'zh_TW'], // Application Fallback Locale 'fallback_locale' => 'en', diff --git a/app/Entities/Tools/PageContent.php b/app/Entities/Tools/PageContent.php index 17cd4a0ad..9aa2e8d35 100644 --- a/app/Entities/Tools/PageContent.php +++ b/app/Entities/Tools/PageContent.php @@ -382,7 +382,7 @@ class PageContent if ($matchedPage && count($splitInclude) === 1) { // If we only have page id, just insert all page html and continue. $replacement = $matchedPage->html; - } else if ($matchedPage && count($splitInclude) > 1) { + } elseif ($matchedPage && count($splitInclude) > 1) { // Otherwise, if our include tag defines a section, load that specific content $innerContent = $this->fetchSectionOfPage($matchedPage, $splitInclude[1]); $replacement = trim($innerContent); diff --git a/app/Http/Controllers/Images/ImageController.php b/app/Http/Controllers/Images/ImageController.php index 4b0ba8b45..cd6b2d406 100644 --- a/app/Http/Controllers/Images/ImageController.php +++ b/app/Http/Controllers/Images/ImageController.php @@ -16,7 +16,7 @@ class ImageController extends Controller { protected ImageRepo $imageRepo; protected ImageService $imageService; - + public function __construct(ImageRepo $imageRepo, ImageService $imageService) { $this->imageRepo = $imageRepo; diff --git a/app/Util/LanguageManager.php b/app/Util/LanguageManager.php index 33ec0e3a9..fcc56b07e 100644 --- a/app/Util/LanguageManager.php +++ b/app/Util/LanguageManager.php @@ -48,6 +48,7 @@ class LanguageManager 'pl' => ['iso' => 'pl_PL', 'windows' => 'Polish'], 'pt' => ['iso' => 'pt_PT', 'windows' => 'Portuguese'], 'pt_BR' => ['iso' => 'pt_BR', 'windows' => 'Portuguese'], + 'ro' => ['iso' => 'ro_RO', 'windows' => 'Romanian'], 'ru' => ['iso' => 'ru', 'windows' => 'Russian'], 'sk' => ['iso' => 'sk_SK', 'windows' => 'Slovak'], 'sl' => ['iso' => 'sl_SI', 'windows' => 'Slovenian'], diff --git a/resources/lang/en/settings.php b/resources/lang/en/settings.php index ea4228488..e2a22ee37 100755 --- a/resources/lang/en/settings.php +++ b/resources/lang/en/settings.php @@ -300,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/th/activities.php b/resources/lang/th/activities.php deleted file mode 100644 index 4cac54b2a..000000000 --- a/resources/lang/th/activities.php +++ /dev/null @@ -1,48 +0,0 @@ - 'created page', - 'page_create_notification' => 'Page Successfully Created', - 'page_update' => 'updated page', - 'page_update_notification' => 'Page Successfully Updated', - 'page_delete' => 'deleted page', - 'page_delete_notification' => 'Page Successfully Deleted', - 'page_restore' => 'restored page', - 'page_restore_notification' => 'Page Successfully Restored', - 'page_move' => 'moved page', - - // Chapters - 'chapter_create' => 'created chapter', - 'chapter_create_notification' => 'Chapter Successfully Created', - 'chapter_update' => 'updated chapter', - 'chapter_update_notification' => 'Chapter Successfully Updated', - 'chapter_delete' => 'deleted chapter', - 'chapter_delete_notification' => 'Chapter Successfully Deleted', - 'chapter_move' => 'moved chapter', - - // Books - 'book_create' => 'created book', - 'book_create_notification' => 'Book Successfully Created', - 'book_update' => 'updated book', - 'book_update_notification' => 'Book Successfully Updated', - 'book_delete' => 'deleted book', - 'book_delete_notification' => 'Book Successfully Deleted', - 'book_sort' => 'sorted book', - 'book_sort_notification' => 'Book Successfully Re-sorted', - - // Bookshelves - 'bookshelf_create' => 'created Bookshelf', - 'bookshelf_create_notification' => 'Bookshelf Successfully Created', - 'bookshelf_update' => 'updated bookshelf', - 'bookshelf_update_notification' => 'Bookshelf Successfully Updated', - 'bookshelf_delete' => 'deleted bookshelf', - 'bookshelf_delete_notification' => 'Bookshelf Successfully Deleted', - - // Other - 'commented_on' => 'commented on', -]; diff --git a/resources/lang/th/auth.php b/resources/lang/th/auth.php deleted file mode 100644 index 8ff408021..000000000 --- a/resources/lang/th/auth.php +++ /dev/null @@ -1,75 +0,0 @@ - 'These credentials do not match our records.', - 'throttle' => 'Too many login attempts. Please try again in :seconds seconds.', - - // Login & Register - 'sign_up' => 'Sign up', - 'log_in' => 'Log in', - 'log_in_with' => 'Login with :socialDriver', - 'sign_up_with' => 'Sign up with :socialDriver', - 'logout' => 'Logout', - - 'name' => 'Name', - 'username' => 'Username', - 'email' => 'Email', - 'password' => 'Password', - 'password_confirm' => 'Confirm Password', - 'password_hint' => 'Must be over 7 characters', - 'forgot_password' => 'Forgot Password?', - 'remember_me' => 'Remember Me', - 'ldap_email_hint' => 'Please enter an email to use for this account.', - 'create_account' => 'Create Account', - 'already_have_account' => 'Already have an account?', - 'dont_have_account' => 'Don\'t have an account?', - 'social_login' => 'Social Login', - 'social_registration' => 'Social Registration', - 'social_registration_text' => 'Register and sign in using another service.', - - 'register_thanks' => 'Thanks for registering!', - 'register_confirm' => 'Please check your email and click the confirmation button to access :appName.', - 'registrations_disabled' => 'Registrations are currently disabled', - 'registration_email_domain_invalid' => 'That email domain does not have access to this application', - 'register_success' => 'Thanks for signing up! You are now registered and signed in.', - - // Password Reset - '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_button' => 'Send Reset Link', - 'reset_password_sent' => 'A password reset link will be sent to :email if that email address is found in the system.', - 'reset_password_success' => 'Your password has been successfully reset.', - '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_not_requested' => 'If you did not request a password reset, no further action is required.', - - // Email Confirmation - 'email_confirm_subject' => 'Confirm your email on :appName', - 'email_confirm_greeting' => 'Thanks for joining :appName!', - 'email_confirm_text' => 'Please confirm your email address by clicking the button below:', - 'email_confirm_action' => 'Confirm Email', - 'email_confirm_send_error' => 'Email confirmation required but the system could not send the email. Contact the admin to ensure email is set up correctly.', - 'email_confirm_success' => 'Your email has been confirmed!', - 'email_confirm_resent' => 'Confirmation email resent, Please check your inbox.', - - 'email_not_confirmed' => 'Email Address Not Confirmed', - 'email_not_confirmed_text' => 'Your email address has not yet been confirmed.', - 'email_not_confirmed_click_link' => 'Please click the link in the email that was sent shortly after you registered.', - 'email_not_confirmed_resend' => 'If you cannot find the email you can re-send the confirmation email by submitting the form below.', - 'email_not_confirmed_resend_button' => 'Resend Confirmation Email', - - // User Invite - 'user_invite_email_subject' => 'You have been invited to join :appName!', - 'user_invite_email_greeting' => 'An account has been created for you on :appName.', - 'user_invite_email_text' => 'Click the button below to set an account password and gain access:', - 'user_invite_email_action' => 'Set Account Password', - 'user_invite_page_welcome' => 'Welcome to :appName!', - 'user_invite_page_text' => 'To finalise your account and gain access you need to set a password which will be used to log-in to :appName on future visits.', - 'user_invite_page_confirm_button' => 'Confirm Password', - 'user_invite_success' => 'Password set, you now have access to :appName!', -]; diff --git a/resources/lang/th/common.php b/resources/lang/th/common.php deleted file mode 100644 index e3bec6837..000000000 --- a/resources/lang/th/common.php +++ /dev/null @@ -1,80 +0,0 @@ - 'Cancel', - 'confirm' => 'Confirm', - 'back' => 'Back', - 'save' => 'Save', - 'continue' => 'Continue', - 'select' => 'Select', - 'toggle_all' => 'Toggle All', - 'more' => 'More', - - // Form Labels - 'name' => 'Name', - 'description' => 'Description', - 'role' => 'Role', - 'cover_image' => 'Cover image', - 'cover_image_description' => 'This image should be approx 440x250px.', - - // Actions - 'actions' => 'Actions', - 'view' => 'View', - 'view_all' => 'View All', - 'create' => 'Create', - 'update' => 'Update', - 'edit' => 'Edit', - 'sort' => 'Sort', - 'move' => 'Move', - 'copy' => 'Copy', - 'reply' => 'Reply', - 'delete' => 'Delete', - 'delete_confirm' => 'Confirm Deletion', - 'search' => 'Search', - 'search_clear' => 'Clear Search', - 'reset' => 'Reset', - 'remove' => 'Remove', - 'add' => 'Add', - 'fullscreen' => 'Fullscreen', - - // Sort Options - 'sort_options' => 'Sort Options', - 'sort_direction_toggle' => 'Sort Direction Toggle', - 'sort_ascending' => 'Sort Ascending', - 'sort_descending' => 'Sort Descending', - 'sort_name' => 'Name', - 'sort_created_at' => 'Created Date', - 'sort_updated_at' => 'Updated Date', - - // Misc - 'deleted_user' => 'Deleted User', - 'no_activity' => 'No activity to show', - 'no_items' => 'No items available', - 'back_to_top' => 'Back to top', - 'toggle_details' => 'Toggle Details', - 'toggle_thumbnails' => 'Toggle Thumbnails', - 'details' => 'Details', - 'grid_view' => 'Grid View', - 'list_view' => 'List View', - 'default' => 'Default', - 'breadcrumb' => 'Breadcrumb', - - // Header - 'profile_menu' => 'Profile Menu', - 'view_profile' => 'View Profile', - 'edit_profile' => 'Edit Profile', - 'dark_mode' => 'Dark Mode', - 'light_mode' => 'Light Mode', - - // Layout tabs - 'tab_info' => 'Info', - 'tab_content' => 'Content', - - // Email Content - 'email_action_help' => 'If you’re having trouble clicking the ":actionText" button, copy and paste the URL below into your web browser:', - 'email_rights' => 'All rights reserved', -]; diff --git a/resources/lang/th/components.php b/resources/lang/th/components.php deleted file mode 100644 index 48a0a32fa..000000000 --- a/resources/lang/th/components.php +++ /dev/null @@ -1,34 +0,0 @@ - 'Image Select', - 'image_all' => 'All', - 'image_all_title' => 'View all images', - 'image_book_title' => 'View images uploaded to this book', - 'image_page_title' => 'View images uploaded to this page', - 'image_search_hint' => 'Search by image name', - 'image_uploaded' => 'Uploaded :uploadedDate', - 'image_load_more' => 'Load More', - 'image_image_name' => 'Image Name', - 'image_delete_used' => 'This image is used in the pages below.', - 'image_delete_confirm_text' => 'Are you sure you want to delete this image?', - 'image_select_image' => 'Select Image', - 'image_dropzone' => 'Drop images or click here to upload', - 'images_deleted' => 'Images Deleted', - 'image_preview' => 'Image Preview', - 'image_upload_success' => 'Image uploaded successfully', - 'image_update_success' => 'Image details successfully updated', - 'image_delete_success' => 'Image successfully deleted', - 'image_upload_remove' => 'Remove', - - // Code Editor - 'code_editor' => 'Edit Code', - 'code_language' => 'Code Language', - 'code_content' => 'Code Content', - 'code_session_history' => 'Session History', - 'code_save' => 'Save Code', -]; diff --git a/resources/lang/th/entities.php b/resources/lang/th/entities.php deleted file mode 100644 index 67c451319..000000000 --- a/resources/lang/th/entities.php +++ /dev/null @@ -1,316 +0,0 @@ - 'Recently Created', - 'recently_created_pages' => 'Recently Created Pages', - 'recently_updated_pages' => 'Recently Updated Pages', - 'recently_created_chapters' => 'Recently Created Chapters', - 'recently_created_books' => 'Recently Created Books', - 'recently_created_shelves' => 'Recently Created Shelves', - 'recently_update' => 'Recently Updated', - 'recently_viewed' => 'Recently Viewed', - 'recent_activity' => 'Recent Activity', - 'create_now' => 'Create one now', - 'revisions' => 'Revisions', - 'meta_revision' => 'Revision #:revisionCount', - 'meta_created' => 'Created :timeLength', - 'meta_created_name' => 'Created :timeLength by :user', - 'meta_updated' => 'Updated :timeLength', - 'meta_updated_name' => 'Updated :timeLength by :user', - 'entity_select' => 'Entity Select', - 'images' => 'Images', - 'my_recent_drafts' => 'My Recent Drafts', - 'my_recently_viewed' => 'My Recently Viewed', - 'no_pages_viewed' => 'You have not viewed any pages', - 'no_pages_recently_created' => 'No pages have been recently created', - 'no_pages_recently_updated' => 'No pages have been recently updated', - 'export' => 'Export', - 'export_html' => 'Contained Web File', - 'export_pdf' => 'PDF File', - 'export_text' => 'Plain Text File', - - // Permissions and restrictions - 'permissions' => 'Permissions', - 'permissions_intro' => 'Once enabled, These permissions will take priority over any set role permissions.', - 'permissions_enable' => 'Enable Custom Permissions', - 'permissions_save' => 'Save Permissions', - - // Search - 'search_results' => 'Search Results', - 'search_total_results_found' => ':count result found|:count total results found', - 'search_clear' => 'Clear Search', - 'search_no_pages' => 'No pages matched this search', - 'search_for_term' => 'Search for :term', - 'search_more' => 'More Results', - 'search_advanced' => 'Advanced Search', - 'search_terms' => 'Search Terms', - 'search_content_type' => 'Content Type', - 'search_exact_matches' => 'Exact Matches', - 'search_tags' => 'Tag Searches', - 'search_options' => 'Options', - 'search_viewed_by_me' => 'Viewed by me', - 'search_not_viewed_by_me' => 'Not viewed by me', - 'search_permissions_set' => 'Permissions set', - 'search_created_by_me' => 'Created by me', - 'search_updated_by_me' => 'Updated by me', - 'search_date_options' => 'Date Options', - 'search_updated_before' => 'Updated before', - 'search_updated_after' => 'Updated after', - 'search_created_before' => 'Created before', - 'search_created_after' => 'Created after', - 'search_set_date' => 'Set Date', - 'search_update' => 'Update Search', - - // Shelves - 'shelf' => 'Shelf', - 'shelves' => 'Shelves', - 'x_shelves' => ':count Shelf|:count Shelves', - 'shelves_long' => 'Bookshelves', - 'shelves_empty' => 'No shelves have been created', - 'shelves_create' => 'Create New Shelf', - 'shelves_popular' => 'Popular Shelves', - 'shelves_new' => 'New Shelves', - 'shelves_new_action' => 'New Shelf', - 'shelves_popular_empty' => 'The most popular shelves will appear here.', - 'shelves_new_empty' => 'The most recently created shelves will appear here.', - 'shelves_save' => 'Save Shelf', - 'shelves_books' => 'Books on this shelf', - 'shelves_add_books' => 'Add books to this shelf', - 'shelves_drag_books' => 'Drag books here to add them to this shelf', - 'shelves_empty_contents' => 'This shelf has no books assigned to it', - 'shelves_edit_and_assign' => 'Edit shelf to assign books', - 'shelves_edit_named' => 'Edit Bookshelf :name', - 'shelves_edit' => 'Edit Bookshelf', - 'shelves_delete' => 'Delete Bookshelf', - 'shelves_delete_named' => 'Delete Bookshelf :name', - 'shelves_delete_explain' => "This will delete the bookshelf with the name ':name'. Contained books will not be deleted.", - 'shelves_delete_confirmation' => 'Are you sure you want to delete this bookshelf?', - 'shelves_permissions' => 'Bookshelf Permissions', - 'shelves_permissions_updated' => 'Bookshelf Permissions Updated', - 'shelves_permissions_active' => 'Bookshelf Permissions Active', - 'shelves_copy_permissions_to_books' => 'Copy Permissions to Books', - 'shelves_copy_permissions' => 'Copy Permissions', - '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', - - // Books - 'book' => 'Book', - 'books' => 'Books', - 'x_books' => ':count Book|:count Books', - 'books_empty' => 'No books have been created', - 'books_popular' => 'Popular Books', - 'books_recent' => 'Recent Books', - 'books_new' => 'New Books', - 'books_new_action' => 'New Book', - 'books_popular_empty' => 'The most popular books will appear here.', - 'books_new_empty' => 'The most recently created books will appear here.', - 'books_create' => 'Create New Book', - 'books_delete' => 'Delete Book', - 'books_delete_named' => 'Delete Book :bookName', - 'books_delete_explain' => 'This will delete the book with the name \':bookName\'. All pages and chapters will be removed.', - 'books_delete_confirmation' => 'Are you sure you want to delete this book?', - 'books_edit' => 'Edit Book', - 'books_edit_named' => 'Edit Book :bookName', - 'books_form_book_name' => 'Book Name', - 'books_save' => 'Save Book', - 'books_permissions' => 'Book Permissions', - 'books_permissions_updated' => 'Book Permissions Updated', - 'books_empty_contents' => 'No pages or chapters have been created for this book.', - 'books_empty_create_page' => 'Create a new page', - 'books_empty_sort_current_book' => 'Sort the current book', - 'books_empty_add_chapter' => 'Add a chapter', - 'books_permissions_active' => 'Book Permissions Active', - 'books_search_this' => 'Search this book', - 'books_navigation' => 'Book Navigation', - 'books_sort' => 'Sort Book Contents', - 'books_sort_named' => 'Sort Book :bookName', - 'books_sort_name' => 'Sort by Name', - 'books_sort_created' => 'Sort by Created Date', - 'books_sort_updated' => 'Sort by Updated Date', - 'books_sort_chapters_first' => 'Chapters First', - 'books_sort_chapters_last' => 'Chapters Last', - 'books_sort_show_other' => 'Show Other Books', - 'books_sort_save' => 'Save New Order', - - // Chapters - 'chapter' => 'Chapter', - 'chapters' => 'Chapters', - 'x_chapters' => ':count Chapter|:count Chapters', - 'chapters_popular' => 'Popular Chapters', - 'chapters_new' => 'New Chapter', - 'chapters_create' => 'Create New Chapter', - 'chapters_delete' => 'Delete Chapter', - 'chapters_delete_named' => 'Delete Chapter :chapterName', - 'chapters_delete_explain' => 'This will delete the chapter with the name \':chapterName\'. All pages will be removed and added directly to the parent book.', - 'chapters_delete_confirm' => 'Are you sure you want to delete this chapter?', - 'chapters_edit' => 'Edit Chapter', - 'chapters_edit_named' => 'Edit Chapter :chapterName', - 'chapters_save' => 'Save Chapter', - 'chapters_move' => 'Move Chapter', - 'chapters_move_named' => 'Move Chapter :chapterName', - 'chapter_move_success' => 'Chapter moved to :bookName', - 'chapters_permissions' => 'Chapter Permissions', - 'chapters_empty' => 'No pages are currently in this chapter.', - 'chapters_permissions_active' => 'Chapter Permissions Active', - 'chapters_permissions_success' => 'Chapter Permissions Updated', - 'chapters_search_this' => 'Search this chapter', - - // Pages - 'page' => 'Page', - 'pages' => 'Pages', - 'x_pages' => ':count Page|:count Pages', - 'pages_popular' => 'Popular Pages', - 'pages_new' => 'New Page', - 'pages_attachments' => 'Attachments', - 'pages_navigation' => 'Page Navigation', - 'pages_delete' => 'Delete Page', - 'pages_delete_named' => 'Delete Page :pageName', - 'pages_delete_draft_named' => 'Delete Draft Page :pageName', - 'pages_delete_draft' => 'Delete Draft Page', - 'pages_delete_success' => 'Page deleted', - 'pages_delete_draft_success' => 'Draft page deleted', - 'pages_delete_confirm' => 'Are you sure you want to delete this page?', - 'pages_delete_draft_confirm' => 'Are you sure you want to delete this draft page?', - 'pages_editing_named' => 'Editing Page :pageName', - 'pages_edit_draft_options' => 'Draft Options', - 'pages_edit_save_draft' => 'Save Draft', - 'pages_edit_draft' => 'Edit Page Draft', - 'pages_editing_draft' => 'Editing Draft', - 'pages_editing_page' => 'Editing Page', - 'pages_edit_draft_save_at' => 'Draft saved at ', - 'pages_edit_delete_draft' => 'Delete Draft', - 'pages_edit_discard_draft' => 'Discard Draft', - 'pages_edit_set_changelog' => 'Set Changelog', - 'pages_edit_enter_changelog_desc' => 'Enter a brief description of the changes you\'ve made', - 'pages_edit_enter_changelog' => 'Enter Changelog', - 'pages_save' => 'Save Page', - 'pages_title' => 'Page Title', - 'pages_name' => 'Page Name', - 'pages_md_editor' => 'Editor', - 'pages_md_preview' => 'Preview', - 'pages_md_insert_image' => 'Insert Image', - 'pages_md_insert_link' => 'Insert Entity Link', - 'pages_md_insert_drawing' => 'Insert Drawing', - 'pages_not_in_chapter' => 'Page is not in a chapter', - 'pages_move' => 'Move Page', - 'pages_move_success' => 'Page moved to ":parentName"', - 'pages_copy' => 'Copy Page', - 'pages_copy_desination' => 'Copy Destination', - 'pages_copy_success' => 'Page successfully copied', - 'pages_permissions' => 'Page Permissions', - 'pages_permissions_success' => 'Page permissions updated', - 'pages_revision' => 'Revision', - 'pages_revisions' => 'Page Revisions', - 'pages_revisions_named' => 'Page Revisions for :pageName', - 'pages_revision_named' => 'Page Revision for :pageName', - 'pages_revisions_created_by' => 'Created By', - 'pages_revisions_date' => 'Revision Date', - 'pages_revisions_number' => '#', - 'pages_revisions_numbered' => 'Revision #:id', - 'pages_revisions_numbered_changes' => 'Revision #:id Changes', - 'pages_revisions_changelog' => 'Changelog', - 'pages_revisions_changes' => 'Changes', - 'pages_revisions_current' => 'Current Version', - 'pages_revisions_preview' => 'Preview', - 'pages_revisions_restore' => 'Restore', - 'pages_revisions_none' => 'This page has no revisions', - 'pages_copy_link' => 'Copy Link', - 'pages_edit_content_link' => 'Edit Content', - 'pages_permissions_active' => 'Page Permissions Active', - 'pages_initial_revision' => 'Initial publish', - 'pages_initial_name' => 'New Page', - 'pages_editing_draft_notification' => 'You are currently editing a draft that was last saved :timeDiff.', - 'pages_draft_edited_notification' => 'This page has been updated by since that time. It is recommended that you discard this draft.', - 'pages_draft_edit_active' => [ - 'start_a' => ':count users have started editing this page', - 'start_b' => ':userName has started editing this page', - 'time_a' => 'since the page was last updated', - 'time_b' => 'in the last :minCount minutes', - 'message' => ':start :time. Take care not to overwrite each other\'s updates!', - ], - 'pages_draft_discarded' => 'Draft discarded, The editor has been updated with the current page content', - 'pages_specific' => 'Specific Page', - 'pages_is_template' => 'Page Template', - - // Editor Sidebar - 'page_tags' => 'Page Tags', - 'chapter_tags' => 'Chapter Tags', - 'book_tags' => 'Book Tags', - 'shelf_tags' => 'Shelf Tags', - 'tag' => 'Tag', - 'tags' => 'Tags', - 'tag_name' => 'Tag Name', - 'tag_value' => 'Tag Value (Optional)', - 'tags_explain' => "Add some tags to better categorise your content. \n You can assign a value to a tag for more in-depth organisation.", - 'tags_add' => 'Add another tag', - 'tags_remove' => 'Remove this tag', - 'attachments' => 'Attachments', - 'attachments_explain' => 'Upload some files or attach some links to display on your page. These are visible in the page sidebar.', - 'attachments_explain_instant_save' => 'Changes here are saved instantly.', - 'attachments_items' => 'Attached Items', - 'attachments_upload' => 'Upload File', - 'attachments_link' => 'Attach Link', - 'attachments_set_link' => 'Set Link', - 'attachments_delete' => 'Are you sure you want to delete this attachment?', - 'attachments_dropzone' => 'Drop files or click here to attach a file', - 'attachments_no_files' => 'No files have been uploaded', - 'attachments_explain_link' => 'You can attach a link if you\'d prefer not to upload a file. This can be a link to another page or a link to a file in the cloud.', - 'attachments_link_name' => 'Link Name', - 'attachment_link' => 'Attachment link', - 'attachments_link_url' => 'Link to file', - 'attachments_link_url_hint' => 'Url of site or file', - 'attach' => 'Attach', - 'attachments_insert_link' => 'Add Attachment Link to Page', - 'attachments_edit_file' => 'Edit File', - 'attachments_edit_file_name' => 'File Name', - 'attachments_edit_drop_upload' => 'Drop files or click here to upload and overwrite', - 'attachments_order_updated' => 'Attachment order updated', - 'attachments_updated_success' => 'Attachment details updated', - 'attachments_deleted' => 'Attachment deleted', - 'attachments_file_uploaded' => 'File successfully uploaded', - 'attachments_file_updated' => 'File successfully updated', - 'attachments_link_attached' => 'Link successfully attached to page', - 'templates' => 'Templates', - 'templates_set_as_template' => 'Page is a template', - 'templates_explain_set_as_template' => 'You can set this page as a template so its contents be utilized when creating other pages. Other users will be able to use this template if they have view permissions for this page.', - 'templates_replace_content' => 'Replace page content', - 'templates_append_content' => 'Append to page content', - 'templates_prepend_content' => 'Prepend to page content', - - // Profile View - 'profile_user_for_x' => 'User for :time', - 'profile_created_content' => 'Created Content', - 'profile_not_created_pages' => ':userName has not created any pages', - 'profile_not_created_chapters' => ':userName has not created any chapters', - 'profile_not_created_books' => ':userName has not created any books', - 'profile_not_created_shelves' => ':userName has not created any shelves', - - // Comments - 'comment' => 'Comment', - 'comments' => 'Comments', - 'comment_add' => 'Add Comment', - 'comment_placeholder' => 'Leave a comment here', - 'comment_count' => '{0} No Comments|{1} 1 Comment|[2,*] :count Comments', - 'comment_save' => 'Save Comment', - 'comment_saving' => 'Saving comment...', - 'comment_deleting' => 'Deleting comment...', - 'comment_new' => 'New Comment', - 'comment_created' => 'commented :createDiff', - 'comment_updated' => 'Updated :updateDiff by :username', - 'comment_deleted_success' => 'Comment deleted', - 'comment_created_success' => 'Comment added', - 'comment_updated_success' => 'Comment updated', - 'comment_delete_confirm' => 'Are you sure you want to delete this comment?', - 'comment_in_reply_to' => 'In reply to :commentId', - - // Revision - 'revision_delete_confirm' => 'Are you sure you want to delete this revision?', - 'revision_restore_confirm' => 'Are you sure you want to restore this revision? The current page contents will be replaced.', - 'revision_delete_success' => 'Revision deleted', - 'revision_cannot_delete_latest' => 'Cannot delete the latest revision.', -]; diff --git a/resources/lang/th/errors.php b/resources/lang/th/errors.php deleted file mode 100644 index 79024e482..000000000 --- a/resources/lang/th/errors.php +++ /dev/null @@ -1,102 +0,0 @@ - 'You do not have permission to access the requested page.', - 'permissionJson' => 'You do not have permission to perform the requested action.', - - // Auth - 'error_user_exists_different_creds' => 'A user with the email :email already exists but with different credentials.', - 'email_already_confirmed' => 'Email has already been confirmed, Try logging in.', - 'email_confirmation_invalid' => 'This confirmation token is not valid or has already been used, Please try registering again.', - 'email_confirmation_expired' => 'The confirmation token has expired, A new confirmation email has been sent.', - 'email_confirmation_awaiting' => 'The email address for the account in use needs to be confirmed', - 'ldap_fail_anonymous' => 'LDAP access failed using anonymous bind', - 'ldap_fail_authed' => 'LDAP access failed using given dn & password details', - 'ldap_extension_not_installed' => 'LDAP PHP extension not installed', - 'ldap_cannot_connect' => 'Cannot connect to ldap server, Initial connection failed', - 'saml_already_logged_in' => 'Already logged in', - 'saml_user_not_registered' => 'The user :name is not registered and automatic registration is disabled', - 'saml_no_email_address' => 'Could not find an email address, for this user, in the data provided by the external authentication system', - 'saml_invalid_response_id' => 'The request from the external authentication system is not recognised by a process started by this application. Navigating back after a login could cause this issue.', - 'saml_fail_authed' => 'Login using :system failed, system did not provide successful authorization', - 'social_no_action_defined' => 'No action defined', - 'social_login_bad_response' => "Error received during :socialAccount login: \n:error", - 'social_account_in_use' => 'This :socialAccount account is already in use, Try logging in via the :socialAccount option.', - 'social_account_email_in_use' => 'The email :email is already in use. If you already have an account you can connect your :socialAccount account from your profile settings.', - 'social_account_existing' => 'This :socialAccount is already attached to your profile.', - 'social_account_already_used_existing' => 'This :socialAccount account is already used by another user.', - 'social_account_not_used' => 'This :socialAccount account is not linked to any users. Please attach it in your profile settings. ', - 'social_account_register_instructions' => 'If you do not yet have an account, You can register an account using the :socialAccount option.', - 'social_driver_not_found' => 'Social driver not found', - 'social_driver_not_configured' => 'Your :socialAccount social settings are not configured correctly.', - 'invite_token_expired' => 'This invitation link has expired. You can instead try to reset your account password.', - - // System - 'path_not_writable' => 'File path :filePath could not be uploaded to. Ensure it is writable to the server.', - 'cannot_get_image_from_url' => 'Cannot get image from :url', - 'cannot_create_thumbs' => 'The server cannot create thumbnails. Please check you have the GD PHP extension installed.', - 'server_upload_limit' => '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_type_error' => 'The image type being uploaded is invalid', - 'file_upload_timeout' => 'The file upload has timed out.', - - // Attachments - 'attachment_not_found' => 'Attachment not found', - - // Pages - 'page_draft_autosave_fail' => 'Failed to save draft. Ensure you have internet connection before saving this page', - 'page_custom_home_deletion' => 'Cannot delete a page while it is set as a homepage', - - // Entities - 'entity_not_found' => 'Entity not found', - 'bookshelf_not_found' => 'Bookshelf not found', - 'book_not_found' => 'Book not found', - 'page_not_found' => 'Page not found', - 'chapter_not_found' => 'Chapter not found', - 'selected_book_not_found' => 'The selected book was not found', - 'selected_book_chapter_not_found' => 'The selected Book or Chapter was not found', - 'guests_cannot_save_drafts' => 'Guests cannot save drafts', - - // Users - 'users_cannot_delete_only_admin' => 'You cannot delete the only admin', - 'users_cannot_delete_guest' => 'You cannot delete the guest user', - - // Roles - '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_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 - 'comment_list' => 'An error occurred while fetching the comments.', - 'cannot_add_comment_to_draft' => 'You cannot add comments to a draft.', - 'comment_add' => 'An error occurred while adding / updating the comment.', - 'comment_delete' => 'An error occurred while deleting the comment.', - 'empty_comment' => 'Cannot add an empty comment.', - - // Error pages - '404_page_not_found' => 'Page Not Found', - 'sorry_page_not_found' => 'Sorry, The page you were looking for could not be found.', - 'sorry_page_not_found_permission_warning' => 'If you expected this page to exist, you might not have permission to view it.', - 'return_home' => 'Return to home', - 'error_occurred' => 'An Error Occurred', - 'app_down' => ':appName is down right now', - 'back_soon' => 'It will be back up soon.', - - // API errors - 'api_no_authorization_found' => 'No authorization token found on the request', - 'api_bad_authorization_format' => 'An authorization token was found on the request but the format appeared incorrect', - 'api_user_token_not_found' => 'No matching API token was found for the provided authorization token', - 'api_incorrect_token_secret' => 'The secret provided for the given used API token is incorrect', - 'api_user_no_api_permission' => 'The owner of the used API token does not have permission to make API calls', - 'api_user_token_expired' => 'The authorization token used has expired', - - // Settings & Maintenance - 'maintenance_test_email_failure' => 'Error thrown when sending a test email:', - -]; diff --git a/resources/lang/th/pagination.php b/resources/lang/th/pagination.php deleted file mode 100644 index 85bd12fc3..000000000 --- a/resources/lang/th/pagination.php +++ /dev/null @@ -1,12 +0,0 @@ - '« Previous', - 'next' => 'Next »', - -]; diff --git a/resources/lang/th/passwords.php b/resources/lang/th/passwords.php deleted file mode 100644 index b408f3c2f..000000000 --- a/resources/lang/th/passwords.php +++ /dev/null @@ -1,15 +0,0 @@ - 'Passwords must be at least eight characters and match the confirmation.', - 'user' => "We can't find a user with that e-mail address.", - 'token' => 'The password reset token is invalid for this email address.', - 'sent' => 'We have e-mailed your password reset link!', - 'reset' => 'Your password has been reset!', - -]; diff --git a/resources/lang/th/settings.php b/resources/lang/th/settings.php deleted file mode 100644 index c2e4ee734..000000000 --- a/resources/lang/th/settings.php +++ /dev/null @@ -1,229 +0,0 @@ - 'Settings', - 'settings_save' => 'Save Settings', - 'settings_save_success' => 'Settings saved', - - // App Settings - 'app_customization' => 'Customization', - 'app_features_security' => 'Features & Security', - 'app_name' => 'Application Name', - 'app_name_desc' => 'This name is shown in the header and in any system-sent emails.', - 'app_name_header' => 'Show name in header', - 'app_public_access' => 'Public Access', - 'app_public_access_desc' => 'Enabling this option will allow visitors, that are not logged-in, to access content in your BookStack instance.', - 'app_public_access_desc_guest' => 'Access for public visitors can be controlled through the "Guest" user.', - 'app_public_access_toggle' => 'Allow public access', - 'app_public_viewing' => 'Allow public viewing?', - 'app_secure_images' => 'Higher Security Image Uploads', - 'app_secure_images_toggle' => 'Enable higher security image uploads', - 'app_secure_images_desc' => 'For performance reasons, all images are public. This option adds a random, hard-to-guess string in front of image urls. Ensure directory indexes are not enabled to prevent easy access.', - 'app_editor' => 'Page Editor', - 'app_editor_desc' => 'Select which editor will be used by all users to edit pages.', - 'app_custom_html' => 'Custom HTML Head Content', - 'app_custom_html_desc' => 'Any content added here will be inserted into the bottom of the section of every page. This is handy for overriding styles or adding analytics code.', - 'app_custom_html_disabled_notice' => 'Custom HTML head content is disabled on this settings page to ensure any breaking changes can be reverted.', - 'app_logo' => 'Application Logo', - 'app_logo_desc' => 'This image should be 43px in height.
Large images will be scaled down.', - 'app_primary_color' => 'Application Primary Color', - 'app_primary_color_desc' => 'Sets the primary color for the application including the banner, buttons, and links.', - 'app_homepage' => 'Application Homepage', - 'app_homepage_desc' => 'Select a view to show on the homepage instead of the default view. Page permissions are ignored for selected pages.', - 'app_homepage_select' => 'Select a page', - 'app_disable_comments' => 'Disable Comments', - 'app_disable_comments_toggle' => 'Disable comments', - 'app_disable_comments_desc' => 'Disables comments across all pages in the application.
Existing comments are not shown.', - - // Color settings - 'content_colors' => 'Content Colors', - 'content_colors_desc' => 'Sets colors for all elements in the page organisation hierarchy. Choosing colors with a similar brightness to the default colors is recommended for readability.', - 'bookshelf_color' => 'Shelf Color', - 'book_color' => 'Book Color', - 'chapter_color' => 'Chapter Color', - 'page_color' => 'Page Color', - 'page_draft_color' => 'Page Draft Color', - - // Registration Settings - 'reg_settings' => 'Registration', - 'reg_enable' => 'Enable Registration', - 'reg_enable_toggle' => 'Enable registration', - 'reg_enable_desc' => 'When registration is enabled user will be able to sign themselves up as an application user. Upon registration they are given a single, default user role.', - 'reg_default_role' => 'Default user role after registration', - 'reg_enable_external_warning' => 'The option above is ignored while external LDAP or SAML authentication is active. User accounts for non-existing members will be auto-created if authentication, against the external system in use, is successful.', - 'reg_email_confirmation' => 'Email Confirmation', - 'reg_email_confirmation_toggle' => 'Require email confirmation', - 'reg_confirm_email_desc' => 'If domain restriction is used then email confirmation will be required and this option will be ignored.', - 'reg_confirm_restrict_domain' => 'Domain Restriction', - '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.
Note that users will be able to change their email addresses after successful registration.', - 'reg_confirm_restrict_domain_placeholder' => 'No restriction set', - - // Maintenance settings - 'maint' => 'Maintenance', - 'maint_image_cleanup' => 'Cleanup Images', - 'maint_image_cleanup_desc' => 'Scans page & revision content to check which images and drawings are currently in use and which images are redundant. Ensure you create a full database and image backup before running this.', - 'maint_image_cleanup_ignore_revisions' => 'Ignore images in revisions', - 'maint_image_cleanup_run' => 'Run Cleanup', - 'maint_image_cleanup_warning' => ':count potentially unused images were found. Are you sure you want to delete these images?', - 'maint_image_cleanup_success' => ':count potentially unused images found and deleted!', - 'maint_image_cleanup_nothing_found' => 'No unused images found, Nothing deleted!', - 'maint_send_test_email' => 'Send a Test Email', - 'maint_send_test_email_desc' => 'This sends a test email to your email address specified in your profile.', - 'maint_send_test_email_run' => 'Send test email', - 'maint_send_test_email_success' => 'Email sent to :address', - 'maint_send_test_email_mail_subject' => 'Test Email', - 'maint_send_test_email_mail_greeting' => 'Email delivery seems to work!', - 'maint_send_test_email_mail_text' => 'Congratulations! As you received this email notification, your email settings seem to be configured properly.', - - // Audit Log - 'audit' => 'Audit Log', - 'audit_desc' => 'This audit log displays a list of activities tracked in the system. This list is unfiltered unlike similar activity lists in the system where permission filters are applied.', - 'audit_event_filter' => 'Event Filter', - 'audit_event_filter_no_filter' => 'No Filter', - 'audit_deleted_item' => 'Deleted Item', - 'audit_deleted_item_name' => 'Name: :name', - 'audit_table_user' => 'User', - 'audit_table_event' => 'Event', - 'audit_table_item' => 'Related Item', - 'audit_table_date' => 'Activity Date', - 'audit_date_from' => 'Date Range From', - 'audit_date_to' => 'Date Range To', - - // Role Settings - 'roles' => 'Roles', - 'role_user_roles' => 'User Roles', - 'role_create' => 'Create New Role', - 'role_create_success' => 'Role successfully created', - 'role_delete' => 'Delete Role', - 'role_delete_confirm' => 'This will delete the role with the name \':roleName\'.', - 'role_delete_users_assigned' => 'This role has :userCount users assigned to it. If you would like to migrate the users from this role select a new role below.', - 'role_delete_no_migration' => "Don't migrate users", - 'role_delete_sure' => 'Are you sure you want to delete this role?', - 'role_delete_success' => 'Role successfully deleted', - 'role_edit' => 'Edit Role', - 'role_details' => 'Role Details', - 'role_name' => 'Role Name', - 'role_desc' => 'Short Description of Role', - 'role_external_auth_id' => 'External Authentication IDs', - 'role_system' => 'System Permissions', - 'role_manage_users' => 'Manage users', - 'role_manage_roles' => 'Manage roles & role permissions', - 'role_manage_entity_permissions' => 'Manage all book, chapter & page permissions', - 'role_manage_own_entity_permissions' => 'Manage permissions on own book, chapter & pages', - 'role_manage_page_templates' => 'Manage page templates', - 'role_access_api' => 'Access system API', - 'role_manage_settings' => 'Manage app settings', - 'role_asset' => 'Asset Permissions', - 'roles_system_warning' => 'Be aware that access to any of the above three permissions can allow a user to alter their own privileges or the privileges of others in the system. Only assign roles with these permissions to trusted users.', - 'role_asset_desc' => 'These permissions control default access to the assets within the system. Permissions on Books, Chapters and Pages will override these permissions.', - 'role_asset_admins' => 'Admins are automatically given access to all content but these options may show or hide UI options.', - 'role_all' => 'All', - 'role_own' => 'Own', - 'role_controlled_by_asset' => 'Controlled by the asset they are uploaded to', - 'role_save' => 'Save Role', - 'role_update_success' => 'Role successfully updated', - 'role_users' => 'Users in this role', - 'role_users_none' => 'No users are currently assigned to this role', - - // Users - 'users' => 'Users', - 'user_profile' => 'User Profile', - 'users_add_new' => 'Add New User', - 'users_search' => 'Search Users', - 'users_details' => 'User Details', - 'users_details_desc' => 'Set a display name and an email address for this user. The email address will be used for logging into the application.', - 'users_details_desc_no_email' => 'Set a display name for this user so others can recognise them.', - 'users_role' => 'User Roles', - 'users_role_desc' => 'Select which roles this user will be assigned to. If a user is assigned to multiple roles the permissions from those roles will stack and they will receive all abilities of the assigned roles.', - 'users_password' => 'User Password', - 'users_password_desc' => 'Set a password used to log-in to the application. This must be at least 6 characters long.', - 'users_send_invite_text' => 'You can choose to send this user an invitation email which allows them to set their own password otherwise you can set their password yourself.', - 'users_send_invite_option' => 'Send user invite email', - 'users_external_auth_id' => 'External Authentication ID', - 'users_external_auth_id_desc' => 'This is the ID used to match this user when communicating with your external authentication system.', - 'users_password_warning' => 'Only fill the below if you would like to change your password.', - 'users_system_public' => 'This user represents any guest users that visit your instance. It cannot be used to log in but is assigned automatically.', - 'users_delete' => 'Delete User', - 'users_delete_named' => 'Delete user :userName', - 'users_delete_warning' => 'This will fully delete this user with the name \':userName\' from the system.', - 'users_delete_confirm' => 'Are you sure you want to delete this user?', - 'users_delete_success' => 'Users successfully removed', - 'users_edit' => 'Edit User', - 'users_edit_profile' => 'Edit Profile', - 'users_edit_success' => 'User successfully updated', - 'users_avatar' => 'User Avatar', - 'users_avatar_desc' => 'Select an image to represent this user. This should be approx 256px square.', - 'users_preferred_language' => 'Preferred Language', - 'users_preferred_language_desc' => 'This option will change the language used for the user-interface of the application. This will not affect any user-created content.', - 'users_social_accounts' => 'Social Accounts', - 'users_social_accounts_info' => 'Here you can connect your other accounts for quicker and easier login. Disconnecting an account here does not revoke previously authorized access. Revoke access from your profile settings on the connected social account.', - 'users_social_connect' => 'Connect Account', - 'users_social_disconnect' => 'Disconnect Account', - 'users_social_connected' => ':socialAccount account was successfully attached to your profile.', - 'users_social_disconnected' => ':socialAccount account was successfully disconnected from your profile.', - 'users_api_tokens' => 'API Tokens', - 'users_api_tokens_none' => 'No API tokens have been created for this user', - 'users_api_tokens_create' => 'Create Token', - 'users_api_tokens_expires' => 'Expires', - 'users_api_tokens_docs' => 'API Documentation', - - // API Tokens - 'user_api_token_create' => 'Create API Token', - 'user_api_token_name' => 'Name', - 'user_api_token_name_desc' => 'Give your token a readable name as a future reminder of its intended purpose.', - 'user_api_token_expiry' => 'Expiry Date', - 'user_api_token_expiry_desc' => 'Set a date at which this token expires. After this date, requests made using this token will no longer work. Leaving this field blank will set an expiry 100 years into the future.', - 'user_api_token_create_secret_message' => 'Immediately after creating this token a "Token ID"" & "Token Secret" will be generated and displayed. The secret will only be shown a single time so be sure to copy the value to somewhere safe and secure before proceeding.', - 'user_api_token_create_success' => 'API token successfully created', - 'user_api_token_update_success' => 'API token successfully updated', - 'user_api_token' => 'API Token', - 'user_api_token_id' => 'Token ID', - 'user_api_token_id_desc' => 'This is a non-editable system generated identifier for this token which will need to be provided in API requests.', - 'user_api_token_secret' => 'Token Secret', - 'user_api_token_secret_desc' => 'This is a system generated secret for this token which will need to be provided in API requests. This will only be displayed this one time so copy this value to somewhere safe and secure.', - 'user_api_token_created' => 'Token Created :timeAgo', - 'user_api_token_updated' => 'Token Updated :timeAgo', - 'user_api_token_delete' => 'Delete Token', - 'user_api_token_delete_warning' => 'This will fully delete this API token with the name \':tokenName\' from the system.', - 'user_api_token_delete_confirm' => 'Are you sure you want to delete this API token?', - 'user_api_token_delete_success' => 'API token successfully deleted', - - //! If editing translations files directly please ignore this in all - //! languages apart from en. Content will be auto-copied from en. - //!//////////////////////////////// - 'language_select' => [ - 'en' => 'English', - 'ar' => 'العربية', - 'cs' => 'Česky', - 'da' => 'Dansk', - 'de' => 'Deutsch (Sie)', - 'de_informal' => 'Deutsch (Du)', - 'es' => 'Español', - 'es_AR' => 'Español Argentina', - 'fr' => 'Français', - 'he' => 'עברית', - 'hu' => 'Magyar', - 'it' => 'Italian', - 'ja' => '日本語', - 'ko' => '한국어', - 'nl' => 'Nederlands', - 'pl' => 'Polski', - 'pt_BR' => 'Português do Brasil', - 'ru' => 'Русский', - 'sk' => 'Slovensky', - 'sl' => 'Slovenščina', - 'sv' => 'Svenska', - 'tr' => 'Türkçe', - 'uk' => 'Українська', - 'vi' => 'Tiếng Việt', - 'zh_CN' => '简体中文', - 'zh_TW' => '繁體中文', - ], - //!//////////////////////////////// -]; diff --git a/resources/lang/th/validation.php b/resources/lang/th/validation.php deleted file mode 100644 index f4af9bc6f..000000000 --- a/resources/lang/th/validation.php +++ /dev/null @@ -1,113 +0,0 @@ - 'The :attribute must be accepted.', - 'active_url' => 'The :attribute is not a valid URL.', - 'after' => 'The :attribute must be a date after :date.', - 'alpha' => 'The :attribute may only contain letters.', - 'alpha_dash' => 'The :attribute may only contain letters, numbers, dashes and underscores.', - 'alpha_num' => 'The :attribute may only contain letters and numbers.', - 'array' => 'The :attribute must be an array.', - 'before' => 'The :attribute must be a date before :date.', - 'between' => [ - 'numeric' => 'The :attribute must be between :min and :max.', - 'file' => 'The :attribute must be between :min and :max kilobytes.', - 'string' => 'The :attribute must be between :min and :max characters.', - 'array' => 'The :attribute must have between :min and :max items.', - ], - 'boolean' => 'The :attribute field must be true or false.', - 'confirmed' => 'The :attribute confirmation does not match.', - 'date' => 'The :attribute is not a valid date.', - 'date_format' => 'The :attribute does not match the format :format.', - 'different' => 'The :attribute and :other must be different.', - 'digits' => 'The :attribute must be :digits digits.', - 'digits_between' => 'The :attribute must be between :min and :max digits.', - 'email' => 'The :attribute must be a valid email address.', - 'ends_with' => 'The :attribute must end with one of the following: :values', - 'filled' => 'The :attribute field is required.', - 'gt' => [ - 'numeric' => 'The :attribute must be greater than :value.', - 'file' => 'The :attribute must be greater than :value kilobytes.', - 'string' => 'The :attribute must be greater than :value characters.', - 'array' => 'The :attribute must have more than :value items.', - ], - 'gte' => [ - 'numeric' => 'The :attribute must be greater than or equal :value.', - 'file' => 'The :attribute must be greater than or equal :value kilobytes.', - 'string' => 'The :attribute must be greater than or equal :value characters.', - 'array' => 'The :attribute must have :value items or more.', - ], - 'exists' => 'The selected :attribute is invalid.', - 'image' => 'The :attribute must be an image.', - 'image_extension' => 'The :attribute must have a valid & supported image extension.', - 'in' => 'The selected :attribute is invalid.', - 'integer' => 'The :attribute must be an integer.', - 'ip' => 'The :attribute must be a valid IP address.', - 'ipv4' => 'The :attribute must be a valid IPv4 address.', - 'ipv6' => 'The :attribute must be a valid IPv6 address.', - 'json' => 'The :attribute must be a valid JSON string.', - 'lt' => [ - 'numeric' => 'The :attribute must be less than :value.', - 'file' => 'The :attribute must be less than :value kilobytes.', - 'string' => 'The :attribute must be less than :value characters.', - 'array' => 'The :attribute must have less than :value items.', - ], - 'lte' => [ - 'numeric' => 'The :attribute must be less than or equal :value.', - 'file' => 'The :attribute must be less than or equal :value kilobytes.', - 'string' => 'The :attribute must be less than or equal :value characters.', - 'array' => 'The :attribute must not have more than :value items.', - ], - 'max' => [ - 'numeric' => 'The :attribute may not be greater than :max.', - 'file' => 'The :attribute may not be greater than :max kilobytes.', - 'string' => 'The :attribute may not be greater than :max characters.', - 'array' => 'The :attribute may not have more than :max items.', - ], - 'mimes' => 'The :attribute must be a file of type: :values.', - 'min' => [ - 'numeric' => 'The :attribute must be at least :min.', - 'file' => 'The :attribute must be at least :min kilobytes.', - 'string' => 'The :attribute must be at least :min characters.', - 'array' => 'The :attribute must have at least :min items.', - ], - 'not_in' => 'The selected :attribute is invalid.', - 'not_regex' => 'The :attribute format is invalid.', - 'numeric' => 'The :attribute must be a number.', - 'regex' => 'The :attribute format is invalid.', - 'required' => 'The :attribute field is required.', - 'required_if' => 'The :attribute field is required when :other is :value.', - 'required_with' => 'The :attribute field is required when :values is present.', - 'required_with_all' => 'The :attribute field is required when :values is present.', - 'required_without' => 'The :attribute field is required when :values is not present.', - 'required_without_all' => 'The :attribute field is required when none of :values are present.', - 'same' => 'The :attribute and :other must match.', - 'size' => [ - 'numeric' => 'The :attribute must be :size.', - 'file' => 'The :attribute must be :size kilobytes.', - 'string' => 'The :attribute must be :size characters.', - 'array' => 'The :attribute must contain :size items.', - ], - 'string' => 'The :attribute must be a string.', - 'timezone' => 'The :attribute must be a valid zone.', - 'unique' => 'The :attribute has already been taken.', - 'url' => 'The :attribute format is invalid.', - 'uploaded' => 'The file could not be uploaded. The server may not accept files of this size.', - - // Custom validation lines - 'custom' => [ - 'password-confirm' => [ - 'required_with' => 'Password confirmation required', - ], - ], - - // Custom validation attributes - 'attributes' => [], -]; diff --git a/tests/Auth/OidcTest.php b/tests/Auth/OidcTest.php index 52444e4a2..c015adb86 100644 --- a/tests/Auth/OidcTest.php +++ b/tests/Auth/OidcTest.php @@ -364,7 +364,7 @@ class OidcTest extends TestCase { config()->set([ 'oidc.user_to_groups' => true, - 'oidc.groups_claim' => 'groups', + 'oidc.groups_claim' => 'groups', 'oidc.remove_from_groups' => false, ]); $roleA = Role::factory()->create(['display_name' => 'Wizards']); @@ -390,7 +390,7 @@ class OidcTest extends TestCase { config()->set([ 'oidc.user_to_groups' => true, - 'oidc.groups_claim' => 'my.custom.groups.attr', + 'oidc.groups_claim' => 'my.custom.groups.attr', 'oidc.remove_from_groups' => false, ]); $roleA = Role::factory()->create(['display_name' => 'Wizards']); diff --git a/tests/ThemeTest.php b/tests/ThemeTest.php index 689c27488..e83758a95 100644 --- a/tests/ThemeTest.php +++ b/tests/ThemeTest.php @@ -228,6 +228,7 @@ class ThemeTest extends TestCase $args = []; $callback = function (...$eventArgs) use (&$args) { $args = $eventArgs; + return 'Big & content replace surprise!'; }; From 98aed794cc7272687720c4f4c42a4f540390c0af Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Tue, 6 Sep 2022 21:30:28 +0100 Subject: [PATCH 42/45] Made a range of rtl fixes Mostly around dropdowns and other items that had right/left specific styling. For #3702 --- resources/js/components/dropdown.js | 7 ++----- resources/sass/_components.scss | 5 ++++- resources/sass/_forms.scss | 4 ++++ resources/sass/_lists.scss | 6 +++--- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/resources/js/components/dropdown.js b/resources/js/components/dropdown.js index 473db37d4..781f90860 100644 --- a/resources/js/components/dropdown.js +++ b/resources/js/components/dropdown.js @@ -37,12 +37,8 @@ class DropDown { if (this.moveMenu) { this.body.appendChild(this.menu); this.menu.style.position = 'fixed'; - if (this.direction === 'right') { - this.menu.style.right = `${(menuOriginalRect.right - menuOriginalRect.width)}px`; - } else { - this.menu.style.left = `${menuOriginalRect.left}px`; - } this.menu.style.width = `${menuOriginalRect.width}px`; + this.menu.style.left = `${menuOriginalRect.left}px`; heightOffset = dropUpwards ? (window.innerHeight - menuOriginalRect.top - toggleHeight / 2) : menuOriginalRect.top; } @@ -94,6 +90,7 @@ class DropDown { this.menu.style.position = ''; this.menu.style[this.direction] = ''; this.menu.style.width = ''; + this.menu.style.left = ''; this.container.appendChild(this.menu); } diff --git a/resources/sass/_components.scss b/resources/sass/_components.scss index cbaf17760..c00f57954 100644 --- a/resources/sass/_components.scss +++ b/resources/sass/_components.scss @@ -814,7 +814,7 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group { .template-item-actions { position: absolute; top: 0; - right: 0; + inset-inline-end: 0; width: 50px; height: 100%; display: flex; @@ -828,6 +828,9 @@ body.flexbox-support #entity-selector-wrap .popup-body .form-group { border: 0; border-top: 1px solid #DDD; } + .template-item-actions button svg { + margin: 0; + } .template-item-actions button:first-child { border-top: 0; } diff --git a/resources/sass/_forms.scss b/resources/sass/_forms.scss index e39f5414f..7025aa898 100644 --- a/resources/sass/_forms.scss +++ b/resources/sass/_forms.scss @@ -210,6 +210,10 @@ select { background-size: 12px; background-position: calc(100% - 20px) 70%; background-repeat: no-repeat; + + @include rtl { + background-position: 20px 70%; + } } input[type=date] { diff --git a/resources/sass/_lists.scss b/resources/sass/_lists.scss index 5e251f9c7..8926eb7f9 100644 --- a/resources/sass/_lists.scss +++ b/resources/sass/_lists.scss @@ -197,7 +197,7 @@ .chapter-contents-toggle { display: block; width: 100%; - text-align: left; + text-align: start; padding: $-xxs $-s ($-xxs * 2) $-s; border-radius: 0 3px 3px 0; line-height: 1; @@ -630,7 +630,7 @@ ul.pagination { z-index: 999; top: 0; list-style: none; - right: 0; + inset-inline-end: 0; margin: $-m 0; @include lightDark(background-color, #fff, #333); box-shadow: 0 1px 6px 0 rgba(0, 0, 0, 0.18); @@ -715,7 +715,7 @@ ul.pagination { // being cut by scrollable container. .tri-layout-right .dropdown-menu, .tri-layout-left .dropdown-menu { - right: $-xs; + inset-inline-end: $-xs; } // Books grid view From f7418d06005b3e706b4e941f4c28c5ef082369c4 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Thu, 8 Sep 2022 11:58:55 +0100 Subject: [PATCH 43/45] Updated translator attribution --- .github/translators.txt | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/translators.txt b/.github/translators.txt index 18a9de924..af5d9658c 100644 --- a/.github/translators.txt +++ b/.github/translators.txt @@ -138,7 +138,7 @@ Xiphoseer :: German MerlinSVK (merlinsvk) :: Slovak Kauê Sena (kaue.sena.ks) :: Portuguese, Brazilian MatthieuParis :: French -Douradinho :: Portuguese, Brazilian +Douradinho :: Portuguese, Brazilian; Portuguese Gaku Yaguchi (tama11) :: Japanese johnroyer :: Chinese Traditional jackaaa :: Chinese Traditional @@ -270,3 +270,7 @@ Nanang Setia Budi (sefidananang) :: Indonesian Андрей Павлов (andrei.pavlov) :: Russian Alex Navarro (alex.n.navarro) :: Portuguese, Brazilian Ji-Hyeon Gim (PotatoGim) :: Korean +Mihai Ochian (soulstorm19) :: Romanian +HeartCore :: German Informal; German +simon.pct :: French +okaeiz :: Persian From e4642257a6723adf87b7a4da468db48941b8f039 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Thu, 8 Sep 2022 11:59:57 +0100 Subject: [PATCH 44/45] New Crowdin updates (#3701) --- resources/lang/ar/settings.php | 2 ++ resources/lang/bg/settings.php | 2 ++ resources/lang/bs/settings.php | 2 ++ resources/lang/ca/settings.php | 2 ++ resources/lang/cs/settings.php | 2 ++ resources/lang/cy/settings.php | 2 ++ resources/lang/da/settings.php | 2 ++ resources/lang/de/settings.php | 2 ++ resources/lang/de_informal/settings.php | 2 ++ resources/lang/es/settings.php | 2 ++ resources/lang/es_AR/settings.php | 2 ++ resources/lang/et/settings.php | 2 ++ resources/lang/eu/settings.php | 2 ++ resources/lang/fa/activities.php | 4 ++-- resources/lang/fa/settings.php | 2 ++ resources/lang/fr/settings.php | 2 ++ resources/lang/he/settings.php | 2 ++ resources/lang/hr/settings.php | 2 ++ resources/lang/hu/settings.php | 2 ++ resources/lang/id/settings.php | 2 ++ resources/lang/it/settings.php | 2 ++ resources/lang/ja/settings.php | 2 ++ resources/lang/ko/settings.php | 2 ++ resources/lang/lt/settings.php | 2 ++ resources/lang/lv/settings.php | 2 ++ resources/lang/nb/settings.php | 2 ++ resources/lang/nl/settings.php | 2 ++ resources/lang/pl/settings.php | 2 ++ resources/lang/pt/settings.php | 2 ++ resources/lang/pt_BR/settings.php | 2 ++ resources/lang/ro/settings.php | 2 ++ resources/lang/ru/settings.php | 2 ++ resources/lang/sk/settings.php | 2 ++ resources/lang/sl/settings.php | 2 ++ resources/lang/sv/settings.php | 2 ++ resources/lang/tr/settings.php | 2 ++ resources/lang/uk/settings.php | 2 ++ resources/lang/uz/settings.php | 2 ++ resources/lang/vi/settings.php | 2 ++ resources/lang/zh_CN/settings.php | 2 ++ resources/lang/zh_TW/settings.php | 2 ++ 41 files changed, 82 insertions(+), 2 deletions(-) diff --git a/resources/lang/ar/settings.php b/resources/lang/ar/settings.php index a0477bdac..aaf2be43f 100755 --- a/resources/lang/ar/settings.php +++ b/resources/lang/ar/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'اعلم أن الوصول إلى أي من الأذونات الثلاثة المذكورة أعلاه يمكن أن يسمح للمستخدم بتغيير امتيازاته الخاصة أو امتيازات الآخرين في النظام. قم بتعيين الأدوار مع هذه الأذونات فقط للمستخدمين الموثوق بهم.', 'role_asset_desc' => 'تتحكم هذه الأذونات في الوصول الافتراضي إلى الأصول داخل النظام. ستتجاوز الأذونات الخاصة بالكتب والفصول والصفحات هذه الأذونات.', 'role_asset_admins' => 'يُمنح المسؤولين حق الوصول تلقائيًا إلى جميع المحتويات ولكن هذه الخيارات قد تعرض خيارات واجهة المستخدم أو تخفيها.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'الكل', 'role_own' => 'ما يخص', 'role_controlled_by_asset' => 'يتحكم فيها الأصول التي يتم رفعها إلى', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/bg/settings.php b/resources/lang/bg/settings.php index 294451c0f..98649b62e 100644 --- a/resources/lang/bg/settings.php +++ b/resources/lang/bg/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Важно: Добавянето на потребител в някое от горните три роли може да му позволи да промени собствените си права или правата на другите в системата. Възлагайте тези роли само на доверени потребители.', 'role_asset_desc' => 'Тези настройки за достъп контролират достъпа по подразбиране до активите в системата. Настройките за достъп до книги, глави и страници ще отменят тези настройки.', 'role_asset_admins' => 'Администраторите автоматично получават достъп до цялото съдържание, но тези опции могат да показват или скриват опциите за потребителския интерфейс.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Всички', 'role_own' => 'Собствени', 'role_controlled_by_asset' => 'Контролирани от актива, към който са качени', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/bs/settings.php b/resources/lang/bs/settings.php index 9dbd96c5a..e2a22ee37 100644 --- a/resources/lang/bs/settings.php +++ b/resources/lang/bs/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Be aware that access to any of the above three permissions can allow a user to alter their own privileges or the privileges of others in the system. Only assign roles with these permissions to trusted users.', 'role_asset_desc' => 'These permissions control default access to the assets within the system. Permissions on Books, Chapters and Pages will override these permissions.', 'role_asset_admins' => 'Admins are automatically given access to all content but these options may show or hide UI options.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'All', 'role_own' => 'Own', 'role_controlled_by_asset' => 'Controlled by the asset they are uploaded to', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/ca/settings.php b/resources/lang/ca/settings.php index 694005cde..18b33ade1 100755 --- a/resources/lang/ca/settings.php +++ b/resources/lang/ca/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Tingueu en compte que l\'accés a qualsevol dels tres permisos de dalt pot permetre que un usuari alteri els seus propis permisos o els privilegis d\'altres usuaris del sistema. Assigneu rols amb aquests permisos només a usuaris de confiança.', 'role_asset_desc' => 'Aquests permisos controlen l\'accés per defecte als recursos del sistema. Els permisos de llibres, capítols i pàgines tindran més importància que aquests permisos.', 'role_asset_admins' => 'Els administradors tenen accés automàticament a tot el contingut, però aquestes opcions poden mostrar o amagar opcions de la interfície d\'usuari.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Tot', 'role_own' => 'Propi', 'role_controlled_by_asset' => 'Controlat pel recurs en què es pugen', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/cs/settings.php b/resources/lang/cs/settings.php index 68328ce53..c885869b0 100644 --- a/resources/lang/cs/settings.php +++ b/resources/lang/cs/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Berte na vědomí, že přístup k některému ze tří výše uvedených oprávnění může uživateli umožnit změnit svá vlastní oprávnění nebo oprávnění ostatních uživatelů v systému. Přiřazujte role s těmito oprávněními pouze důvěryhodným uživatelům.', 'role_asset_desc' => 'Tato oprávnění řídí přístup k obsahu napříč systémem. Specifická oprávnění na knihách, kapitolách a stránkách převáží tato nastavení.', 'role_asset_admins' => 'Administrátoři automaticky dostávají přístup k veškerému obsahu, ale tyto volby mohou ukázat nebo skrýt volby v uživatelském rozhraní.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Vše', 'role_own' => 'Vlastní', 'role_controlled_by_asset' => 'Řídí se obsahem, do kterého jsou nahrávány', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/cy/settings.php b/resources/lang/cy/settings.php index 9dbd96c5a..e2a22ee37 100644 --- a/resources/lang/cy/settings.php +++ b/resources/lang/cy/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Be aware that access to any of the above three permissions can allow a user to alter their own privileges or the privileges of others in the system. Only assign roles with these permissions to trusted users.', 'role_asset_desc' => 'These permissions control default access to the assets within the system. Permissions on Books, Chapters and Pages will override these permissions.', 'role_asset_admins' => 'Admins are automatically given access to all content but these options may show or hide UI options.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'All', 'role_own' => 'Own', 'role_controlled_by_asset' => 'Controlled by the asset they are uploaded to', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/da/settings.php b/resources/lang/da/settings.php index 2296e3e1c..5c7913b71 100644 --- a/resources/lang/da/settings.php +++ b/resources/lang/da/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Vær opmærksom på, at adgang til alle af de ovennævnte tre tilladelser, kan give en bruger mulighed for at ændre deres egne brugerrettigheder eller brugerrettigheder for andre i systemet. Tildel kun roller med disse tilladelser til betroede brugere.', 'role_asset_desc' => 'Disse tilladelser kontrollerer standardadgang til medier og "assets" i systemet. Tilladelser til bøger, kapitler og sider tilsidesætter disse tilladelser.', 'role_asset_admins' => 'Administratorer får automatisk adgang til alt indhold, men disse indstillinger kan vise eller skjule UI-indstillinger.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Alle', 'role_own' => 'Eget', 'role_controlled_by_asset' => 'Styres af det medie/"asset", de uploades til', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/de/settings.php b/resources/lang/de/settings.php index 95ee06021..bb004187d 100644 --- a/resources/lang/de/settings.php +++ b/resources/lang/de/settings.php @@ -164,6 +164,7 @@ Hinweis: Benutzer können ihre E-Mail Adresse nach erfolgreicher Registrierung 'roles_system_warning' => 'Beachten Sie, dass der Zugriff auf eine der oben genannten drei Berechtigungen einem Benutzer erlauben kann, seine eigenen Berechtigungen oder die Rechte anderer im System zu ändern. Weisen Sie nur Rollen, mit diesen Berechtigungen, vertrauenswürdigen Benutzern zu.', 'role_asset_desc' => 'Diese Berechtigungen gelten für den Standard-Zugriff innerhalb des Systems. Berechtigungen für Bücher, Kapitel und Seiten überschreiben diese Berechtigungenen.', 'role_asset_admins' => 'Administratoren erhalten automatisch Zugriff auf alle Inhalte, aber diese Optionen können Oberflächenoptionen ein- oder ausblenden.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Alle', 'role_own' => 'Eigene', 'role_controlled_by_asset' => 'Berechtigungen werden vom Uploadziel bestimmt', @@ -302,6 +303,7 @@ Hinweis: Benutzer können ihre E-Mail Adresse nach erfolgreicher Registrierung 'pl' => 'Polnisch', 'pt' => 'Portugiesisch', 'pt_BR' => 'Portugiesisch (Brasilien)', + 'ro' => 'Română', 'ru' => 'Russisch', 'sk' => 'Slowenisch', 'sl' => 'Slowenisch', diff --git a/resources/lang/de_informal/settings.php b/resources/lang/de_informal/settings.php index 84ae4b0ee..7bc59a53d 100644 --- a/resources/lang/de_informal/settings.php +++ b/resources/lang/de_informal/settings.php @@ -164,6 +164,7 @@ Hinweis: Benutzer können ihre E-Mail Adresse nach erfolgreicher Registrierung 'roles_system_warning' => 'Beachten Sie, dass der Zugriff auf eine der oben genannten drei Berechtigungen einem Benutzer erlauben kann, seine eigenen Berechtigungen oder die Rechte anderer im System zu ändern. Weisen Sie nur Rollen, mit diesen Berechtigungen, vertrauenswürdigen Benutzern zu.', 'role_asset_desc' => 'Diese Berechtigungen gelten für den Standard-Zugriff innerhalb des Systems. Berechtigungen für Bücher, Kapitel und Seiten überschreiben diese Berechtigungenen.', 'role_asset_admins' => 'Administratoren erhalten automatisch Zugriff auf alle Inhalte, aber diese Optionen können Oberflächenoptionen ein- oder ausblenden.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Alle', 'role_own' => 'Eigene', 'role_controlled_by_asset' => 'Berechtigungen werden vom Uploadziel bestimmt', @@ -302,6 +303,7 @@ Hinweis: Benutzer können ihre E-Mail Adresse nach erfolgreicher Registrierung 'pl' => 'Polnisch', 'pt' => 'Portugiesisch', 'pt_BR' => 'Portugiesisch (Brasilien)', + 'ro' => 'Română', 'ru' => 'Russisch', 'sk' => 'Slowenisch', 'sl' => 'Slowenisch', diff --git a/resources/lang/es/settings.php b/resources/lang/es/settings.php index 4c12e9636..da51f14c7 100644 --- a/resources/lang/es/settings.php +++ b/resources/lang/es/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Tenga en cuenta que el acceso a cualquiera de los tres permisos anteriores puede permitir a un usuario alterar sus propios privilegios o los privilegios de otros en el sistema. Sólo asignar roles con estos permisos a usuarios de confianza.', 'role_asset_desc' => 'Estos permisos controlan el acceso por defecto a los contenidos del sistema. Los permisos de Libros, Capítulos y Páginas sobreescribiran estos permisos.', 'role_asset_admins' => 'A los administradores se les asigna automáticamente permisos para acceder a todo el contenido pero estas opciones podrían mostrar u ocultar opciones de la interfaz.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Todo', 'role_own' => 'Propio', 'role_controlled_by_asset' => 'Controlado por el contenido al que ha sido subido', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polaco', 'pt' => 'Portugués', 'pt_BR' => 'Portugués brasileño', + 'ro' => 'Română', 'ru' => 'Ruso', 'sk' => 'Eslovaco', 'sl' => 'Esloveno', diff --git a/resources/lang/es_AR/settings.php b/resources/lang/es_AR/settings.php index 6794affe7..3d9a25b72 100644 --- a/resources/lang/es_AR/settings.php +++ b/resources/lang/es_AR/settings.php @@ -162,6 +162,7 @@ return [ 'roles_system_warning' => 'Tenga en cuenta que el acceso a cualquiera de los tres permisos anteriores puede permitir a un usuario modificar sus propios privilegios o los privilegios de otros usuarios en el sistema. Asignar roles con estos permisos sólo a usuarios de comfianza.', 'role_asset_desc' => 'Estos permisos controlan el acceso por defecto a los activos del sistema. Permisos definidos en Libros, Capítulos y Páginas ignorarán estos permisos.', 'role_asset_admins' => 'Los administradores reciben automáticamente acceso a todo el contenido pero estas opciones pueden mostrar u ocultar opciones de UI.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Todo', 'role_own' => 'Propio', 'role_controlled_by_asset' => 'Controlado por el activo al que ha sido subido', @@ -300,6 +301,7 @@ return [ 'pl' => 'Polaco', 'pt' => 'Portugués', 'pt_BR' => 'Portugués brasileño', + 'ro' => 'Română', 'ru' => 'Ruso', 'sk' => 'Eslovaco', 'sl' => 'Esloveno', diff --git a/resources/lang/et/settings.php b/resources/lang/et/settings.php index e74f1e35a..2248f0c23 100644 --- a/resources/lang/et/settings.php +++ b/resources/lang/et/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Pane tähele, et ülalolevad kolm õigust võimaldavad kasutajal enda või teiste kasutajate õiguseid muuta. Määra nende õigustega roll ainult usaldusväärsetele kasutajatele.', 'role_asset_desc' => 'Need load kontrollivad vaikimisi ligipääsu süsteemis olevale sisule. Raamatute, peatükkide ja lehtede õigused rakenduvad esmajärjekorras.', 'role_asset_admins' => 'Administraatoritel on automaatselt ligipääs kogu sisule, aga need valikud võivad peida või näidata kasutajaliidese elemente.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Kõik', 'role_own' => 'Enda omad', 'role_controlled_by_asset' => 'Õigused määratud seotud objekti kaudu', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski (poola keel)', 'pt' => 'Português (portugali keel)', 'pt_BR' => 'Português do Brasil (Brasiilia portugali keel)', + 'ro' => 'Română', 'ru' => 'Русский (vene keel)', 'sk' => 'Slovensky', 'sl' => 'Sloveenia', diff --git a/resources/lang/eu/settings.php b/resources/lang/eu/settings.php index 0c6c93b4e..390b47705 100644 --- a/resources/lang/eu/settings.php +++ b/resources/lang/eu/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Be aware that access to any of the above three permissions can allow a user to alter their own privileges or the privileges of others in the system. Only assign roles with these permissions to trusted users.', 'role_asset_desc' => 'These permissions control default access to the assets within the system. Permissions on Books, Chapters and Pages will override these permissions.', 'role_asset_admins' => 'Admins are automatically given access to all content but these options may show or hide UI options.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Guztiak', 'role_own' => 'Norberarenak', 'role_controlled_by_asset' => 'Controlled by the asset they are uploaded to', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/fa/activities.php b/resources/lang/fa/activities.php index 0626eb903..5cca3a587 100644 --- a/resources/lang/fa/activities.php +++ b/resources/lang/fa/activities.php @@ -39,13 +39,13 @@ return [ // Bookshelves 'bookshelf_create' => 'created shelf', - 'bookshelf_create_notification' => 'Shelf successfully created', + 'bookshelf_create_notification' => 'قفسه کتاب با موفقیت ایجاد شد', 'bookshelf_create_from_book' => 'converted book to shelf', 'bookshelf_create_from_book_notification' => 'کتاب با موفقیت به یک قفسه تبدیل شد', 'bookshelf_update' => 'updated shelf', 'bookshelf_update_notification' => 'Shelf successfully updated', 'bookshelf_delete' => 'deleted shelf', - 'bookshelf_delete_notification' => 'Shelf successfully deleted', + 'bookshelf_delete_notification' => 'قفسه کتاب با موفقیت حذف شد', // Favourites 'favourite_add_notification' => '":name" به علاقه مندی های شما اضافه شد', diff --git a/resources/lang/fa/settings.php b/resources/lang/fa/settings.php index 36079ab72..84b71f592 100644 --- a/resources/lang/fa/settings.php +++ b/resources/lang/fa/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'توجه داشته باشید که دسترسی به هر یک از سه مجوز فوق می‌تواند به کاربر اجازه دهد تا امتیازات خود یا امتیازات دیگران را در سیستم تغییر دهد. فقط نقش هایی را با این مجوزها به کاربران مورد اعتماد اختصاص دهید.', 'role_asset_desc' => 'این مجوزها دسترسی پیش‌فرض به دارایی‌های درون سیستم را کنترل می‌کنند. مجوزهای مربوط به کتاب‌ها، فصل‌ها و صفحات این مجوزها را لغو می‌کنند.', 'role_asset_admins' => 'به ادمین‌ها به‌طور خودکار به همه محتوا دسترسی داده می‌شود، اما این گزینه‌ها ممکن است گزینه‌های UI را نشان داده یا پنهان کنند.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'همه', 'role_own' => 'صاحب', 'role_controlled_by_asset' => 'توسط دارایی که در آن آپلود می شود کنترل می شود', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/fr/settings.php b/resources/lang/fr/settings.php index 2afae373e..c97a9c81c 100644 --- a/resources/lang/fr/settings.php +++ b/resources/lang/fr/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Sachez que l\'accès à l\'une des trois permissions ci-dessus peut permettre à un utilisateur de modifier ses propres privilèges ou les privilèges des autres utilisateurs du système. N\'attribuez uniquement des rôles avec ces permissions qu\'à des utilisateurs de confiance.', 'role_asset_desc' => 'Ces permissions contrôlent l\'accès par défaut des ressources dans le système. Les permissions dans les livres, les chapitres et les pages ignoreront ces permissions', 'role_asset_admins' => 'Les administrateurs ont automatiquement accès à tous les contenus mais les options suivantes peuvent afficher ou masquer certaines options de l\'interface.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Tous', 'role_own' => 'Propres', 'role_controlled_by_asset' => 'Contrôlé par les ressources les ayant envoyés', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polonais', 'pt' => 'Portugais', 'pt_BR' => 'Portugais (Brésil)', + 'ro' => 'Română', 'ru' => 'Russe', 'sk' => 'Slovaque', 'sl' => 'Slovène', diff --git a/resources/lang/he/settings.php b/resources/lang/he/settings.php index ddf087bdc..64d5491cd 100755 --- a/resources/lang/he/settings.php +++ b/resources/lang/he/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'שימו לב לכך שגישה לכל אחת משלושת ההרשאות הנ"ל יכולה לאפשר למשתמש לשנות את הפריווילגיות שלהם או של אחרים במערכת. הגדירו תפקידים להרשאות אלה למשתמשים בהם אתם בוטחים בלבד.', 'role_asset_desc' => 'הרשאות אלו שולטות בגישת ברירת המחדל למשאבים בתוך המערכת. הרשאות של ספרים, פרקים ודפים יגברו על הרשאות אלו.', 'role_asset_admins' => 'מנהלים מקבלים הרשאה מלאה לכל התוכן אך אפשרויות אלו עלולות להציג או להסתיר אפשרויות בממשק', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'הכל', 'role_own' => 'שלי', 'role_controlled_by_asset' => 'נשלטים על ידי המשאב אליו הועלו', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/hr/settings.php b/resources/lang/hr/settings.php index d865488e8..70b2ddac8 100644 --- a/resources/lang/hr/settings.php +++ b/resources/lang/hr/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Uzmite u obzir da pristup bilo kojem od ovih dopuštenja dozvoljavate korisniku upravljanje dopuštenjima ostalih u sustavu. Ova dopuštenja dodijelite pouzdanim korisnicima.', 'role_asset_desc' => 'Ova dopuštenja kontroliraju zadane pristupe. Dopuštenja za knjige, poglavlja i stranice ih poništavaju.', 'role_asset_admins' => 'Administratori automatski imaju pristup svim sadržajima, ali ove opcije mogu prikazati ili sakriti korisnička sučelja.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Sve', 'role_own' => 'Vlastito', 'role_controlled_by_asset' => 'Kontrolirano od strane vlasnika', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/hu/settings.php b/resources/lang/hu/settings.php index 876cfdc23..c1a9bf68b 100644 --- a/resources/lang/hu/settings.php +++ b/resources/lang/hu/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Be aware that access to any of the above three permissions can allow a user to alter their own privileges or the privileges of others in the system. Only assign roles with these permissions to trusted users.', 'role_asset_desc' => 'Ezek a jogosultság vezérlik a alapértelmezés szerinti hozzáférést a rendszerben található eszközökhöz. A könyvek, fejezetek és oldalak jogosultságai felülírják ezeket a jogosultságokat.', 'role_asset_admins' => 'Az adminisztrátorok automatikusan hozzáférést kapnak minden tartalomhoz, de ezek a beállítások megjeleníthetnek vagy elrejthetnek felhasználói felület beállításokat.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Összes', 'role_own' => 'Saját', 'role_controlled_by_asset' => 'Az általuk feltöltött eszköz által ellenőrzött', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/id/settings.php b/resources/lang/id/settings.php index 5015f863f..a6221e646 100644 --- a/resources/lang/id/settings.php +++ b/resources/lang/id/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Ketahuilah bahwa akses ke salah satu dari tiga izin di atas dapat memungkinkan pengguna untuk mengubah hak mereka sendiri atau orang lain dalam sistem. Hanya tetapkan peran dengan izin ini untuk pengguna tepercaya.', 'role_asset_desc' => 'Izin ini mengontrol akses default ke aset dalam sistem. Izin pada Buku, Bab, dan Halaman akan menggantikan izin ini.', 'role_asset_admins' => 'Admin secara otomatis diberi akses ke semua konten tetapi opsi ini dapat menampilkan atau menyembunyikan opsi UI.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Semua', 'role_own' => 'Sendiri', 'role_controlled_by_asset' => 'Dikendalikan oleh aset tempat mereka diunggah', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/it/settings.php b/resources/lang/it/settings.php index 7f5c10df1..df8954a8d 100755 --- a/resources/lang/it/settings.php +++ b/resources/lang/it/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Siate consapevoli che l\'accesso a uno dei tre permessi qui sopra, può consentire a un utente di modificare i propri privilegi o i privilegi di altri nel sistema. Assegna ruoli con questi permessi solo ad utenti fidati.', 'role_asset_desc' => 'Questi permessi controllano l\'accesso di default alle entità. I permessi nei Libri, Capitoli e Pagine sovrascriveranno questi.', 'role_asset_admins' => 'Gli amministratori hanno automaticamente accesso a tutti i contenuti ma queste opzioni possono mostrare o nascondere le opzioni della UI.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Tutti', 'role_own' => 'Propri', 'role_controlled_by_asset' => 'Controllato dall\'entità in cui sono caricati', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polacco', 'pt' => 'Portoghese', 'pt_BR' => 'Portoghese Brasiliano', + 'ro' => 'Română', 'ru' => 'Russo', 'sk' => 'Sloveno', 'sl' => 'Sloveno', diff --git a/resources/lang/ja/settings.php b/resources/lang/ja/settings.php index f68f5f7c4..2bf691c9f 100644 --- a/resources/lang/ja/settings.php +++ b/resources/lang/ja/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => '上記の3つの権限のいずれかを付与することは、ユーザーが自分の特権またはシステム内の他のユーザーの特権を変更できる可能性があることに注意してください。これらの権限は信頼できるユーザーにのみ割り当ててください。', 'role_asset_desc' => '各アセットに対するデフォルトの権限を設定します。ここで設定した権限が優先されます。', 'role_asset_admins' => '管理者にはすべてのコンテンツへのアクセス権が自動的に付与されますが、これらのオプションはUIオプションを表示または非表示にする場合があります。', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => '全て', 'role_own' => '自身', 'role_controlled_by_asset' => 'このアセットに対し、右記の操作を許可:', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/ko/settings.php b/resources/lang/ko/settings.php index 6d7d49fda..2c3b21de8 100755 --- a/resources/lang/ko/settings.php +++ b/resources/lang/ko/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => '위 세 권한은 자신의 권한이나 다른 유저의 권한을 바꿀 수 있습니다.', 'role_asset_desc' => '책, 챕터, 문서별 권한은 이 설정에 우선합니다.', 'role_asset_admins' => 'Admin 권한은 어디든 접근할 수 있지만 이 설정은 사용자 인터페이스에서 해당 활동을 표시할지 결정합니다.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => '모든 항목', 'role_own' => '직접 만든 항목', 'role_controlled_by_asset' => '저마다 다름', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/lt/settings.php b/resources/lang/lt/settings.php index 16df6b826..40e7b500f 100644 --- a/resources/lang/lt/settings.php +++ b/resources/lang/lt/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Būkite sąmoningi, kad prieiga prie bet kurio iš trijų leidimų viršuje gali leisti naudotojui pakeisti jų pačių privilegijas arba kitų privilegijas sistemoje. Paskirkite vaidmenis su šiais leidimais tik patikimiems naudotojams.', 'role_asset_desc' => 'Šie leidimai kontroliuoja numatytą prieigą į nuosavybę, esančią sistemoje. Knygų, skyrių ir puslapių leidimai nepaisys šių leidimų.', 'role_asset_admins' => 'Administratoriams automatiškai yra suteikiama prieiga prie viso turinio, tačiau šie pasirinkimai gali rodyti arba slėpti vartotojo sąsajos parinktis.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Visi', 'role_own' => 'Nuosavi', 'role_controlled_by_asset' => 'Kontroliuojami nuosavybės, į kurią yra įkelti', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/lv/settings.php b/resources/lang/lv/settings.php index 66381a595..7c0896a7a 100644 --- a/resources/lang/lv/settings.php +++ b/resources/lang/lv/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Jebkuras no trīs augstāk redzamajām atļaujām dod iespēju lietotājam mainīt savas un citu lietotāju sistēmas atļaujas. Pievieno šīs grupu atļaujas tikai tiem lietotājiem, kuriem uzticies.', 'role_asset_desc' => 'Šīs piekļuves tiesības kontrolē noklusēto piekļuvi sistēmas resursiem. Grāmatām, nodaļām un lapām norādītās tiesības būs pārākas par šīm.', 'role_asset_admins' => 'Administratoriem automātiski ir piekļuve visam saturam, bet šie uzstādījumi var noslēpt vai parādīt lietotāja saskarnes iespējas.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Visi', 'role_own' => 'Savi', 'role_controlled_by_asset' => 'Kontrolē resurss, uz ko tie ir augšupielādēti', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/nb/settings.php b/resources/lang/nb/settings.php index c0b5a8596..a14ffb59c 100644 --- a/resources/lang/nb/settings.php +++ b/resources/lang/nb/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Vær oppmerksom på at tilgang til noen av de ovennevnte tre tillatelsene kan tillate en bruker å endre sine egne rettigheter eller rettighetene til andre i systemet. Bare tildel roller med disse tillatelsene til pålitelige brukere.', 'role_asset_desc' => 'Disse tillatelsene kontrollerer standard tilgang til eiendelene i systemet. Tillatelser til bøker, kapitler og sider overstyrer disse tillatelsene.', 'role_asset_admins' => 'Administratorer får automatisk tilgang til alt innhold, men disse alternativene kan vise eller skjule UI-alternativer.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Alle', 'role_own' => 'Egne', 'role_controlled_by_asset' => 'Kontrollert av eiendelen de er lastet opp til', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/nl/settings.php b/resources/lang/nl/settings.php index 96dd849b0..32784f527 100644 --- a/resources/lang/nl/settings.php +++ b/resources/lang/nl/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Wees ervan bewust dat toegang tot een van de bovengenoemde drie machtigingen een gebruiker in staat kan stellen zijn eigen machtigingen of de machtigingen van anderen in het systeem kan wijzigen. Wijs alleen rollen toe met deze machtigingen aan vertrouwde gebruikers.', 'role_asset_desc' => 'Deze machtigingen bepalen de standaard toegang tot de assets binnen het systeem. Machtigingen op boeken, hoofdstukken en pagina\'s overschrijven deze instelling.', 'role_asset_admins' => 'Beheerders krijgen automatisch toegang tot alle inhoud, maar deze opties kunnen gebruikersinterface opties tonen of verbergen.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Alles', 'role_own' => 'Eigen', 'role_controlled_by_asset' => 'Gecontroleerd door de asset waar deze is geüpload', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski (Pools)', 'pt' => 'Português (Portugees)', 'pt_BR' => 'Português do Brasil (Braziliaans-Portugees)', + 'ro' => 'Română', 'ru' => 'Русский (Russisch)', 'sk' => 'Slovensky (Slowaaks)', 'sl' => 'Slovenščina (Sloveens)', diff --git a/resources/lang/pl/settings.php b/resources/lang/pl/settings.php index 27587fbd5..fd3d89bfc 100644 --- a/resources/lang/pl/settings.php +++ b/resources/lang/pl/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Pamiętaj, że dostęp do trzech powyższych uprawnień może pozwolić użytkownikowi na zmianę własnych uprawnień lub uprawnień innych osób w systemie. Przypisz tylko role z tymi uprawnieniami do zaufanych użytkowników.', 'role_asset_desc' => 'Te ustawienia kontrolują zarządzanie zasobami systemu. Uprawnienia książek, rozdziałów i stron nadpisują te ustawienia.', 'role_asset_admins' => 'Administratorzy mają automatycznie dostęp do wszystkich treści, ale te opcję mogą być pokazywać lub ukrywać opcje interfejsu użytkownika.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Wszyscy', 'role_own' => 'Własne', 'role_controlled_by_asset' => 'Kontrolowane przez zasób, do którego zostały udostępnione', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/pt/settings.php b/resources/lang/pt/settings.php index 3a2c9c62f..cf581fe2c 100644 --- a/resources/lang/pt/settings.php +++ b/resources/lang/pt/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Esteja ciente de que o acesso a qualquer uma das três permissões acima pode permitir que um utilizador altere os seus próprios privilégios ou privilégios de outros no sistema. Apenas atribua cargos com essas permissões a utilizadores de confiança.', 'role_asset_desc' => 'Estas permissões controlam o acesso padrão para os ativos dentro do sistema. Permissões em Livros, Capítulos e Páginas serão sobrescritas por estas permissões.', 'role_asset_admins' => 'Os administradores recebem automaticamente acesso a todo o conteúdo, mas estas opções podem mostrar ou ocultar as opções da Interface de Usuário.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Todos', 'role_own' => 'Próprio', 'role_controlled_by_asset' => 'Controlado pelo ativo para o qual eles são enviados', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/pt_BR/settings.php b/resources/lang/pt_BR/settings.php index 7b8234c59..5d5a5f61d 100644 --- a/resources/lang/pt_BR/settings.php +++ b/resources/lang/pt_BR/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Esteja ciente de que o acesso a qualquer uma das três permissões acima pode permitir que um usuário altere seus próprios privilégios ou privilégios de outros usuários no sistema. Apenas atribua cargos com essas permissões para usuários confiáveis.', 'role_asset_desc' => 'Essas permissões controlam o acesso padrão para os ativos dentro do sistema. Permissões em Livros, Capítulos e Páginas serão sobrescritas por essas permissões.', 'role_asset_admins' => 'Administradores recebem automaticamente acesso a todo o conteúdo, mas essas opções podem mostrar ou ocultar as opções da Interface de Usuário.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Todos', 'role_own' => 'Próprio', 'role_controlled_by_asset' => 'Controlado pelos ativos nos quais o upload foi realizado', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/ro/settings.php b/resources/lang/ro/settings.php index 04265581c..fd11ed99d 100644 --- a/resources/lang/ro/settings.php +++ b/resources/lang/ro/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Fi conștient de faptul că accesul la oricare dintre cele trei permisiuni de mai sus poate permite unui utilizator să își modifice propriile privilegii sau privilegiile altor persoane din sistem. Atribuie doar roluri cu aceste permisiuni utilizatorilor de încredere.', 'role_asset_desc' => 'Aceste permisiuni controlează accesul implicit la activele din sistem. Permisiunile pe Cărți, Capitole și Pagini vor suprascrie aceste permisiuni.', 'role_asset_admins' => 'Administratorilor li se acordă automat acces la tot conținutul, dar aceste opțiuni pot afișa sau ascunde opțiunile UI.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Tot', 'role_own' => 'Propriu', 'role_controlled_by_asset' => 'Controlat de activele pe care sunt încărcate', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/ru/settings.php b/resources/lang/ru/settings.php index 5eaca38d2..010df30f7 100755 --- a/resources/lang/ru/settings.php +++ b/resources/lang/ru/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Имейте в виду, что доступ к любому из указанных выше трех разрешений может позволить пользователю изменить свои собственные привилегии или привилегии других пользователей системы. Назначать роли с этими правами можно только доверенным пользователям.', 'role_asset_desc' => 'Эти разрешения контролируют доступ по умолчанию к параметрам внутри системы. Разрешения на книги, главы и страницы перезапишут эти разрешения.', 'role_asset_admins' => 'Администраторы автоматически получают доступ ко всему контенту, но эти опции могут отображать или скрывать параметры пользовательского интерфейса.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Все', 'role_own' => 'Владелец', 'role_controlled_by_asset' => 'Контролируется активом, в который они загружены', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/sk/settings.php b/resources/lang/sk/settings.php index 841e6620d..d6ceb0d84 100644 --- a/resources/lang/sk/settings.php +++ b/resources/lang/sk/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Uvedomte si, že prístup ku ktorémukoľvek z vyššie uvedených troch povolení môže používateľovi umožniť zmeniť svoje vlastné privilégiá alebo privilégiá ostatných v systéme. Roly s týmito povoleniami priraďujte iba dôveryhodným používateľom.', 'role_asset_desc' => 'Tieto oprávnenia regulujú prednastavený prístup k zdroju v systéme. Oprávnenia pre knihy, kapitoly a stránky majú vyššiu prioritu.', 'role_asset_admins' => 'Správcovia majú automaticky prístup ku všetkému obsahu, ale tieto možnosti môžu zobraziť alebo skryť možnosti používateľského rozhrania.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Všetko', 'role_own' => 'Vlastné', 'role_controlled_by_asset' => 'Regulované zdrojom, do ktorého sú nahrané', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/sl/settings.php b/resources/lang/sl/settings.php index b7974c114..8adaabc0f 100644 --- a/resources/lang/sl/settings.php +++ b/resources/lang/sl/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Zavedajte se, da lahko dostop do kateregakoli od zgornjih treh dovoljenj uporabniku omogoči, da spremeni lastne privilegije ali privilegije drugih v sistemu. Vloge s temi dovoljenji dodelite samo zaupanja vrednim uporabnikom.', 'role_asset_desc' => 'Ta dovoljenja nadzorujejo privzeti dostop do sredstev v sistemu. Dovoljenja za knjige, poglavja in strani bodo razveljavila ta dovoljenja.', 'role_asset_admins' => 'Skrbniki samodejno pridobijo dostop do vseh vsebin, vendar lahko te možnosti prikažejo ali pa skrijejo možnosti uporabniškega vmesnika.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Vse', 'role_own' => 'Lasten', 'role_controlled_by_asset' => 'Nadzira ga sredstvo, v katerega so naloženi', @@ -300,6 +301,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'slovenščina', diff --git a/resources/lang/sv/settings.php b/resources/lang/sv/settings.php index 36ec995d1..f27605454 100644 --- a/resources/lang/sv/settings.php +++ b/resources/lang/sv/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Var medveten om att åtkomst till någon av ovanstående tre behörigheter kan tillåta en användare att ändra sina egna rättigheter eller andras rättigheter i systemet. Tilldela endast roller med dessa behörigheter till betrodda användare.', 'role_asset_desc' => 'Det här är standardinställningarna för allt innehåll i systemet. Eventuella anpassade rättigheter på böcker, kapitel och sidor skriver över dessa inställningar.', 'role_asset_admins' => 'Administratörer har automatisk tillgång till allt innehåll men dessa alternativ kan visa och dölja vissa gränssnittselement', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Alla', 'role_own' => 'Egna', 'role_controlled_by_asset' => 'Kontrolleras av den sida de laddas upp till', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenska', diff --git a/resources/lang/tr/settings.php b/resources/lang/tr/settings.php index e12d60f69..68714e796 100755 --- a/resources/lang/tr/settings.php +++ b/resources/lang/tr/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Yukarıdaki üç izinden herhangi birine erişimin, kullanıcının kendi ayrıcalıklarını veya sistemdeki diğerlerinin ayrıcalıklarını değiştirmesine izin verebileceğini unutmayın. Yalnızca bu izinlere sahip rolleri güvenilir kullanıcılara atayın.', 'role_asset_desc' => 'Bu izinler, sistem içindeki varlıklara varsayılan erişim izinlerini ayarlar. Kitaplar, bölümler ve sayfalar üzerindeki izinler, buradaki izinleri geçersiz kılar.', 'role_asset_admins' => 'Yöneticilere otomatik olarak bütün içeriğe erişim yetkisi verilir ancak bu seçenekler, kullanıcı arayüzündeki bazı seçeneklerin gösterilmesine veya gizlenmesine neden olabilir.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Hepsi', 'role_own' => 'Kendine Ait', 'role_controlled_by_asset' => 'Yüklendikleri varlık tarafından kontrol ediliyor', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovence', diff --git a/resources/lang/uk/settings.php b/resources/lang/uk/settings.php index 5a454296b..19d68e907 100644 --- a/resources/lang/uk/settings.php +++ b/resources/lang/uk/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Майте на увазі, що доступ до будь-якого з вищезазначених трьох дозволів може дозволити користувачеві змінювати власні привілеї або привілеї інших в системі. Ролі з цими дозволами призначайте лише довіреним користувачам.', 'role_asset_desc' => 'Ці дозволи контролюють стандартні доступи всередині системи. Права на книги, розділи та сторінки перевизначать ці дозволи.', 'role_asset_admins' => 'Адміністратори автоматично отримують доступ до всього вмісту, але ці параметри можуть відображати або приховувати параметри інтерфейсу користувача.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Все', 'role_own' => 'Власне', 'role_controlled_by_asset' => 'Контролюється за об\'єктом, до якого вони завантажуються', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/uz/settings.php b/resources/lang/uz/settings.php index 9dbd96c5a..e2a22ee37 100644 --- a/resources/lang/uz/settings.php +++ b/resources/lang/uz/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Be aware that access to any of the above three permissions can allow a user to alter their own privileges or the privileges of others in the system. Only assign roles with these permissions to trusted users.', 'role_asset_desc' => 'These permissions control default access to the assets within the system. Permissions on Books, Chapters and Pages will override these permissions.', 'role_asset_admins' => 'Admins are automatically given access to all content but these options may show or hide UI options.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'All', 'role_own' => 'Own', 'role_controlled_by_asset' => 'Controlled by the asset they are uploaded to', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/vi/settings.php b/resources/lang/vi/settings.php index 77eb39272..54edf5c8a 100644 --- a/resources/lang/vi/settings.php +++ b/resources/lang/vi/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => 'Be aware that access to any of the above three permissions can allow a user to alter their own privileges or the privileges of others in the system. Only assign roles with these permissions to trusted users.', 'role_asset_desc' => 'Các quyền này điều khiển truy cập mặc định tới tài sản (asset) nằm trong hệ thống. Quyền tại Sách, Chường và Trang se ghi đè các quyền này.', 'role_asset_admins' => 'Quản trị viên được tự động cấp quyền truy cập đến toàn bộ nội dung, tuy nhiên các tùy chọn đó có thể hiện hoặc ẩn tùy chọn giao diện.', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => 'Tất cả', 'role_own' => 'Sở hữu', 'role_controlled_by_asset' => 'Kiểm soát các tài sản (asset) người dùng tải lên', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/zh_CN/settings.php b/resources/lang/zh_CN/settings.php index c68924f8d..b582b4436 100755 --- a/resources/lang/zh_CN/settings.php +++ b/resources/lang/zh_CN/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => '请注意,拥有以上三个权限中的任何一个都会允许用户更改自己的权限或系统中其他人的权限。 请只将拥有这些权限的角色分配给你信任的用户。', 'role_asset_desc' => '对系统内资源的默认访问许可将由这些权限控制。单独设置在书籍、章节和页面上的权限将覆盖这里的权限设定。', 'role_asset_admins' => '管理员可自动获得对所有内容的访问权限,但这些选项可能会显示或隐藏UI选项。', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => '全部的', 'role_own' => '拥有的', 'role_controlled_by_asset' => '由其所在的资源来控制', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', diff --git a/resources/lang/zh_TW/settings.php b/resources/lang/zh_TW/settings.php index 23f9eb0c6..1f523e760 100644 --- a/resources/lang/zh_TW/settings.php +++ b/resources/lang/zh_TW/settings.php @@ -161,6 +161,7 @@ return [ 'roles_system_warning' => '請注意,有上述三項權限中的任一項的使用者都可以更改自己或系統中其他人的權限。有這些權限的角色只應分配給受信任的使用者。', 'role_asset_desc' => '對系統內資源的預設權限將由這裡的權限控制。若有單獨設定在書本、章節和頁面上的權限,將會覆寫這裡的權限設定。', 'role_asset_admins' => '管理員會自動取得對所有內容的存取權,但這些選項可能會顯示或隱藏使用者介面的選項。', + 'role_asset_image_view_note' => 'This relates to visibility within the image manager. Actual access of uploaded image files will be dependant upon system image storage option.', 'role_all' => '全部', 'role_own' => '擁有', 'role_controlled_by_asset' => '依據隸屬的資源來決定', @@ -299,6 +300,7 @@ return [ 'pl' => 'Polski', 'pt' => 'Português', 'pt_BR' => 'Português do Brasil', + 'ro' => 'Română', 'ru' => 'Русский', 'sk' => 'Slovensky', 'sl' => 'Slovenščina', From d0dc5e5c5daccd3e8e801c5d2eac1aab0d300ae8 Mon Sep 17 00:00:00 2001 From: Dan Brown Date: Thu, 8 Sep 2022 12:26:14 +0100 Subject: [PATCH 45/45] Added a little protection to migration query Just to be sure the query is filtered as expected to only affect shelf-based images. --- .../2022_09_02_082910_fix_shelf_cover_image_types.php | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/database/migrations/2022_09_02_082910_fix_shelf_cover_image_types.php b/database/migrations/2022_09_02_082910_fix_shelf_cover_image_types.php index 837bdfe24..a9a413607 100644 --- a/database/migrations/2022_09_02_082910_fix_shelf_cover_image_types.php +++ b/database/migrations/2022_09_02_082910_fix_shelf_cover_image_types.php @@ -22,10 +22,12 @@ class FixShelfCoverImageTypes extends Migration ->pluck('image_id') ->values()->all(); - DB::table('images') - ->where('type', '=', 'cover_book') - ->whereIn('id', $shelfImageIds) - ->update(['type' => 'cover_bookshelf']); + if (count($shelfImageIds) > 0) { + DB::table('images') + ->where('type', '=', 'cover_book') + ->whereIn('id', $shelfImageIds) + ->update(['type' => 'cover_bookshelf']); + } } /**