0
0
Fork 0
mirror of https://github.com/BookStackApp/BookStack.git synced 2025-05-01 06:59:52 +00:00

Started refactoring of view service

Phasing out the view service from being a generic 'service' class,
moving the core create/delete methods into the model.
The idea is that the existing query work will need to interlink
with the favourite system so maybe we have a (or many composable)
query building classes rather than mixing query building and
create/delete work as per the old service.
This commit is contained in:
Dan Brown 2021-05-16 10:49:37 +01:00
parent 3ca149137e
commit 93fd869ba3
No known key found for this signature in database
GPG key ID: 46D9F943C24A2EF9
9 changed files with 62 additions and 42 deletions

View file

@ -1,8 +1,19 @@
<?php namespace BookStack\Actions; <?php namespace BookStack\Actions;
use BookStack\Interfaces\Viewable;
use BookStack\Model; use BookStack\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo; use Illuminate\Database\Eloquent\Relations\MorphTo;
/**
* Class View
* Views are stored per-item per-person within the database.
* They can be used to find popular items or recently viewed items
* at a per-person level. They do not record every view instance as an
* activity. Only the latest and original view times could be recognised.
*
* @property int $views
* @property int $user_id
*/
class View extends Model class View extends Model
{ {
@ -15,4 +26,32 @@ class View extends Model
{ {
return $this->morphTo(); return $this->morphTo();
} }
/**
* Increment the current user's view count for the given viewable model.
*/
public static function incrementFor(Viewable $viewable): int
{
$user = user();
if (is_null($user) || $user->isDefault()) {
return 0;
}
/** @var View $view */
$view = $viewable->views()->firstOrNew([
'user_id' => $user->id,
], ['views' => 0]);
$view->save(['views' => $view->views + 1]);
return $view->views;
}
/**
* Clear all views from the system.
*/
public static function clearAll()
{
static::query()->truncate();
}
} }

View file

@ -1,7 +1,6 @@
<?php namespace BookStack\Actions; <?php namespace BookStack\Actions;
use BookStack\Auth\Permissions\PermissionService; use BookStack\Auth\Permissions\PermissionService;
use BookStack\Entities\Models\Book;
use BookStack\Entities\Models\Entity; use BookStack\Entities\Models\Entity;
use BookStack\Entities\EntityProvider; use BookStack\Entities\EntityProvider;
use DB; use DB;
@ -26,33 +25,6 @@ class ViewService
$this->entityProvider = $entityProvider; $this->entityProvider = $entityProvider;
} }
/**
* Add a view to the given entity.
* @param \BookStack\Entities\Models\Entity $entity
* @return int
*/
public function add(Entity $entity)
{
$user = user();
if ($user === null || $user->isDefault()) {
return 0;
}
$view = $entity->views()->where('user_id', '=', $user->id)->first();
// Add view if model exists
if ($view) {
$view->increment('views');
return $view->views;
}
// Otherwise create new view count
$entity->views()->save($this->view->newInstance([
'user_id' => $user->id,
'views' => 1
]));
return 1;
}
/** /**
* Get the entities with the most views. * Get the entities with the most views.
* @param int $count * @param int $count
@ -106,12 +78,4 @@ class ViewService
return $all->sortByDesc('last_viewed_at')->slice(0, $count); return $all->sortByDesc('last_viewed_at')->slice(0, $count);
} }
/**
* Reset all view counts by deleting all views.
*/
public function resetAll()
{
$this->view->truncate();
}
} }

View file

@ -2,6 +2,7 @@
namespace BookStack\Console\Commands; namespace BookStack\Console\Commands;
use BookStack\Actions\View;
use Illuminate\Console\Command; use Illuminate\Console\Command;
class ClearViews extends Command class ClearViews extends Command
@ -36,7 +37,7 @@ class ClearViews extends Command
*/ */
public function handle() public function handle()
{ {
\Views::resetAll(); View::clearAll();
$this->comment('Views cleared'); $this->comment('Views cleared');
} }
} }

View file

