Skip to content

Commit 06ec914

Browse files
committed
Entities: Changed from *Data to a common "contents" system
Added smart loading from builder instances which should hydrate with "contents()" loaded via join, while keeping the core model original.
1 parent 5c2908e commit 06ec914

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

49 files changed

+302
-156
lines changed

app/Entities/Controllers/BookApiController.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,8 +124,8 @@ protected function forJsonDisplay(Book $book): Book
124124

125125
$book->load(['tags']);
126126
$book->makeVisible(['cover', 'description_html'])
127-
->setAttribute('description_html', $book->containerData->getDescriptionHtml())
128-
->setAttribute('cover', $book->containerData->cover);
127+
->setAttribute('description_html', $book->contents()->getDescriptionHtml())
128+
->setAttribute('cover', $book->contents()->cover);
129129

130130
return $book;
131131
}

app/Entities/Controllers/BookshelfApiController.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,8 +118,8 @@ protected function forJsonDisplay(Bookshelf $shelf): Bookshelf
118118

119119
$shelf->load(['tags']);
120120
$shelf->makeVisible(['cover', 'description_html'])
121-
->setAttribute('description_html', $shelf->containerData->getDescriptionHtml())
122-
->setAttribute('cover', $shelf->containerData->cover);
121+
->setAttribute('description_html', $shelf->contents()->getDescriptionHtml())
122+
->setAttribute('cover', $shelf->contents()->cover);
123123

124124
return $shelf;
125125
}

app/Entities/Controllers/ChapterApiController.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -144,7 +144,7 @@ protected function forJsonDisplay(Chapter $chapter): Chapter
144144

145145
$chapter->load(['tags']);
146146
$chapter->makeVisible('description_html');
147-
$chapter->setAttribute('description_html', $chapter->containerData->getDescriptionHtml());
147+
$chapter->setAttribute('description_html', $chapter->contents()->getDescriptionHtml());
148148

149149
/** @var Book $book */
150150
$book = $chapter->book()->first();

app/Entities/Models/Book.php

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,11 +4,10 @@
44

55
use BookStack\Sorting\SortRule;
66
use BookStack\Uploads\Image;
7-
use Exception;
87
use Illuminate\Database\Eloquent\Factories\HasFactory;
9-
use Illuminate\Database\Eloquent\Relations\BelongsTo;
108
use Illuminate\Database\Eloquent\Relations\BelongsToMany;
119
use Illuminate\Database\Eloquent\Relations\HasMany;
10+
use Illuminate\Database\Eloquent\Relations\HasOne;
1211
use Illuminate\Support\Collection;
1312

1413
/**
@@ -29,6 +28,7 @@
2928
class Book extends Entity
3029
{
3130
use HasFactory;
31+
use ContainerTrait;
3232

3333
public float $searchFactor = 1.2;
3434

@@ -47,7 +47,7 @@ public function getUrl(string $path = ''): string
4747
*/
4848
public function getCover(int $width = 440, int $height = 250): string
4949
{
50-
return $this->containerData->getCoverUrl($width, $height);
50+
return $this->contents()->getCoverUrl($width, $height);
5151
}
5252

5353
/**

app/Entities/Models/Bookshelf.php

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
class Bookshelf extends Entity
99
{
1010
use HasFactory;
11+
use ContainerTrait;
1112

1213
public float $searchFactor = 1.2;
1314

app/Entities/Models/Chapter.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,6 @@
22

33
namespace BookStack\Entities\Models;
44

5-
use Illuminate\Database\Eloquent\Relations\BelongsTo;
65
use Illuminate\Database\Eloquent\Factories\HasFactory;
76
use Illuminate\Database\Eloquent\Relations\HasMany;
87
use Illuminate\Support\Collection;
@@ -15,6 +14,7 @@
1514
class Chapter extends BookChild
1615
{
1716
use HasFactory;
17+
use ContainerTrait;
1818

1919
public float $searchFactor = 1.2;
2020
protected $hidden = ['pivot', 'deleted_at', 'description_html'];
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
<?php
2+
3+
namespace BookStack\Entities\Models;
4+
5+
use Illuminate\Database\Eloquent\Relations\HasOne;
6+
7+
/**
8+
* @mixin Entity
9+
*/
10+
trait ContainerTrait
11+
{
12+
/**
13+
* @return HasOne<EntityContainerContents, $this>
14+
*/
15+
public function relatedData(): HasOne
16+
{
17+
return $this->hasOne(EntityContainerContents::class, 'entity_id', 'id')
18+
->where('entity_type', '=', $this->getMorphClass());
19+
}
20+
21+
public function contents(): EntityContainerContents
22+
{
23+
$data = parent::contents();
24+
if ($data instanceof EntityContainerContents) {
25+
return $data;
26+
}
27+
28+
/** @var EntityContainerContents $data */
29+
$data = $this->relatedData()->newModelInstance();
30+
$data->setRawAttributes([
31+
'entity_id' => $this->id,
32+
'entity_type' => $this->getMorphClass(),
33+
'description' => '',
34+
'description_html' => '',
35+
'default_template_id' => null,
36+
'image_id' => null,
37+
'sort_rule_id' => null,
38+
]);
39+
40+
return $data;
41+
}
42+
}

