Compare commits

...

16 Commits

Author SHA1 Message Date
Dan Brown
0a22af7b14 Updated version for release v0.31.6 2021-02-06 14:41:19 +00:00
Dan Brown
b54702ab08 Merge branch 'v0.31.x' into release 2021-02-06 14:40:47 +00:00
Dan Brown
a7e3c26fe3 Fixed markdown content on revision restore
Closes #2496
2021-02-06 14:14:38 +00:00
Dan Brown
37de4e2e0a Added test for markdown page revision restore
Also added md change detection in revision saving.
2021-02-06 13:51:05 +00:00
Dan Brown
61a911dd39 Removed "isA" usages from trashcan 2021-02-06 13:29:39 +00:00
Aleksandr Sazhin
cc5d0ef4cf Update TrashCan.php
bookshelf
2021-02-06 13:23:12 +00:00
Dan Brown
7843d8f054 Added recycle-bin test to cover type deletions 2021-02-06 13:22:31 +00:00
Dan Brown
c4fdcfc5d1 Updated version for release v0.31.5 2021-02-02 20:58:06 +00:00
Dan Brown
cb8117e8df Merge branch 'v0.31.x' into release 2021-02-02 20:57:41 +00:00
Dan Brown
d547ed4a6b Updated laravel/framework to latest 6.x version 2021-02-02 20:56:19 +00:00
Dan Brown
5a218d5056 Updated version and assets for release v0.31.4 2021-01-16 17:50:45 +00:00
Dan Brown
8dbc5cf9c6 Merge branch 'master' into release 2021-01-16 17:50:11 +00:00
Dan Brown
d33f136660 Updated translator attribution before release v0.31.4 2021-01-16 17:49:56 +00:00
Dan Brown
173dad345e New Crowdin updates (#2482)
* New translations entities.php (Chinese Traditional)

* New translations settings.php (Chinese Traditional)

* New translations activities.php (Chinese Traditional)

* New translations settings.php (Chinese Traditional)
2021-01-16 17:45:59 +00:00
Dan Brown
47b0eb6324 Updated framework and other php deps 2021-01-16 17:45:04 +00:00
Dan Brown
c35c37008d Added imagetools plugin back in
For #2493
2021-01-16 17:39:30 +00:00
13 changed files with 399 additions and 334 deletions

View File

@@ -133,3 +133,4 @@ MatthieuParis :: French
Douradinho :: Portuguese, Brazilian
Gaku Yaguchi (tama11) :: Japanese
johnroyer :: Chinese Traditional
jackaaa :: Chinese Traditional

View File

@@ -177,17 +177,13 @@ class PageRepo
// Hold the old details to compare later
$oldHtml = $page->html;
$oldName = $page->name;
$oldMarkdown = $page->markdown;
$this->updateTemplateStatusAndContentFromInput($page, $input);
$this->baseRepo->update($page, $input);
// Update with new details
$page->revision_count++;
if (setting('app-editor') !== 'markdown') {
$page->markdown = '';
}
$page->save();
// Remove all update drafts for this user & page.
@@ -195,7 +191,10 @@ class PageRepo
// Save a revision after updating
$summary = $input['summary'] ?? null;
if ($oldHtml !== $input['html'] || $oldName !== $input['name'] || $summary !== null) {
$htmlChanged = isset($input['html']) && $input['html'] !== $oldHtml;
$nameChanged = isset($input['name']) && $input['name'] !== $oldName;
$markdownChanged = isset($input['markdown']) && $input['markdown'] !== $oldMarkdown;
if ($htmlChanged || $nameChanged || $markdownChanged || $summary !== null) {
$this->savePageRevision($page, $summary);
}
@@ -224,10 +223,6 @@ class PageRepo
{
$revision = new PageRevision($page->getAttributes());
if (setting('app-editor') !== 'markdown') {
$revision->markdown = '';
}
$revision->page_id = $page->id;
$revision->slug = $page->slug;
$revision->book_slug = $page->book->slug;
@@ -290,7 +285,13 @@ class PageRepo
$page->fill($revision->toArray());
$content = new PageContent($page);
$content->setNewHTML($revision->html);
if (!empty($revision->markdown)) {
$content->setNewMarkdown($revision->markdown);
} else {
$content->setNewHTML($revision->html);
}
$page->updated_by = user()->id;
$page->refreshSlug();
$page->save();

View File

@@ -273,11 +273,11 @@ class TrashCan
$count++;
};
if ($entity->isA('chapter') || $entity->isA('book')) {
if ($entity instanceof Chapter || $entity instanceof Book) {
$entity->pages()->withTrashed()->withCount('deletions')->get()->each($restoreAction);
}
if ($entity->isA('book')) {
if ($entity instanceof Book) {
$entity->chapters()->withTrashed()->withCount('deletions')->get()->each($restoreAction);
}
@@ -286,19 +286,20 @@ class TrashCan
/**
* Destroy the given entity.
* @throws Exception
*/
protected function destroyEntity(Entity $entity): int
{
if ($entity->isA('page')) {
if ($entity instanceof Page) {
return $this->destroyPage($entity);
}
if ($entity->isA('chapter')) {
if ($entity instanceof Chapter) {
return $this->destroyChapter($entity);
}
if ($entity->isA('book')) {
if ($entity instanceof Book) {
return $this->destroyBook($entity);
}
if ($entity->isA('shelf')) {
if ($entity instanceof Bookshelf) {
return $this->destroyShelf($entity);
}
}

View File

@@ -18,7 +18,7 @@
"facade/ignition": "^1.16.4",
"fideloper/proxy": "^4.4.1",
"intervention/image": "^2.5.1",
"laravel/framework": "^6.20",
"laravel/framework": "^6.20.16",
"laravel/socialite": "^5.1",
"league/commonmark": "^1.5",
"league/flysystem-aws-s3-v3": "^1.0.29",

618
composer.lock generated

File diff suppressed because it is too large Load Diff

2
public/dist/app.js vendored

File diff suppressed because one or more lines are too long

View File

@@ -422,7 +422,7 @@ class WysiwygEditor {
this.imageUploadErrorText = this.$opts.imageUploadErrorText;
this.isDarkMode = document.documentElement.classList.contains('dark-mode');
this.plugins = "image table textcolor paste link autolink fullscreen code customhr autosave lists codeeditor media";
this.plugins = "image imagetools table textcolor paste link autolink fullscreen code customhr autosave lists codeeditor media";
this.loadPlugins();
this.tinyMceConfig = this.getTinyMceConfig();

View File

@@ -45,5 +45,5 @@ return [
// Other
'commented_on' => '評論',
'permissions_update' => 'updated permissions',
'permissions_update' => '更新權限',
];

View File

@@ -268,7 +268,7 @@ return [
'attachments_link_url' => '連結到檔案',
'attachments_link_url_hint' => '網站或檔案的網址',
'attach' => '附加',
'attachments_insert_link' => 'Add Attachment Link to Page',
'attachments_insert_link' => '將附件連結增加到頁面',
'attachments_edit_file' => '編輯檔案',
'attachments_edit_file_name' => '檔案名稱',
'attachments_edit_drop_upload' => '刪除檔案或點選這裡上傳並覆蓋',

View File

@@ -68,7 +68,7 @@ return [
'maint' => '維護',
'maint_image_cleanup' => '清理圖像',
'maint_image_cleanup_desc' => "掃描頁面和修訂內容以檢查哪些圖像是正在使用的以及哪些圖像是多余的。確保在運行前創建完整的數據庫和映像備份。",
'maint_delete_images_only_in_revisions' => 'Also delete images that only exist in old page revisions',
'maint_delete_images_only_in_revisions' => '包含刪除僅在舊頁面修訂版中存在的圖像',
'maint_image_cleanup_run' => '運行清理',
'maint_image_cleanup_warning' => '發現了:count 張可能未使用的圖像。您確定要刪除這些圖像嗎?',
'maint_image_cleanup_success' => '找到並刪除了:count 張可能未使用的圖像!',
@@ -80,11 +80,11 @@ return [
'maint_send_test_email_mail_subject' => '測試郵件',
'maint_send_test_email_mail_greeting' => '電子郵件傳遞似乎有效!',
'maint_send_test_email_mail_text' => '恭喜你! 收到此電子郵件通知時,您的電子郵件設置已經認證成功。',
'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_desc' => '刪除的書架,書籍,章節和頁面將發送到回收站,以便可以還原或永久刪除它們。 回收站中的較舊項目可能會在一段時間後自動刪除,具體取決於系統配置。',
'maint_recycle_bin_open' => 'Open Recycle Bin',
// Recycle Bin
'recycle_bin' => 'Recycle Bin',
'recycle_bin' => '資源回收筒',
'recycle_bin_desc' => 'Here you can restore items that have been deleted or choose to permanently remove them from the system. This list is unfiltered unlike similar activity lists in the system where permission filters are applied.',
'recycle_bin_deleted_item' => 'Deleted Item',
'recycle_bin_deleted_by' => 'Deleted By',
@@ -103,16 +103,16 @@ return [
'recycle_bin_restore_notification' => 'Restored :count total items from the recycle bin.',
// Audit Log
'audit' => 'Audit Log',
'audit' => '稽核記錄',
'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_user' => '使用者',
'audit_table_event' => '活動',
'audit_table_related' => 'Related Item or Detail',
'audit_table_date' => 'Activity Date',
'audit_table_date' => '最後活動日期',
'audit_date_from' => 'Date Range From',
'audit_date_to' => 'Date Range To',
@@ -157,7 +157,7 @@ return [
'user_profile' => '使用者資料',
'users_add_new' => '加入使用者',
'users_search' => '搜尋使用者',
'users_latest_activity' => 'Latest Activity',
'users_latest_activity' => '最新活動',
'users_details' => '用戶詳情',
'users_details_desc' => '請設置用戶的顯示名稱和電子郵件地址, 該電子郵件地址將用於登錄該應用。',
'users_details_desc_no_email' => '設置一個用戶的顯示名稱,以便其他人可以認出你。',
@@ -177,7 +177,7 @@ return [
'users_delete_confirm' => '您確定要刪除這個使用者?',
'users_migrate_ownership' => 'Migrate Ownership',
'users_migrate_ownership_desc' => 'Select a user here if you want another user to become the owner of all items currently owned by this user.',
'users_none_selected' => 'No user selected',
'users_none_selected' => '沒有選定的使用者',
'users_delete_success' => 'User successfully removed',
'users_edit' => '編輯使用者',
'users_edit_profile' => '編輯資料',

View File

@@ -66,6 +66,36 @@ class PageRevisionTest extends TestCase
$pageView->assertSee('def456');
}
public function test_page_revision_restore_with_markdown_retains_markdown_content()
{
$this->asEditor();
$pageRepo = app(PageRepo::class);
$page = Page::first();
$pageRepo->update($page, ['name' => 'updated page abc123', 'markdown' => '## New Content def456', 'summary' => 'initial page revision testing']);
$pageRepo->update($page, ['name' => 'updated page again', 'markdown' => '## New Content Updated', 'summary' => 'page revision testing']);
$page = Page::find($page->id);
$pageView = $this->get($page->getUrl());
$pageView->assertDontSee('abc123');
$pageView->assertDontSee('def456');
$revToRestore = $page->revisions()->where('name', 'like', '%abc123')->first();
$restoreReq = $this->put($page->getUrl() . '/revisions/' . $revToRestore->id . '/restore');
$page = Page::find($page->id);
$restoreReq->assertStatus(302);
$restoreReq->assertRedirect($page->getUrl());
$pageView = $this->get($page->getUrl());
$this->assertDatabaseHas('pages', [
'id' => $page->id,
'markdown' => '## New Content def456',
]);
$pageView->assertSee('abc123');
$pageView->assertSee('def456');
}
public function test_page_revision_restore_sets_new_revision_with_summary()
{
$this->asEditor();

View File

@@ -1,7 +1,10 @@
<?php namespace Tests;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Models\Chapter;
use BookStack\Entities\Models\Deletion;
use BookStack\Entities\Models\Entity;
use BookStack\Entities\Models\Page;
use DB;
use Illuminate\Support\Carbon;
@@ -129,6 +132,21 @@ class RecycleBinTest extends TestCase
$redirectReq->assertNotificationContains('Deleted '.$itemCount.' total items from the recycle bin');
}
public function test_permanent_delete_for_each_type()
{
/** @var Entity $entity */
foreach ([new Bookshelf, new Book, new Chapter, new Page] as $entity) {
$entity = $entity->newQuery()->first();
$this->asEditor()->delete($entity->getUrl());
$deletion = Deletion::query()->orderBy('id', 'desc')->firstOrFail();
$deleteReq = $this->asAdmin()->delete("/settings/recycle-bin/{$deletion->id}");
$deleteReq->assertRedirect('/settings/recycle-bin');
$this->assertDatabaseMissing('deletions', ['id' => $deletion->id]);
$this->assertDatabaseMissing($entity->getTable(), ['id' => $entity->id]);
}
}
public function test_permanent_entity_delete_updates_existing_activity_with_entity_name()
{
$page = Page::query()->firstOrFail();

View File

@@ -1 +1 @@
v0.31.3
v0.31.6