@ -12,6 +12,7 @@ use BookStack\Entities\Tools\SlugGenerator;
use BookStack\Facades\Permissions; use BookStack\Facades\Permissions;
use BookStack\Interfaces\Favouritable; use BookStack\Interfaces\Favouritable;
use BookStack\Interfaces\Sluggable; use BookStack\Interfaces\Sluggable;
use BookStack\Interfaces\Viewable;
use BookStack\Model; use BookStack\Model;
use BookStack\Traits\HasCreatorAndUpdater; use BookStack\Traits\HasCreatorAndUpdater;
use BookStack\Traits\HasOwner; use BookStack\Traits\HasOwner;
@ -40,7 +41,7 @@ use Illuminate\Database\Eloquent\SoftDeletes;
* @method static Builder withLastView() * @method static Builder withLastView()
* @method static Builder withViewCount() * @method static Builder withViewCount()
*/ */
abstract class Entity extends Model implements Sluggable, Favouritable abstract class Entity extends Model implements Sluggable, Favouritable, Viewable
{ {
use SoftDeletes; use SoftDeletes;
use HasCreatorAndUpdater; use HasCreatorAndUpdater;

View file

@ -2,6 +2,7 @@
use Activity; use Activity;
use BookStack\Actions\ActivityType; use BookStack\Actions\ActivityType;
use BookStack\Actions\View;
use BookStack\Entities\Tools\BookContents; use BookStack\Entities\Tools\BookContents;
use BookStack\Entities\Models\Bookshelf; use BookStack\Entities\Models\Bookshelf;
use BookStack\Entities\Tools\PermissionsUpdater; use BookStack\Entities\Tools\PermissionsUpdater;
@ -112,7 +113,7 @@ class BookController extends Controller
$bookChildren = (new BookContents($book))->getTree(true); $bookChildren = (new BookContents($book))->getTree(true);
$bookParentShelves = $book->shelves()->visible()->get(); $bookParentShelves = $book->shelves()->visible()->get();
Views::add($book); View::incrementFor($book);
if ($request->has('shelf')) { if ($request->has('shelf')) {
$this->entityContextManager->setShelfContext(intval($request->get('shelf'))); $this->entityContextManager->setShelfContext(intval($request->get('shelf')));
} }

View file

@ -1,6 +1,7 @@
<?php namespace BookStack\Http\Controllers; <?php namespace BookStack\Http\Controllers;
use Activity; use Activity;
use BookStack\Actions\View;
use BookStack\Entities\Models\Book; use BookStack\Entities\Models\Book;
use BookStack\Entities\Tools\PermissionsUpdater; use BookStack\Entities\Tools\PermissionsUpdater;
use BookStack\Entities\Tools\ShelfContext; use BookStack\Entities\Tools\ShelfContext;
@ -109,7 +110,7 @@ class BookshelfController extends Controller
->values() ->values()
->all(); ->all();
Views::add($shelf); View::incrementFor($shelf);
$this->entityContextManager->setShelfContext($shelf->id); $this->entityContextManager->setShelfContext($shelf->id);
$view = setting()->getForCurrentUser('bookshelf_view_type'); $view = setting()->getForCurrentUser('bookshelf_view_type');

View file

@ -1,5 +1,6 @@
<?php namespace BookStack\Http\Controllers; <?php namespace BookStack\Http\Controllers;
use BookStack\Actions\View;
use BookStack\Entities\Models\Book; use BookStack\Entities\Models\Book;
use BookStack\Entities\Tools\BookContents; use BookStack\Entities\Tools\BookContents;
use BookStack\Entities\Repos\ChapterRepo; use BookStack\Entities\Repos\ChapterRepo;
@ -64,7 +65,7 @@ class ChapterController extends Controller
$sidebarTree = (new BookContents($chapter->book))->getTree(); $sidebarTree = (new BookContents($chapter->book))->getTree();
$pages = $chapter->getVisiblePages(); $pages = $chapter->getVisiblePages();
Views::add($chapter); View::incrementFor($chapter);
$this->setPageTitle($chapter->getShortName()); $this->setPageTitle($chapter->getShortName());
return view('chapters.show', [ return view('chapters.show', [

View file

@ -1,5 +1,6 @@
<?php namespace BookStack\Http\Controllers; <?php namespace BookStack\Http\Controllers;
use BookStack\Actions\View;
use BookStack\Entities\Tools\BookContents; use BookStack\Entities\Tools\BookContents;
use BookStack\Entities\Tools\PageContent; use BookStack\Entities\Tools\PageContent;
use BookStack\Entities\Tools\PageEditActivity; use BookStack\Entities\Tools\PageEditActivity;
@ -141,7 +142,7 @@ class PageController extends Controller
$page->load(['comments.createdBy']); $page->load(['comments.createdBy']);
} }
Views::add($page); View::incrementFor($page);
$this->setPageTitle($page->getShortName()); $this->setPageTitle($page->getShortName());
return view('pages.show', [ return view('pages.show', [
'page' => $page, 'page' => $page,

View file

@ -0,0 +1,11 @@
<?php namespace BookStack\Interfaces;
use Illuminate\Database\Eloquent\Relations\MorphMany;
interface Viewable
{
/**
* Get all view instances for this viewable model.
*/
public function views(): MorphMany;
}