2023-12-27 22:54:58 +01:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Form\Models;
|
|
|
|
|
2024-06-29 18:02:23 +02:00
|
|
|
use App\Form\Data\ExportData;
|
2024-03-07 00:58:14 +01:00
|
|
|
use App\Form\Data\FieldCollection;
|
|
|
|
use App\Form\Data\FormConfigData;
|
2024-07-12 18:05:11 +02:00
|
|
|
use App\Lib\Editor\Condition;
|
2024-07-06 15:08:13 +02:00
|
|
|
use App\Lib\Editor\EditorData;
|
2024-01-12 22:52:42 +01:00
|
|
|
use Cviebrock\EloquentSluggable\Sluggable;
|
2023-12-27 22:54:58 +01:00
|
|
|
use Illuminate\Database\Eloquent\Factories\HasFactory;
|
|
|
|
use Illuminate\Database\Eloquent\Model;
|
2024-02-06 01:45:25 +01:00
|
|
|
use Illuminate\Database\Eloquent\Relations\HasMany;
|
2024-01-29 22:07:33 +01:00
|
|
|
use Laravel\Scout\Searchable;
|
2024-01-19 18:16:57 +01:00
|
|
|
use Spatie\Image\Manipulations;
|
2024-01-12 23:29:18 +01:00
|
|
|
use Spatie\MediaLibrary\HasMedia;
|
|
|
|
use Spatie\MediaLibrary\InteractsWithMedia;
|
2024-01-19 18:16:57 +01:00
|
|
|
use Spatie\MediaLibrary\MediaCollections\Models\Media;
|
2024-01-12 23:29:18 +01:00
|
|
|
use Zoomyboy\MedialibraryHelper\DefersUploads;
|
2023-12-27 22:54:58 +01:00
|
|
|
|
2024-07-04 23:56:47 +02:00
|
|
|
/** @todo replace editor content with EditorData cast */
|
2024-01-12 23:29:18 +01:00
|
|
|
class Form extends Model implements HasMedia
|
2023-12-27 22:54:58 +01:00
|
|
|
{
|
|
|
|
use HasFactory;
|
2024-01-12 22:52:42 +01:00
|
|
|
use Sluggable;
|
2024-01-12 23:29:18 +01:00
|
|
|
use InteractsWithMedia;
|
|
|
|
use DefersUploads;
|
2024-01-29 22:07:33 +01:00
|
|
|
use Searchable;
|
2023-12-27 22:54:58 +01:00
|
|
|
|
|
|
|
public $guarded = [];
|
|
|
|
|
|
|
|
public $casts = [
|
2024-03-07 00:58:14 +01:00
|
|
|
'config' => FormConfigData::class,
|
2024-02-21 22:44:52 +01:00
|
|
|
'meta' => 'json',
|
2024-07-14 19:29:42 +02:00
|
|
|
'description' => EditorData::class,
|
|
|
|
'mail_top' => EditorData::class,
|
|
|
|
'mail_bottom' => EditorData::class,
|
2024-05-27 18:30:05 +02:00
|
|
|
'is_active' => 'boolean',
|
2024-05-27 18:49:11 +02:00
|
|
|
'is_private' => 'boolean',
|
2024-06-29 18:02:23 +02:00
|
|
|
'export' => ExportData::class,
|
2024-07-02 22:55:37 +02:00
|
|
|
'needs_prevention' => 'boolean',
|
2024-07-06 15:08:13 +02:00
|
|
|
'prevention_text' => EditorData::class,
|
2024-07-12 18:05:11 +02:00
|
|
|
'prevention_conditions' => Condition::class,
|
2024-09-21 17:46:07 +02:00
|
|
|
'from' => 'datetime',
|
|
|
|
'to' => 'datetime',
|
|
|
|
'registration_from' => 'datetime',
|
|
|
|
'registration_until' => 'datetime',
|
2023-12-27 22:54:58 +01:00
|
|
|
];
|
2023-12-31 21:46:52 +01:00
|
|
|
|
2024-01-14 13:51:48 +01:00
|
|
|
/**
|
|
|
|
* @return SluggableConfig
|
|
|
|
*/
|
2024-01-12 22:52:42 +01:00
|
|
|
public function sluggable(): array
|
|
|
|
{
|
|
|
|
return [
|
|
|
|
'slug' => ['source' => ['name']],
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2024-02-06 01:45:25 +01:00
|
|
|
/**
|
2024-02-08 23:13:59 +01:00
|
|
|
* @return HasMany<Participant>
|
2024-02-06 01:45:25 +01:00
|
|
|
*/
|
|
|
|
public function participants(): HasMany
|
|
|
|
{
|
|
|
|
return $this->hasMany(Participant::class);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2024-01-12 23:29:18 +01:00
|
|
|
public function registerMediaCollections(): void
|
|
|
|
{
|
|
|
|
$this->addMediaCollection('headerImage')
|
|
|
|
->singleFile()
|
|
|
|
->maxWidth(fn () => 500)
|
2024-01-19 18:16:57 +01:00
|
|
|
->forceFileName(fn (Form $model, string $name) => $model->slug)
|
2024-07-13 19:49:50 +02:00
|
|
|
->convert(fn () => 'jpg')
|
2024-01-19 18:16:57 +01:00
|
|
|
->registerMediaConversions(function (Media $media) {
|
|
|
|
$this->addMediaConversion('square')->fit(Manipulations::FIT_CROP, 400, 400);
|
|
|
|
});
|
2024-04-18 22:15:28 +02:00
|
|
|
$this->addMediaCollection('mailattachments')
|
|
|
|
->withDefaultProperties(fn () => [
|
2024-04-19 22:06:09 +02:00
|
|
|
'conditions' => [
|
|
|
|
'mode' => 'all',
|
|
|
|
'ifs' => []
|
|
|
|
],
|
2024-04-18 22:15:28 +02:00
|
|
|
])
|
|
|
|
->withPropertyValidation(fn () => [
|
2024-04-19 22:06:09 +02:00
|
|
|
'conditions.mode' => 'required|string|in:all,any',
|
|
|
|
'conditions.ifs' => 'array',
|
|
|
|
'conditions.ifs.*.field' => 'required',
|
|
|
|
'conditions.ifs.*.comparator' => 'required',
|
|
|
|
'conditions.ifs.*.value' => 'present',
|
2024-04-18 22:15:28 +02:00
|
|
|
]);
|
2024-01-12 23:29:18 +01:00
|
|
|
}
|
|
|
|
|
2024-02-06 01:45:25 +01:00
|
|
|
/**
|
|
|
|
* @return array<string, mixed>
|
|
|
|
*/
|
|
|
|
public function getRegistrationRules(): array
|
|
|
|
{
|
2024-03-07 00:58:14 +01:00
|
|
|
return $this->getFields()->reduce(fn ($carry, $field) => [
|
|
|
|
...$carry,
|
|
|
|
...$field->getRegistrationRules($this),
|
|
|
|
], []);
|
2024-02-06 01:45:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return array<string, mixed>
|
|
|
|
*/
|
|
|
|
public function getRegistrationMessages(): array
|
|
|
|
{
|
2024-03-07 00:58:14 +01:00
|
|
|
return $this->getFields()->reduce(fn ($carry, $field) => [
|
|
|
|
...$carry,
|
|
|
|
...$field->getRegistrationMessages($this),
|
|
|
|
], []);
|
2024-02-06 01:45:25 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return array<string, mixed>
|
|
|
|
*/
|
|
|
|
public function getRegistrationAttributes(): array
|
|
|
|
{
|
2024-03-07 00:58:14 +01:00
|
|
|
return $this->getFields()->reduce(fn ($carry, $field) => [
|
|
|
|
...$carry,
|
|
|
|
...$field->getRegistrationAttributes($this),
|
|
|
|
], []);
|
2024-02-06 01:45:25 +01:00
|
|
|
}
|
|
|
|
|
2024-03-07 00:58:14 +01:00
|
|
|
public function getFields(): FieldCollection
|
2024-02-06 01:45:25 +01:00
|
|
|
{
|
2024-03-07 00:58:14 +01:00
|
|
|
return $this->config->fields();
|
2024-02-06 01:45:25 +01:00
|
|
|
}
|
|
|
|
|
2024-01-12 22:52:42 +01:00
|
|
|
|
2024-01-29 22:07:33 +01:00
|
|
|
// --------------------------------- Searching ---------------------------------
|
|
|
|
// *****************************************************************************
|
|
|
|
|
2024-01-12 22:52:42 +01:00
|
|
|
/**
|
2024-01-29 22:07:33 +01:00
|
|
|
* Get the indexable data array for the model.
|
2024-01-12 22:52:42 +01:00
|
|
|
*
|
2024-01-29 22:07:33 +01:00
|
|
|
* @return array<string, mixed>
|
2024-01-12 22:52:42 +01:00
|
|
|
*/
|
2024-01-29 22:07:33 +01:00
|
|
|
public function toSearchableArray()
|
2024-01-12 22:52:42 +01:00
|
|
|
{
|
2024-01-29 22:07:33 +01:00
|
|
|
return [
|
|
|
|
'from' => $this->from->timestamp,
|
|
|
|
'to' => $this->to->timestamp,
|
|
|
|
'name' => $this->name,
|
2024-05-27 18:30:05 +02:00
|
|
|
'is_active' => $this->is_active,
|
2024-05-27 18:49:11 +02:00
|
|
|
'is_private' => $this->is_private,
|
2024-01-29 22:07:33 +01:00
|
|
|
];
|
2024-01-12 22:52:42 +01:00
|
|
|
}
|
2024-02-08 23:09:51 +01:00
|
|
|
|
|
|
|
public static function booted(): void
|
|
|
|
{
|
|
|
|
static::saving(function (self $model) {
|
2024-04-23 23:12:14 +02:00
|
|
|
if (is_null(data_get($model->meta, 'active_columns'))) {
|
2024-02-21 22:44:52 +01:00
|
|
|
$model->setAttribute('meta', [
|
2024-02-22 00:06:16 +01:00
|
|
|
'active_columns' => $model->getFields()->count() ? $model->getFields()->take(4)->pluck('key')->toArray() : null,
|
2024-03-07 00:58:14 +01:00
|
|
|
'sorting' => $model->getFields()->count() ? [$model->getFields()->first()->key, 'asc'] : null,
|
2024-02-21 22:44:52 +01:00
|
|
|
]);
|
2024-04-23 23:12:14 +02:00
|
|
|
return;
|
2024-02-08 23:09:51 +01:00
|
|
|
}
|
2024-03-01 03:00:33 +01:00
|
|
|
|
|
|
|
if (is_array(data_get($model->meta, 'active_columns'))) {
|
|
|
|
$model->setAttribute('meta', [
|
|
|
|
...$model->meta,
|
2024-07-25 00:17:31 +02:00
|
|
|
'active_columns' => array_values(array_intersect([...$model->getFields()->pluck('key')->toArray(), 'created_at', 'prevention'], $model->meta['active_columns'])),
|
2024-03-01 03:00:33 +01:00
|
|
|
]);
|
2024-04-23 23:12:14 +02:00
|
|
|
return;
|
2024-03-01 03:00:33 +01:00
|
|
|
}
|
2024-02-08 23:09:51 +01:00
|
|
|
});
|
|
|
|
}
|
2023-12-27 22:54:58 +01:00
|
|
|
}
|