28
common/Pages/ContactPageController.php
Executable file
28
common/Pages/ContactPageController.php
Executable file
@@ -0,0 +1,28 @@
|
||||
<?php namespace Common\Pages;
|
||||
|
||||
use App\Models\User;
|
||||
use Common\Core\BaseController;
|
||||
use Common\Notifications\ContactPageMessage;
|
||||
use Common\Settings\Settings;
|
||||
use Illuminate\Http\Request;
|
||||
|
||||
class ContactPageController extends BaseController
|
||||
{
|
||||
public function sendMessage(Request $request)
|
||||
{
|
||||
if ( ! config('common.site.enable_contact_page')) return abort(404);
|
||||
|
||||
$this->validate($request, [
|
||||
'name' => 'required|string|min:5',
|
||||
'email' => 'required|email',
|
||||
'message' => 'required|string|min:10'
|
||||
]);
|
||||
|
||||
$notification = new ContactPageMessage($request->all());
|
||||
|
||||
(new User())->forceFill([
|
||||
'name' => config('mail.from.name'),
|
||||
'email' => app(Settings::class)->get('mail.contact_page_address', config('mail.from.address')),
|
||||
])->notify($notification);
|
||||
}
|
||||
}
|
||||
23
common/Pages/CrupdatePage.php
Executable file
23
common/Pages/CrupdatePage.php
Executable file
@@ -0,0 +1,23 @@
|
||||
<?php
|
||||
|
||||
namespace Common\Pages;
|
||||
|
||||
use Common\Workspaces\ActiveWorkspace;
|
||||
use Illuminate\Support\Arr;
|
||||
use Illuminate\Support\Facades\Auth;
|
||||
|
||||
class CrupdatePage
|
||||
{
|
||||
public function execute(CustomPage $page, array $data): CustomPage
|
||||
{
|
||||
if (!$page->exists) {
|
||||
$data['user_id'] = Auth::id();
|
||||
$data['slug'] = $data['slug'] ?? slugify(Arr::get($data, 'title'));
|
||||
$data['workspace_id'] = app(ActiveWorkspace::class)->id ?? 0;
|
||||
}
|
||||
|
||||
$page->fill($data)->save();
|
||||
|
||||
return $page;
|
||||
}
|
||||
}
|
||||
93
common/Pages/CustomPage.php
Executable file
93
common/Pages/CustomPage.php
Executable file
@@ -0,0 +1,93 @@
|
||||
<?php namespace Common\Pages;
|
||||
|
||||
use App\Models\User;
|
||||
use Common\Core\BaseModel;
|
||||
use Common\Tags\Tag;
|
||||
use Illuminate\Database\Eloquent\Casts\Attribute;
|
||||
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
||||
use Illuminate\Database\Eloquent\Relations\BelongsTo;
|
||||
use Illuminate\Database\Eloquent\Relations\MorphToMany;
|
||||
use Illuminate\Support\Str;
|
||||
|
||||
class CustomPage extends BaseModel
|
||||
{
|
||||
use HasFactory;
|
||||
|
||||
const PAGE_TYPE = 'default';
|
||||
const MODEL_TYPE = 'customPage';
|
||||
|
||||
protected $guarded = ['id'];
|
||||
|
||||
protected $casts = [
|
||||
'id' => 'integer',
|
||||
'hide_nav' => 'boolean',
|
||||
'meta' => 'json',
|
||||
];
|
||||
|
||||
protected $appends = ['model_type'];
|
||||
|
||||
protected function slug(): Attribute
|
||||
{
|
||||
return Attribute::make(
|
||||
set: fn (string $value) => slugify($value),
|
||||
);
|
||||
}
|
||||
|
||||
public function user(): BelongsTo
|
||||
{
|
||||
return $this->belongsTo(User::class);
|
||||
}
|
||||
|
||||
public function tags(): MorphToMany
|
||||
{
|
||||
return $this->morphToMany(Tag::class, 'taggable');
|
||||
}
|
||||
|
||||
public function toSearchableArray(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'title' => $this->title,
|
||||
'body' => $this->body,
|
||||
'slug' => $this->slug,
|
||||
'type' => $this->type,
|
||||
'created_at' => $this->created_at->timestamp ?? '_null',
|
||||
'updated_at' => $this->updated_at->timestamp ?? '_null',
|
||||
'user_id' => $this->user_id,
|
||||
'workspace_id' => $this->workspace_id ?? '_null',
|
||||
];
|
||||
}
|
||||
|
||||
public function toNormalizedArray(): array
|
||||
{
|
||||
return [
|
||||
'id' => $this->id,
|
||||
'name' => $this->title,
|
||||
'image' => $this->meta['image'] ?? null,
|
||||
'description' => Str::limit($this->body, 100),
|
||||
'model_type' => static::MODEL_TYPE,
|
||||
];
|
||||
}
|
||||
|
||||
public static function filterableFields(): array
|
||||
{
|
||||
return [
|
||||
'id',
|
||||
'user_id',
|
||||
'created_at',
|
||||
'updated_at',
|
||||
'type',
|
||||
'workspace_id',
|
||||
];
|
||||
}
|
||||
|
||||
public static function getModelTypeAttribute(): string
|
||||
{
|
||||
return static::MODEL_TYPE;
|
||||
}
|
||||
|
||||
public static function factory(): CustomPageFactory
|
||||
{
|
||||
return CustomPageFactory::new();
|
||||
}
|
||||
}
|
||||
143
common/Pages/CustomPageController.php
Executable file
143
common/Pages/CustomPageController.php
Executable file
@@ -0,0 +1,143 @@
|
||||
<?php namespace Common\Pages;
|
||||
|
||||
use Auth;
|
||||
use Common\Core\BaseController;
|
||||
use Common\Database\Datasource\Datasource;
|
||||
use Illuminate\Http\Request;
|
||||
use Illuminate\Validation\Rule;
|
||||
use Str;
|
||||
|
||||
class CustomPageController extends BaseController
|
||||
{
|
||||
/**
|
||||
* CustomPage model might get overwritten with
|
||||
* parent page model, for example, LinkPage
|
||||
*/
|
||||
public function __construct(
|
||||
protected CustomPage $page,
|
||||
protected Request $request,
|
||||
) {
|
||||
}
|
||||
|
||||
public function index()
|
||||
{
|
||||
$userId = $this->request->get('userId');
|
||||
$this->authorize('index', [get_class($this->page), $userId]);
|
||||
|
||||
$builder = $this->page->newQuery();
|
||||
|
||||
// make sure we filter by page type on full text engines for
|
||||
// example, only search "link page" on "meilisearch" on "belink"
|
||||
$modelType = $this->page::PAGE_TYPE;
|
||||
$pageType = $this->request->get(
|
||||
'type',
|
||||
$modelType !== 'default' ? $modelType : null,
|
||||
);
|
||||
if ($pageType) {
|
||||
$builder->where('type', '=', $pageType);
|
||||
}
|
||||
|
||||
if ($userId) {
|
||||
$builder->where('user_id', '=', $userId);
|
||||
}
|
||||
|
||||
$pagination = (new Datasource($builder, $this->request->all()))
|
||||
->paginate()
|
||||
->toArray();
|
||||
|
||||
$pagination['data'] = array_map(function ($page) {
|
||||
$page['body'] = Str::limit(strip_tags($page['body']), 100);
|
||||
return $page;
|
||||
}, $pagination['data']);
|
||||
|
||||
return $this->success(['pagination' => $pagination]);
|
||||
}
|
||||
|
||||
public function show(int|string $id)
|
||||
{
|
||||
$page = $this->page
|
||||
->where('slug', $id)
|
||||
->orWhere('id', $id)
|
||||
->firstOrFail();
|
||||
|
||||
$this->authorize('show', $page);
|
||||
|
||||
return $this->renderClientOrApi([
|
||||
'pageName' => 'custom-page',
|
||||
'data' => [
|
||||
'page' => $page,
|
||||
'loader' => 'customPage',
|
||||
],
|
||||
]);
|
||||
}
|
||||
|
||||
public function store()
|
||||
{
|
||||
$this->authorize('store', get_class($this->page));
|
||||
|
||||
$validatedData = $this->validate($this->request, [
|
||||
'title' => [
|
||||
'string',
|
||||
'min:3',
|
||||
'max:250',
|
||||
Rule::unique('custom_pages')->where('user_id', Auth::id()),
|
||||
],
|
||||
'slug' => [
|
||||
'nullable',
|
||||
'string',
|
||||
'min:3',
|
||||
'max:250',
|
||||
Rule::unique('custom_pages'),
|
||||
],
|
||||
'body' => 'required|string|min:1',
|
||||
'meta' => 'nullable|array',
|
||||
]);
|
||||
|
||||
$page = app(CrupdatePage::class)->execute(
|
||||
$this->page->newInstance(),
|
||||
$validatedData,
|
||||
);
|
||||
|
||||
return $this->success(['page' => $page]);
|
||||
}
|
||||
|
||||
public function update(int $id)
|
||||
{
|
||||
$page = $this->page->findOrFail($id);
|
||||
$this->authorize('update', $page);
|
||||
|
||||
$validatedData = $this->validate($this->request, [
|
||||
'title' => [
|
||||
'string',
|
||||
'min:3',
|
||||
'max:250',
|
||||
Rule::unique('custom_pages')
|
||||
->where('user_id', $page->user_id)
|
||||
->ignore($page->id),
|
||||
],
|
||||
'slug' => [
|
||||
'nullable',
|
||||
'string',
|
||||
'min:3',
|
||||
'max:250',
|
||||
Rule::unique('custom_pages')->ignore($page->id),
|
||||
],
|
||||
'body' => 'string|min:1',
|
||||
'meta' => 'nullable|array',
|
||||
]);
|
||||
|
||||
$page = app(CrupdatePage::class)->execute($page, $validatedData);
|
||||
|
||||
return $this->success(['page' => $page]);
|
||||
}
|
||||
|
||||
public function destroy(string $ids)
|
||||
{
|
||||
$pageIds = explode(',', $ids);
|
||||
$this->authorize('destroy', [get_class($this->page), $pageIds]);
|
||||
|
||||
$this->page->whereIn('id', $pageIds)->delete();
|
||||
|
||||
return $this->success();
|
||||
}
|
||||
}
|
||||
27
common/Pages/CustomPageFactory.php
Executable file
27
common/Pages/CustomPageFactory.php
Executable file
@@ -0,0 +1,27 @@
|
||||
<?php
|
||||
|
||||
namespace Common\Pages;
|
||||
|
||||
use Carbon\CarbonPeriod;
|
||||
use Illuminate\Database\Eloquent\Factories\Factory;
|
||||
use Illuminate\Support\Arr;
|
||||
|
||||
class CustomPageFactory extends Factory
|
||||
{
|
||||
protected $model = CustomPage::class;
|
||||
|
||||
public function definition(): array
|
||||
{
|
||||
$period = CarbonPeriod::create(now()->subMonths(3), now());
|
||||
|
||||
return [
|
||||
'body' => $this->faker->randomHtml(),
|
||||
'slug' => $this->faker->slug(3),
|
||||
'title' => $this->faker->words(3, true),
|
||||
'workspace_id' => 0,
|
||||
'user_id' => 1,
|
||||
'created_at' => Arr::random($period->toArray()),
|
||||
'updated_at' => Arr::random($period->toArray()),
|
||||
];
|
||||
}
|
||||
}
|
||||
25
common/Pages/LoadCustomPageMenuItems.php
Executable file
25
common/Pages/LoadCustomPageMenuItems.php
Executable file
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
namespace Common\Pages;
|
||||
|
||||
use Illuminate\Support\Collection;
|
||||
|
||||
class LoadCustomPageMenuItems
|
||||
{
|
||||
public function execute(): Collection
|
||||
{
|
||||
return app(CustomPage::class)
|
||||
->limit(40)
|
||||
->where('type', 'default')
|
||||
->get()
|
||||
->map(function (CustomPage $page) {
|
||||
return [
|
||||
'id' => $page->id,
|
||||
'label' => $page->title ?: $page->slug,
|
||||
'action' => "/pages/{$page->slug}",
|
||||
'model_id' => $page->id,
|
||||
'type' => 'customPage',
|
||||
];
|
||||
});
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user