diff --git a/app/Http/Controllers/Entity/PostController.php b/app/Http/Controllers/Entity/PostController.php index bf3d889ea3..96bba29e50 100644 --- a/app/Http/Controllers/Entity/PostController.php +++ b/app/Http/Controllers/Entity/PostController.php @@ -25,12 +25,20 @@ public function create(Campaign $campaign, Entity $entity, Post $post) { $this->authorize('post', [$entity->child, 'add']); $parentRoute = $entity->pluralType(); + $templates = Post::template()->pluck('name', 'id')->all(); + + $template = request()->input('template'); + if (!empty($template) && $this->authorize('useTemplates', $campaign)) { + $template = Post::template()->where('id', $template)->first(); + } return view('entities.pages.posts.create', compact( 'campaign', 'post', 'entity', 'parentRoute', + 'templates', + 'template', )); } diff --git a/app/Http/Controllers/Entity/Posts/TemplateController.php b/app/Http/Controllers/Entity/Posts/TemplateController.php new file mode 100644 index 0000000000..7fbe14684f --- /dev/null +++ b/app/Http/Controllers/Entity/Posts/TemplateController.php @@ -0,0 +1,38 @@ +middleware('auth'); + $this->service = $templateService; + } + + /** + * @return \Illuminate\Http\RedirectResponse + */ + public function update(Campaign $campaign, Post $post) + { + $this->authorize('template', $post); + $this->service->post($post)->toggle(); + return redirect()->back() + ->with( + 'success', + __('entities/actions.templates.success.' . ($post->is_template ? 'set' : 'unset'), ['name' => $post->name]) + ); + } +} diff --git a/app/Models/CharacterRace.php b/app/Models/CharacterRace.php index 7a50a96b2e..429afd410d 100644 --- a/app/Models/CharacterRace.php +++ b/app/Models/CharacterRace.php @@ -36,6 +36,7 @@ public function character(): BelongsTo { return $this->belongsTo(Character::class); } + public function race(): BelongsTo { return $this->belongsTo(Race::class); diff --git a/app/Models/Post.php b/app/Models/Post.php index 57784c4365..b7811644fc 100644 --- a/app/Models/Post.php +++ b/app/Models/Post.php @@ -33,7 +33,7 @@ * @property string|null $marketplace_uuid * @property bool|int $is_private * @property int $deleted_by - * @property bool|int $is_pinned + * @property bool|int $is_template * @property int $position * @property array $settings * @property Entity|null $entity @@ -69,6 +69,7 @@ class Post extends Model 'settings', 'location_id', 'layout_id', + 'is_template' ]; /** @var string[] Fields that can be used to order by */ @@ -187,14 +188,21 @@ public function getEntryForEditionAttribute() } /** - * @return Builder */ - public function scopeOrdered(Builder $query) + public function scopeOrdered(Builder $query): Builder { return $query ->orderBy('position'); } + /** + */ + public function scopeTemplate(Builder $query): Builder + { + return $query->where('is_template', true); + } + + /** */ public function collapsed(): bool diff --git a/app/Policies/CampaignPolicy.php b/app/Policies/CampaignPolicy.php index 36f705b3c7..2281e4d647 100644 --- a/app/Policies/CampaignPolicy.php +++ b/app/Policies/CampaignPolicy.php @@ -282,7 +282,6 @@ public function galleryUpload(?User $user, Campaign $campaign): bool ); } - /** * @return bool */ @@ -290,4 +289,11 @@ protected function checkPermission(int $action, User $user, Campaign $campaign = { return EntityPermission::hasPermission(0, $action, $user, null, $campaign); } + + /** + */ + public function useTemplates(?User $user, Campaign $campaign): bool + { + return $this->isAdmin($user); + } } diff --git a/app/Policies/PostPolicy.php b/app/Policies/PostPolicy.php new file mode 100644 index 0000000000..0bb5de455b --- /dev/null +++ b/app/Policies/PostPolicy.php @@ -0,0 +1,18 @@ +layout_id && $user && UserCache::user($user)->admin(); + } +} diff --git a/app/Services/Entity/TemplateService.php b/app/Services/Entity/TemplateService.php index 402d2ec725..5d5b6fd668 100644 --- a/app/Services/Entity/TemplateService.php +++ b/app/Services/Entity/TemplateService.php @@ -3,14 +3,21 @@ namespace App\Services\Entity; use App\Traits\EntityAware; +use App\Traits\PostAware; class TemplateService { use EntityAware; + use PostAware; public function toggle(): void { - $this->entity->is_template = !$this->entity->is_template; - $this->entity->save(); + if (isset($this->post)) { + $this->post->is_template = !$this->post->is_template; + $this->post->save(); + } else { + $this->entity->is_template = !$this->entity->is_template; + $this->entity->save(); + } } } diff --git a/app/Traits/PostAware.php b/app/Traits/PostAware.php new file mode 100644 index 0000000000..99f6d93398 --- /dev/null +++ b/app/Traits/PostAware.php @@ -0,0 +1,18 @@ +post = $post; + return $this; + } +} diff --git a/database/migrations/2024_07_02_172619_update_posts_add_is_template.php b/database/migrations/2024_07_02_172619_update_posts_add_is_template.php new file mode 100644 index 0000000000..e068a61fb8 --- /dev/null +++ b/database/migrations/2024_07_02_172619_update_posts_add_is_template.php @@ -0,0 +1,29 @@ +boolean('is_template')->defaultValue(false); + $table->index('is_template'); + }); + } + + /** + * Reverse the migrations. + */ + public function down(): void + { + Schema::table('posts', function (Blueprint $table) { + $table->dropIndex('is_template'); + $table->dropColumn('is_template'); + }); + } +}; diff --git a/lang/en/posts.php b/lang/en/posts.php index c9576d3cd0..79962f6c19 100644 --- a/lang/en/posts.php +++ b/lang/en/posts.php @@ -2,7 +2,10 @@ return [ 'create' => [ - 'title' => 'New Post', + 'title' => 'New Post', + 'template' => [ + 'helper' => 'The campaigns admins have defined the following posts as templates that can be re-used.' + ] ], 'fields' => [ 'name' => 'Name', diff --git a/resources/views/cruds/lists/_create.blade.php b/resources/views/cruds/lists/_create.blade.php index 064bf22bfe..8a0bb2a937 100644 --- a/resources/views/cruds/lists/_create.blade.php +++ b/resources/views/cruds/lists/_create.blade.php @@ -10,7 +10,7 @@ {{ __('crud.actions.actions') }}
@include('entities.pages.posts._save-options') @@ -99,8 +106,8 @@ class="html-editor" - @includeWhen(auth()->user()->can('permission', $entity->child), 'entities.pages.posts._permissions') + @includeWhen(auth()->user()->isAdmin() && !empty($templates), 'entities.pages.posts._templates') diff --git a/resources/views/entities/pages/posts/_templates.blade.php b/resources/views/entities/pages/posts/_templates.blade.php new file mode 100644 index 0000000000..4b9b5fd834 --- /dev/null +++ b/resources/views/entities/pages/posts/_templates.blade.php @@ -0,0 +1,16 @@ +