From db51cee2d89f7b5acfc815e93cf04c8d67c6a4b8 Mon Sep 17 00:00:00 2001
From: Dan Brown <ssddanbrown@googlemail.com>
Date: Sun, 15 Oct 2017 19:14:46 +0100
Subject: [PATCH] Prevented custom homepage being deleted

Fixes #546
---
 app/Http/Controllers/PageController.php |  3 ++-
 app/Repos/EntityRepo.php                |  8 ++++++++
 resources/lang/en/errors.php            |  1 +
 tests/HomepageTest.php                  | 25 ++++++++++++++++++++++++-
 4 files changed, 35 insertions(+), 2 deletions(-)

diff --git a/app/Http/Controllers/PageController.php b/app/Http/Controllers/PageController.php
index fd36b3158..c11355db5 100644
--- a/app/Http/Controllers/PageController.php
+++ b/app/Http/Controllers/PageController.php
@@ -324,9 +324,10 @@ class PageController extends Controller
         $page = $this->entityRepo->getBySlug('page', $pageSlug, $bookSlug);
         $book = $page->book;
         $this->checkOwnablePermission('page-delete', $page);
+        $this->entityRepo->destroyPage($page);
+
         Activity::addMessage('page_delete', $book->id, $page->name);
         session()->flash('success', trans('entities.pages_delete_success'));
-        $this->entityRepo->destroyPage($page);
         return redirect($book->getUrl());
     }
 
diff --git a/app/Repos/EntityRepo.php b/app/Repos/EntityRepo.php
index c2899b136..95ae2ed0e 100644
--- a/app/Repos/EntityRepo.php
+++ b/app/Repos/EntityRepo.php
@@ -4,6 +4,7 @@ use BookStack\Book;
 use BookStack\Chapter;
 use BookStack\Entity;
 use BookStack\Exceptions\NotFoundException;
+use BookStack\Exceptions\NotifyException;
 use BookStack\Page;
 use BookStack\PageRevision;
 use BookStack\Services\AttachmentService;
@@ -1073,6 +1074,7 @@ class EntityRepo
     /**
      * Destroy a given page along with its dependencies.
      * @param Page $page
+     * @throws NotifyException
      */
     public function destroyPage(Page $page)
     {
@@ -1084,6 +1086,12 @@ class EntityRepo
         $this->permissionService->deleteJointPermissionsForEntity($page);
         $this->searchService->deleteEntityTerms($page);
 
+        // Check if set as custom homepage
+        $customHome = setting('app-homepage', '0:');
+        if (intval($page->id) === intval(explode(':', $customHome)[0])) {
+            throw new NotifyException(trans('errors.page_custom_home_deletion'), $page->getUrl());
+        }
+
         // Delete Attached Files
         $attachmentService = app(AttachmentService::class);
         foreach ($page->attachments as $attachment) {
diff --git a/resources/lang/en/errors.php b/resources/lang/en/errors.php
index 09158caac..572bec42b 100644
--- a/resources/lang/en/errors.php
+++ b/resources/lang/en/errors.php
@@ -41,6 +41,7 @@ return [
 
     // 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',
diff --git a/tests/HomepageTest.php b/tests/HomepageTest.php
index 7c77e9449..ed0dbe47c 100644
--- a/tests/HomepageTest.php
+++ b/tests/HomepageTest.php
@@ -16,7 +16,8 @@ class HomepageTest extends TestCase
         $homeVisit->assertSee('Recent Activity');
     }
 
-    public function test_custom_homepage() {
+    public function test_custom_homepage()
+    {
         $this->asEditor();
         $name = 'My custom homepage';
         $content = 'This is the body content of my custom homepage.';
@@ -30,4 +31,26 @@ class HomepageTest extends TestCase
         $homeVisit->assertSee('Recently Updated Pages');
         $homeVisit->assertSee('Recent Activity');
     }
+
+    public function test_delete_custom_homepage()
+    {
+        $this->asEditor();
+        $name = 'My custom homepage';
+        $content = 'This is the body content of my custom homepage.';
+        $customPage = $this->newPage(['name' => $name, 'html' => $content]);
+        $this->setSettings(['app-homepage' => $customPage->id]);
+
+        $homeVisit = $this->get('/');
+        $homeVisit->assertSee($name);
+
+        $pageDeleteReq = $this->delete($customPage->getUrl());
+        $pageDeleteReq->assertStatus(302);
+        $pageDeleteReq->assertRedirect($customPage->getUrl());
+        $pageDeleteReq->assertSessionHas('error');
+        $pageDeleteReq->assertSessionMissing('success');
+
+        $homeVisit = $this->get('/');
+        $homeVisit->assertSee($name);
+        $homeVisit->assertStatus(200);
+    }
 }