diff --git a/.github/translators.txt b/.github/translators.txt index b7639ce85..0a4fbdc1b 100644 --- a/.github/translators.txt +++ b/.github/translators.txt @@ -210,3 +210,4 @@ Tomáš Batelka (Vofy) :: Czech Mundo Racional (ismael.mesquita) :: Portuguese, Brazilian Zarik (3apuk) :: Russian Ali Shaatani (a.shaatani) :: Arabic +ChacMaster :: Portuguese, Brazilian diff --git a/app/Entities/Models/Deletion.php b/app/Entities/Models/Deletion.php index 97abb87ff..181c9c580 100644 --- a/app/Entities/Models/Deletion.php +++ b/app/Entities/Models/Deletion.php @@ -59,7 +59,7 @@ class Deletion extends Model implements Loggable /** * Get a URL for this specific deletion. */ - public function getUrl($path): string + public function getUrl(string $path = 'restore'): string { return url("/settings/recycle-bin/{$this->id}/" . ltrim($path, '/')); } diff --git a/app/Entities/Models/Entity.php b/app/Entities/Models/Entity.php index b55334295..7ad78f1d1 100644 --- a/app/Entities/Models/Entity.php +++ b/app/Entities/Models/Entity.php @@ -36,6 +36,7 @@ use Illuminate\Database\Eloquent\SoftDeletes; * @property string $slug * @property Carbon $created_at * @property Carbon $updated_at + * @property Carbon $deleted_at * @property int $created_by * @property int $updated_by * @property bool $restricted diff --git a/app/Entities/Models/PageRevision.php b/app/Entities/Models/PageRevision.php index 2bfa169f4..4daf50536 100644 --- a/app/Entities/Models/PageRevision.php +++ b/app/Entities/Models/PageRevision.php @@ -46,19 +46,10 @@ class PageRevision extends Model /** * Get the url for this revision. - * - * @param null|string $path - * - * @return string */ - public function getUrl($path = null) + public function getUrl(string $path = ''): string { - $url = $this->page->getUrl() . '/revisions/' . $this->id; - if ($path) { - return $url . '/' . trim($path, '/'); - } - - return $url; + return $this->page->getUrl('/revisions/' . $this->id . '/' . ltrim($path, '/')); } /** diff --git a/app/Entities/Tools/BookSortMap.php b/app/Entities/Tools/BookSortMap.php index 43b25817e..ff1ec767f 100644 --- a/app/Entities/Tools/BookSortMap.php +++ b/app/Entities/Tools/BookSortMap.php @@ -24,7 +24,7 @@ class BookSortMap public static function fromJson(string $json): self { - $map = new static(); + $map = new BookSortMap(); $mapData = json_decode($json); foreach ($mapData as $mapDataItem) { diff --git a/app/Entities/Tools/TrashCan.php b/app/Entities/Tools/TrashCan.php index ab62165af..1e130c9e1 100644 --- a/app/Entities/Tools/TrashCan.php +++ b/app/Entities/Tools/TrashCan.php @@ -22,9 +22,12 @@ class TrashCan { /** * Send a shelf to the recycle bin. + * + * @throws NotifyException */ public function softDestroyShelf(Bookshelf $shelf) { + $this->ensureDeletable($shelf); Deletion::createForEntity($shelf); $shelf->delete(); } @@ -36,6 +39,7 @@ class TrashCan */ public function softDestroyBook(Book $book) { + $this->ensureDeletable($book); Deletion::createForEntity($book); foreach ($book->pages as $page) { @@ -57,6 +61,7 @@ class TrashCan public function softDestroyChapter(Chapter $chapter, bool $recordDelete = true) { if ($recordDelete) { + $this->ensureDeletable($chapter); Deletion::createForEntity($chapter); } @@ -77,19 +82,47 @@ class TrashCan public function softDestroyPage(Page $page, bool $recordDelete = true) { if ($recordDelete) { + $this->ensureDeletable($page); Deletion::createForEntity($page); } - // Check if set as custom homepage & remove setting if not used or throw error if active - $customHome = setting('app-homepage', '0:'); - if (intval($page->id) === intval(explode(':', $customHome)[0])) { - if (setting('app-homepage-type') === 'page') { - throw new NotifyException(trans('errors.page_custom_home_deletion'), $page->getUrl()); + $page->delete(); + } + + /** + * Ensure the given entity is deletable. + * Is not for permissions, but logical conditions within the application. + * Will throw if not deletable. + * + * @throws NotifyException + */ + protected function ensureDeletable(Entity $entity): void + { + $customHomeId = intval(explode(':', setting('app-homepage', '0:'))[0]); + $customHomeActive = setting('app-homepage-type') === 'page'; + $removeCustomHome = false; + + // Check custom homepage usage for pages + if ($entity instanceof Page && $entity->id === $customHomeId) { + if ($customHomeActive) { + throw new NotifyException(trans('errors.page_custom_home_deletion'), $entity->getUrl()); } - setting()->remove('app-homepage'); + $removeCustomHome = true; } - $page->delete(); + // Check custom homepage usage within chapters or books + if ($entity instanceof Chapter || $entity instanceof Book) { + if ($entity->pages()->where('id', '=', $customHomeId)->exists()) { + if ($customHomeActive) { + throw new NotifyException(trans('errors.page_custom_home_deletion'), $entity->getUrl()); + } + $removeCustomHome = true; + } + } + + if ($removeCustomHome) { + setting()->remove('app-homepage'); + } } /** diff --git a/app/Http/Controllers/Controller.php b/app/Http/Controllers/Controller.php index f836f18ed..2c4c2df1e 100644 --- a/app/Http/Controllers/Controller.php +++ b/app/Http/Controllers/Controller.php @@ -48,6 +48,8 @@ abstract class Controller extends BaseController /** * On a permission error redirect to home and display. * the error as a notification. + * + * @return never */ protected function showPermissionError() { diff --git a/public/loading_error.png b/public/loading_error.png new file mode 100644 index 000000000..4f588fbe1 Binary files /dev/null and b/public/loading_error.png differ diff --git a/resources/js/components/image-manager.js b/resources/js/components/image-manager.js index c974ab1b0..6d05d3388 100644 --- a/resources/js/components/image-manager.js +++ b/resources/js/components/image-manager.js @@ -74,6 +74,10 @@ class ImageManager { this.listContainer.addEventListener('event-emit-select-image', this.onImageSelectEvent.bind(this)); + this.listContainer.addEventListener('error', event => { + event.target.src = baseUrl('loading_error.png'); + }, true); + onSelect(this.selectButton, () => { if (this.callback) { this.callback(this.lastSelected); diff --git a/resources/js/components/markdown-editor.js b/resources/js/components/markdown-editor.js index a90f74e27..def3db5af 100644 --- a/resources/js/components/markdown-editor.js +++ b/resources/js/components/markdown-editor.js @@ -395,8 +395,9 @@ class MarkdownEditor { actionInsertImage() { const cursorPos = this.cm.getCursor('from'); window.ImageManager.show(image => { + const imageUrl = image.thumbs.display || image.url; let selectedText = this.cm.getSelection(); - let newText = "[![" + (selectedText || image.name) + "](" + image.thumbs.display + ")](" + image.url + ")"; + let newText = "[![" + (selectedText || image.name) + "](" + imageUrl + ")](" + image.url + ")"; this.cm.focus(); this.cm.replaceSelection(newText); this.cm.setCursor(cursorPos.line, cursorPos.ch + newText.length); diff --git a/resources/js/components/wysiwyg-editor.js b/resources/js/components/wysiwyg-editor.js index bde73f4bf..7a2b6ceba 100644 --- a/resources/js/components/wysiwyg-editor.js +++ b/resources/js/components/wysiwyg-editor.js @@ -563,8 +563,9 @@ class WysiwygEditor { } // Replace the actively selected content with the linked image + const imageUrl = image.thumbs.display || image.url; let html = ``; - html += `${image.name}`; + html += `${image.name}`; html += ''; win.tinyMCE.activeEditor.execCommand('mceInsertContent', false, html); }, 'gallery'); @@ -723,8 +724,9 @@ class WysiwygEditor { tooltip: 'Insert an image', onclick: function () { window.ImageManager.show(function (image) { + const imageUrl = image.thumbs.display || image.url; let html = ``; - html += `${image.name}`; + html += `${image.name}`; html += ''; editor.execCommand('mceInsertContent', false, html); }, 'gallery'); diff --git a/resources/lang/cs/common.php b/resources/lang/cs/common.php index 9acd965b3..13865f40e 100644 --- a/resources/lang/cs/common.php +++ b/resources/lang/cs/common.php @@ -74,7 +74,7 @@ return [ 'status' => 'Stav', 'status_active' => 'Aktivní', 'status_inactive' => 'Neaktivní', - 'never' => 'Never', + 'never' => 'Nikdy', // Header 'header_menu_expand' => 'Rozbalit menu v záhlaví', diff --git a/resources/lang/es/auth.php b/resources/lang/es/auth.php index f35432138..4980229ec 100644 --- a/resources/lang/es/auth.php +++ b/resources/lang/es/auth.php @@ -64,7 +64,7 @@ return [ 'email_not_confirmed_resend_button' => 'Reenviar Correo Electrónico de confirmación', // User Invite - 'user_invite_email_subject' => 'As sido invitado a unirte a :appName!', + 'user_invite_email_subject' => 'Has sido invitado a unirte a :appName!', 'user_invite_email_greeting' => 'Se ha creado una cuenta para usted en :appName.', 'user_invite_email_text' => 'Clica en el botón a continuación para ajustar una contraseña y poder acceder:', 'user_invite_email_action' => 'Ajustar la Contraseña de la Cuenta', diff --git a/resources/lang/ja/auth.php b/resources/lang/ja/auth.php index bbfb675c0..9c8d36669 100644 --- a/resources/lang/ja/auth.php +++ b/resources/lang/ja/auth.php @@ -21,7 +21,7 @@ return [ 'email' => 'メールアドレス', 'password' => 'パスワード', 'password_confirm' => 'パスワード (確認)', - 'password_hint' => 'Must be at least 8 characters', + 'password_hint' => '8文字以上で設定する必要があります', 'forgot_password' => 'パスワードをお忘れですか?', 'remember_me' => 'ログイン情報を保存する', 'ldap_email_hint' => 'このアカウントで使用するEメールアドレスを入力してください。', @@ -54,7 +54,7 @@ return [ 'email_confirm_text' => '以下のボタンを押し、メールアドレスを確認してください:', 'email_confirm_action' => 'メールアドレスを確認', 'email_confirm_send_error' => 'Eメールの確認が必要でしたが、システム上でEメールの送信ができませんでした。管理者に連絡し、Eメールが正しく設定されていることを確認してください。', - 'email_confirm_success' => 'Your email has been confirmed! You should now be able to login using this email address.', + 'email_confirm_success' => 'メールアドレスが確認されました!このメールアドレスでログインできるようになりました。', 'email_confirm_resent' => '確認メールを再送信しました。受信トレイを確認してください。', 'email_not_confirmed' => 'Eメールアドレスが確認できていません', @@ -71,7 +71,7 @@ return [ 'user_invite_page_welcome' => ':appNameへようこそ!', 'user_invite_page_text' => 'アカウントの設定を完了してアクセスするには、今後の訪問時に:appNameにログインするためのパスワードを設定する必要があります。', 'user_invite_page_confirm_button' => 'パスワードを確定', - 'user_invite_success_login' => 'Password set, you should now be able to login using your set password to access :appName!', + 'user_invite_success_login' => 'パスワードが設定されました。設定したパスワードで:appNameにログインできるようになりました!', // Multi-factor Authentication 'mfa_setup' => '多要素認証を設定', diff --git a/resources/lang/ja/common.php b/resources/lang/ja/common.php index 2c1d37c08..bf605525b 100644 --- a/resources/lang/ja/common.php +++ b/resources/lang/ja/common.php @@ -85,10 +85,10 @@ return [ 'light_mode' => 'ライトモード', // Layout tabs - 'tab_info' => 'Info', - 'tab_info_label' => 'Tab: Show Secondary Information', - 'tab_content' => 'Content', - 'tab_content_label' => 'Tab: Show Primary Content', + 'tab_info' => '情報', + 'tab_info_label' => 'タブ: サブコンテンツを表示', + 'tab_content' => '内容', + 'tab_content_label' => 'タブ: メインコンテンツを表示', // Email Content 'email_action_help' => '":actionText" をクリックできない場合、以下のURLをコピーしブラウザで開いてください:', diff --git a/resources/lang/ja/entities.php b/resources/lang/ja/entities.php index e6d1f426b..e5ba8c673 100644 --- a/resources/lang/ja/entities.php +++ b/resources/lang/ja/entities.php @@ -22,7 +22,7 @@ return [ 'meta_created_name' => '作成: :timeLength (:user)', 'meta_updated' => '更新: :timeLength', 'meta_updated_name' => '更新: :timeLength (:user)', - 'meta_owned_name' => 'Owned by :user', + 'meta_owned_name' => '所有者: :user', 'entity_select' => 'エンティティ選択', 'images' => '画像', 'my_recent_drafts' => '最近の下書き', @@ -36,14 +36,14 @@ return [ 'export_html' => 'Webページ', 'export_pdf' => 'PDF', 'export_text' => 'テキストファイル', - 'export_md' => 'Markdown File', + 'export_md' => 'Markdown', // Permissions and restrictions 'permissions' => '権限', 'permissions_intro' => 'この設定は各ユーザの役割よりも優先して適用されます。', 'permissions_enable' => 'カスタム権限設定を有効にする', 'permissions_save' => '権限を保存', - 'permissions_owner' => 'Owner', + 'permissions_owner' => '所有者', // Search 'search_results' => '検索結果', @@ -143,8 +143,8 @@ return [ 'books_sort_chapters_last' => 'チャプターを後に', 'books_sort_show_other' => '他のブックを表示', 'books_sort_save' => '並び順を保存', - 'books_copy' => 'Copy Book', - 'books_copy_success' => 'Book successfully copied', + 'books_copy' => 'ブックをコピー', + 'books_copy_success' => 'ブックが正常にコピーされました', // Chapters 'chapter' => 'チャプター', @@ -163,8 +163,8 @@ return [ 'chapters_move' => 'チャプターを移動', 'chapters_move_named' => 'チャプター「:chapterName」を移動', 'chapter_move_success' => 'チャプターを「:bookName」に移動しました', - 'chapters_copy' => 'Copy Chapter', - 'chapters_copy_success' => 'Chapter successfully copied', + 'chapters_copy' => 'チャプターをコピー', + 'chapters_copy_success' => 'チャプターが正常にコピーされました', 'chapters_permissions' => 'チャプター権限', 'chapters_empty' => 'まだチャプター内にページはありません。', 'chapters_permissions_active' => 'チャプターの権限は有効です', @@ -215,16 +215,16 @@ return [ 'pages_copy_success' => 'ページが正常にコピーされました', 'pages_permissions' => 'ページの権限設定', 'pages_permissions_success' => 'ページの権限を更新しました', - 'pages_revision' => 'Revision', + 'pages_revision' => '編集履歴', 'pages_revisions' => '編集履歴', 'pages_revisions_named' => ':pageName のリビジョン', 'pages_revision_named' => ':pageName のリビジョン', - 'pages_revision_restored_from' => 'Restored from #:id; :summary', + 'pages_revision_restored_from' => '#:id :summary から復元', 'pages_revisions_created_by' => '作成者', 'pages_revisions_date' => '日付', 'pages_revisions_number' => '#', - 'pages_revisions_numbered' => 'Revision #:id', - 'pages_revisions_numbered_changes' => 'Revision #:id Changes', + 'pages_revisions_numbered' => 'リビジョン #:id', + 'pages_revisions_numbered_changes' => 'リビジョン #:id の変更', 'pages_revisions_changelog' => '説明', 'pages_revisions_changes' => '変更点', 'pages_revisions_current' => '現在のバージョン', @@ -333,15 +333,15 @@ return [ // Revision 'revision_delete_confirm' => 'このリビジョンを削除しますか?', - 'revision_restore_confirm' => 'Are you sure you want to restore this revision? The current page contents will be replaced.', + 'revision_restore_confirm' => 'このリビジョンを復元してよろしいですか?現在のページの内容が置換されます。', 'revision_delete_success' => 'リビジョンを削除しました', 'revision_cannot_delete_latest' => '最新のリビジョンを削除できません。', // Copy view - 'copy_consider' => 'Please consider the below when copying content.', - 'copy_consider_permissions' => 'Custom permission settings will not be copied.', - 'copy_consider_owner' => 'You will become the owner of all copied content.', - 'copy_consider_images' => 'Page image files will not be duplicated & the original images will retain their relation to the page they were originally uploaded to.', - 'copy_consider_attachments' => 'Page attachments will not be copied.', - 'copy_consider_access' => 'A change of location, owner or permissions may result in this content being accessible to those previously without access.', + 'copy_consider' => 'コンテンツをコピーする場合は以下の点にご注意ください。', + 'copy_consider_permissions' => 'カスタム権限設定はコピーされません。', + 'copy_consider_owner' => 'あなたはコピーされた全てのコンテンツの所有者になります。', + 'copy_consider_images' => 'ページの画像ファイルは複製されず、元の画像は最初にアップロードされたページとの関係を保持します。', + 'copy_consider_attachments' => 'ページの添付ファイルはコピーされません。', + 'copy_consider_access' => '場所、所有者または権限を変更すると、以前アクセスできなかったユーザーがこのコンテンツにアクセスできるようになる可能性があります。', ]; diff --git a/resources/lang/ja/errors.php b/resources/lang/ja/errors.php index c30e3c50c..d63e9bf36 100644 --- a/resources/lang/ja/errors.php +++ b/resources/lang/ja/errors.php @@ -99,7 +99,7 @@ return [ 'api_no_authorization_found' => 'リクエストに認証トークンが見つかりません', 'api_bad_authorization_format' => 'リクエストに認証トークンが見つかりましたが、形式が正しくないようです', 'api_user_token_not_found' => '提供された認証トークンに一致するAPIトークンが見つかりませんでした', - 'api_incorrect_token_secret' => 'The secret provided for the given used API token is incorrect', + 'api_incorrect_token_secret' => '利用されたAPIトークンに対して提供されたシークレットが正しくありません', 'api_user_no_api_permission' => '使用されているAPIトークンの所有者には、API呼び出しを行う権限がありません', 'api_user_token_expired' => '認証トークンが期限切れです。', diff --git a/resources/lang/ja/settings.php b/resources/lang/ja/settings.php index bee756813..0fb4b113e 100644 --- a/resources/lang/ja/settings.php +++ b/resources/lang/ja/settings.php @@ -234,27 +234,27 @@ return [ 'user_api_token_delete_success' => 'APIトークンが正常に削除されました', // Webhooks - 'webhooks' => 'Webhooks', - 'webhooks_create' => 'Create New Webhook', - 'webhooks_none_created' => 'No webhooks have yet been created.', - 'webhooks_edit' => 'Edit Webhook', - 'webhooks_save' => 'Save Webhook', - 'webhooks_details' => 'Webhook Details', - 'webhooks_details_desc' => 'Provide a user friendly name and a POST endpoint as a location for the webhook data to be sent to.', - 'webhooks_events' => 'Webhook Events', - 'webhooks_events_desc' => 'Select all the events that should trigger this webhook to be called.', - 'webhooks_events_warning' => 'Keep in mind that these events will be triggered for all selected events, even if custom permissions are applied. Ensure that use of this webhook won\'t expose confidential content.', - 'webhooks_events_all' => 'All system events', - 'webhooks_name' => 'Webhook Name', - 'webhooks_timeout' => 'Webhook Request Timeout (Seconds)', - 'webhooks_endpoint' => 'Webhook Endpoint', + 'webhooks' => 'Webhook', + 'webhooks_create' => 'Webhookを作成', + 'webhooks_none_created' => 'Webhookはまだ作成されていません。', + 'webhooks_edit' => 'Webhookを編集', + 'webhooks_save' => 'Webhookを保存', + 'webhooks_details' => 'Webhookの詳細', + 'webhooks_details_desc' => 'ユーザーフレンドリーな名前とWebhookデータの送信先にするPOSTエンドポイントを指定します。', + 'webhooks_events' => 'Webhookのイベント', + 'webhooks_events_desc' => 'このWebhookの呼び出しをトリガーするすべてのイベントを選択します。', + 'webhooks_events_warning' => 'これらのイベントはカスタム権限が適用されている場合でも、選択したすべてのイベントに対してトリガーされることに注意してください。このWebhookの利用により機密コンテンツが公開されないことを確認してください。', + 'webhooks_events_all' => '全てのシステムイベント', + 'webhooks_name' => 'Webhook名', + 'webhooks_timeout' => 'Webhookリクエストタイムアウト (秒)', + 'webhooks_endpoint' => 'Webhookエンドポイント', 'webhooks_active' => 'Webhook Active', 'webhook_events_table_header' => 'Events', 'webhooks_delete' => 'Delete Webhook', 'webhooks_delete_warning' => 'This will fully delete this webhook, with the name \':webhookName\', from the system.', 'webhooks_delete_confirm' => 'Are you sure you want to delete this webhook?', - 'webhooks_format_example' => 'Webhook Format Example', - 'webhooks_format_example_desc' => 'Webhook data is sent as a POST request to the configured endpoint as JSON following the format below. The "related_item" and "url" properties are optional and will depend on the type of event triggered.', + 'webhooks_format_example' => 'Webhookのフォーマット例', + 'webhooks_format_example_desc' => 'Webhookのデータは、設定されたエンドポイントにPOSTリクエストにより以下のフォーマットのJSONで送信されます。related_item と url プロパティはオプションであり、トリガーされるイベントの種類によって異なります。', 'webhooks_status' => 'Webhook Status', 'webhooks_last_called' => 'Last Called:', 'webhooks_last_errored' => 'Last Errored:', diff --git a/resources/lang/pt_BR/activities.php b/resources/lang/pt_BR/activities.php index b24446622..f6fa8e415 100644 --- a/resources/lang/pt_BR/activities.php +++ b/resources/lang/pt_BR/activities.php @@ -7,57 +7,57 @@ return [ // Pages 'page_create' => 'criou a página', - 'page_create_notification' => 'Page successfully created', + 'page_create_notification' => 'Página criada com sucesso', 'page_update' => 'atualizou a página', - 'page_update_notification' => 'Page successfully updated', + 'page_update_notification' => 'Página atualizada com sucesso', 'page_delete' => 'excluiu a página', - 'page_delete_notification' => 'Page successfully deleted', + 'page_delete_notification' => 'Página excluída com sucesso', 'page_restore' => 'restaurou a página', - 'page_restore_notification' => 'Page successfully restored', + 'page_restore_notification' => 'Página restaurada com sucesso', 'page_move' => 'moveu a página', // Chapters 'chapter_create' => 'criou o capítulo', - 'chapter_create_notification' => 'Chapter successfully created', + 'chapter_create_notification' => 'Capítulo criado com sucesso', 'chapter_update' => 'atualizou o capítulo', - 'chapter_update_notification' => 'Chapter successfully updated', + 'chapter_update_notification' => 'Capítulo atualizado com sucesso', 'chapter_delete' => 'excluiu o capítulo', - 'chapter_delete_notification' => 'Chapter successfully deleted', + 'chapter_delete_notification' => 'Capítulo excluída com sucesso', 'chapter_move' => 'moveu o capítulo', // Books 'book_create' => 'criou o livro', - 'book_create_notification' => 'Book successfully created', + 'book_create_notification' => 'Livro criado com sucesso', 'book_update' => 'atualizou o livro', - 'book_update_notification' => 'Book successfully updated', + 'book_update_notification' => 'Livro atualizado com sucesso', 'book_delete' => 'excluiu o livro', - 'book_delete_notification' => 'Book successfully deleted', + 'book_delete_notification' => 'Livro excluído com sucesso', 'book_sort' => 'ordenou o livro', - 'book_sort_notification' => 'Book successfully re-sorted', + 'book_sort_notification' => 'Livro reordenado com sucesso', // Bookshelves - 'bookshelf_create' => 'created bookshelf', - 'bookshelf_create_notification' => 'Bookshelf successfully created', + 'bookshelf_create' => 'prateleira criada', + 'bookshelf_create_notification' => 'Prateleira criada com sucesso', 'bookshelf_update' => 'atualizou a prateleira', - 'bookshelf_update_notification' => 'Bookshelf successfully updated', + 'bookshelf_update_notification' => 'Prateleira atualizada com sucesso', 'bookshelf_delete' => 'excluiu a prateleira', - 'bookshelf_delete_notification' => 'Bookshelf successfully deleted', + 'bookshelf_delete_notification' => 'Prateleira excluída com sucesso', // Favourites - 'favourite_add_notification' => '":name" has been added to your favourites', - 'favourite_remove_notification' => '":name" has been removed from your favourites', + 'favourite_add_notification' => '":name" foi adicionada aos seus favoritos', + 'favourite_remove_notification' => '":name" foi removida dos seus favoritos', // MFA - 'mfa_setup_method_notification' => 'Multi-factor method successfully configured', - 'mfa_remove_method_notification' => 'Multi-factor method successfully removed', + 'mfa_setup_method_notification' => 'Método de multi-fatores configurado com sucesso', + 'mfa_remove_method_notification' => 'Método de multi-fatores removido com sucesso', // Webhooks - 'webhook_create' => 'created webhook', - 'webhook_create_notification' => 'Webhook successfully created', - 'webhook_update' => 'updated webhook', - 'webhook_update_notification' => 'Webhook successfully updated', - 'webhook_delete' => 'deleted webhook', - 'webhook_delete_notification' => 'Webhook successfully deleted', + 'webhook_create' => 'webhook criado', + 'webhook_create_notification' => 'Webhook criado com sucesso', + 'webhook_update' => 'webhook atualizado', + 'webhook_update_notification' => 'Webhook atualizado com sucesso', + 'webhook_delete' => 'webhook excluído', + 'webhook_delete_notification' => 'Webhook excluido com sucesso', // Other 'commented_on' => 'comentou em', diff --git a/resources/lang/pt_BR/common.php b/resources/lang/pt_BR/common.php index 00d0ca844..fd2e4235f 100644 --- a/resources/lang/pt_BR/common.php +++ b/resources/lang/pt_BR/common.php @@ -39,14 +39,14 @@ return [ 'reset' => 'Redefinir', 'remove' => 'Remover', 'add' => 'Adicionar', - 'configure' => 'Configure', + 'configure' => 'Configurar', 'fullscreen' => 'Tela cheia', 'favourite' => 'Favoritos', 'unfavourite' => 'Remover dos Favoritos', 'next' => 'Seguinte', 'previous' => 'Anterior', - 'filter_active' => 'Active Filter:', - 'filter_clear' => 'Clear Filter', + 'filter_active' => 'Filtro Ativo:', + 'filter_clear' => 'Limpar Filtro', // Sort Options 'sort_options' => 'Opções de Ordenação', @@ -72,12 +72,12 @@ return [ 'default' => 'Padrão', 'breadcrumb' => 'Caminho', 'status' => 'Status', - 'status_active' => 'Active', - 'status_inactive' => 'Inactive', - 'never' => 'Never', + 'status_active' => 'Ativo', + 'status_inactive' => 'Inativo', + 'never' => 'Nunca', // Header - 'header_menu_expand' => 'Expand Header Menu', + 'header_menu_expand' => 'Expandir Cabeçalho do Menu', 'profile_menu' => 'Menu de Perfil', 'view_profile' => 'Visualizar Perfil', 'edit_profile' => 'Editar Perfil', @@ -86,9 +86,9 @@ return [ // Layout tabs 'tab_info' => 'Informações', - 'tab_info_label' => 'Tab: Show Secondary Information', + 'tab_info_label' => 'Aba: Mostrar Informação Secundária', 'tab_content' => 'Conteúdo', - 'tab_content_label' => 'Tab: Show Primary Content', + 'tab_content_label' => 'Aba: Mostrar Conteúdo Primário', // Email Content 'email_action_help' => 'Se você estiver tendo problemas ao clicar o botão ":actionText", copie e cole a URL abaixo no seu navegador:', diff --git a/resources/lang/zh_CN/common.php b/resources/lang/zh_CN/common.php index 5edb74d25..412ecb062 100644 --- a/resources/lang/zh_CN/common.php +++ b/resources/lang/zh_CN/common.php @@ -74,7 +74,7 @@ return [ 'status' => '状态', 'status_active' => '已激活', 'status_inactive' => '未激活', - 'never' => '永不', + 'never' => '从未', // Header 'header_menu_expand' => '展开标头菜单', diff --git a/resources/lang/zh_CN/settings.php b/resources/lang/zh_CN/settings.php index 85b7094b9..064b16650 100755 --- a/resources/lang/zh_CN/settings.php +++ b/resources/lang/zh_CN/settings.php @@ -236,7 +236,7 @@ return [ // Webhooks 'webhooks' => 'Webhooks', 'webhooks_create' => '新建 Webhook', - 'webhooks_none_created' => '不存在已创建的 webhooks', + 'webhooks_none_created' => '尚未创建任何 webhook', 'webhooks_edit' => '编辑 Webhook', 'webhooks_save' => '保存 Webhook', 'webhooks_details' => 'Webhook 详情', diff --git a/resources/views/pages/parts/image-manager-form.blade.php b/resources/views/pages/parts/image-manager-form.blade.php index 6d6255226..81041fcac 100644 --- a/resources/views/pages/parts/image-manager-form.blade.php +++ b/resources/views/pages/parts/image-manager-form.blade.php @@ -8,7 +8,7 @@
- {{ $image->name }} diff --git a/tests/HomepageTest.php b/tests/HomepageTest.php index dc1b22779..900650a70 100644 --- a/tests/HomepageTest.php +++ b/tests/HomepageTest.php @@ -79,6 +79,24 @@ class HomepageTest extends TestCase $pageDeleteReq->assertSessionMissing('error'); } + public function test_custom_homepage_cannot_be_deleted_from_parent_deletion() + { + /** @var Page $page */ + $page = Page::query()->first(); + $this->setSettings([ + 'app-homepage' => $page->id, + 'app-homepage-type' => 'page', + ]); + + $this->asEditor()->delete($page->book->getUrl()); + $this->assertSessionError('Cannot delete a page while it is set as a homepage'); + $this->assertDatabaseMissing('deletions', ['deletable_id' => $page->book->id]); + + $page->refresh(); + $this->assertNull($page->deleted_at); + $this->assertNull($page->book->deleted_at); + } + public function test_custom_homepage_renders_includes() { $this->asEditor();