app/Entities/Models/Entity.php

Lines changed: 58 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@
3434

3535
/**
3636
* Class Entity
37-
* The base class for book-like items such as pages, chapters & books.
37+
* The base class for book-like items such as pages, chapters and books.
3838
* This is not a database model in itself but extended.
3939
*
4040
* @property int $id
@@ -49,8 +49,6 @@
4949
* @property int $owned_by
5050
* @property Collection $tags
5151
*
52-
* @property ?EntityContainerData $containerData
53-
*
5452
* @method static Entity|Builder visible()
5553
* @method static Builder withLastView()
5654
* @method static Builder withViewCount()
@@ -87,27 +85,48 @@ abstract class Entity extends Model implements
8785
protected $table = 'entities';
8886

8987
/**
90-
* Set global scopes to limit queries down to just the right type of entity.
88+
* Set a custom query builder for entities.
9189
*/
92-
protected static function booted(): void
93-
{
94-
static::addGlobalScope('entity', new EntityScope());
95-
}
90+
protected static string $builder = EntityQueryBuilder::class;
91+
92+
protected static array $commonFields = [
93+
'id',
94+
'type',
95+
'name',
96+
'slug',
97+
'book_id',
98+
'priority',
99+
'created_at',
100+
'updated_at',
101+
'deleted_at',
102+
'created_by',
103+
'updated_by',
104+
'owned_by',
105+
];
96106

97-
public function shouldHaveContainerData(): bool
107+
public function newFromBuilder($attributes = [], $connection = null): static
98108
{
99-
return $this instanceof Bookshelf ||
100-
$this instanceof Book ||
101-
$this instanceof Chapter;
109+
$entityFields = array_intersect_key($attributes, array_flip(static::$commonFields));
110+
$extraFields = array_diff_key($attributes, $entityFields);
111+
112+
$instance = parent::newFromBuilder($entityFields, $connection);
113+
$data = $instance->relatedData()->newModelInstance()->newFromBuilder($extraFields, $connection);
114+
115+
$instance->setRelation('contents', $data);
116+
117+
return $instance;
102118
}
103119

120+
// TODO - Move attribute usage to `->contents()->attr` calls
121+
104122
/**
105-
* Get the container-specific data for this item.
123+
* Check if this item is a container item.
106124
*/
107-
public function containerData(): HasOne
125+
public function isContainer(): bool
108126
{
109-
return $this->hasOne(EntityContainerData::class, 'id', 'entity_id')
110-
->where('entity_type', '=', $this->getMorphClass());
127+
return $this instanceof Bookshelf ||
128+
$this instanceof Book ||
129+
$this instanceof Chapter;
111130
}
112131

113132
/**
@@ -168,7 +187,7 @@ public function matchesOrContains(self $entity): bool
168187
}
169188

170189
if ($entity instanceof Page && $this instanceof Chapter) {
171-
return $entity->chapter_id === $this->id;
190+
return $entity->contents()->chapter_id === $this->id;
172191
}
173192

174193
return false;
@@ -412,4 +431,26 @@ public function logDescriptor(): string
412431
{
413432
return "({$this->id}) {$this->name}";
414433
}
434+
435+
/**
436+
* @return HasOne<EntityContainerContents|EntityPageContents, $this>
437+
*/
438+
abstract public function relatedData(): HasOne;
439+
440+
/**
441+
* Get the contents of this entity.
442+
*/
443+
public function contents(): EntityContainerContents|EntityPageContents|null
444+
{
445+
if ($this->relationLoaded('contents')) {
446+
return $this->getRelation('contents');
447+
}
448+
449+
$relatedData = $this->relatedData()->first();
450+
if ($relatedData) {
451+
return $relatedData;
452+
}
453+
454+
return null;
455+
}
415456
}

app/Entities/Models/EntityContainerData.php renamed to app/Entities/Models/EntityContainerContents.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
* @property ?int $image_id
1818
* @property ?int $sort_rule_id
1919
*/
20-
class EntityContainerData extends Model
20+
class EntityContainerContents extends Model
2121
{
2222
public $timestamps = false;
2323

app/Entities/Models/EntityPageData.php renamed to app/Entities/Models/EntityPageContents.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use Illuminate\Database\Eloquent\Model;
66

7-
class EntityPageData extends Model
7+
class EntityPageContents extends Model
88
{
99
public $timestamps = false;
1010
}

0 commit comments

Comments
 (0)