From 73615cdf1fc4e2122e496d3f97dbcb3ba52645de Mon Sep 17 00:00:00 2001 From: Noah Lancien Date: Tue, 17 Jun 2025 12:29:15 +0200 Subject: [PATCH] fix: some fixes after local testing --- app/Http/Controllers/Bo/TenantController.php | 2 +- .../Bo/AppUser/StoreAppUserRequest.php | 3 +- .../Bo/Documents/StoreDocumentRequest.php | 2 +- .../Bo/Formularies/StoreFormularyRequest.php | 1 + app/Http/Requests/Bo/Tags/StoreTagRequest.php | 20 ------- .../Bo/Tenants/StoreTenantRequest.php | 14 ----- app/Models/AppUser.php | 2 +- app/Models/Document.php | 24 +++++---- app/Models/Formulary.php | 28 +++++++++- app/Models/Tag.php | 52 +++++++++++++++++-- app/Traits/Models/IsRelatedToTenant.php | 20 +++++++ .../2023_03_27_112237_update_users_table.php | 2 +- .../components/CrudDocumentInputComponent.vue | 6 ++- .../FormulariesSelectInputComponent.vue | 12 ++--- .../views/bo/pages/app_users/form.blade.php | 2 +- .../views/bo/pages/app_users/index.blade.php | 15 +++--- .../views/bo/pages/documents/index.blade.php | 5 +- .../bo/pages/formularies/index.blade.php | 5 +- resources/views/bo/pages/tags/form.blade.php | 8 +-- resources/views/bo/pages/tags/index.blade.php | 2 +- 20 files changed, 145 insertions(+), 80 deletions(-) create mode 100644 app/Traits/Models/IsRelatedToTenant.php diff --git a/app/Http/Controllers/Bo/TenantController.php b/app/Http/Controllers/Bo/TenantController.php index b936742..b50b253 100644 --- a/app/Http/Controllers/Bo/TenantController.php +++ b/app/Http/Controllers/Bo/TenantController.php @@ -142,7 +142,7 @@ class TenantController extends Controller return DB::transaction(function () use ($tenant, $previousQueries) { if ($tenant->deleteOrFail()) { /** @var string $tenantKey */ - $tenantKey = \tenant()->getKey(); + $tenantKey = $tenant->getKey(); Storage::disk('public')->deleteDirectory("modelfiles/{$tenantKey}"); Storage::disk('public')->deleteDirectory("docs/{$tenantKey}"); return redirect() diff --git a/app/Http/Requests/Bo/AppUser/StoreAppUserRequest.php b/app/Http/Requests/Bo/AppUser/StoreAppUserRequest.php index fe5a141..30987de 100644 --- a/app/Http/Requests/Bo/AppUser/StoreAppUserRequest.php +++ b/app/Http/Requests/Bo/AppUser/StoreAppUserRequest.php @@ -50,7 +50,8 @@ class StoreAppUserRequest extends FormRequest 'email' => [ 'required', 'email:rfc,strict,dns,spoof,filter', - Rule::unique('app_users', 'email')->where(fn (Builder $query) => $query->where('tenant_id', tenant('id'))) + Rule::unique('app_users', 'email') + ->where(fn(Builder $query) => $query->where('tenant_id', tenant('id'))) ], 'password' => [ 'required', diff --git a/app/Http/Requests/Bo/Documents/StoreDocumentRequest.php b/app/Http/Requests/Bo/Documents/StoreDocumentRequest.php index 3530f19..6ae256a 100644 --- a/app/Http/Requests/Bo/Documents/StoreDocumentRequest.php +++ b/app/Http/Requests/Bo/Documents/StoreDocumentRequest.php @@ -50,7 +50,7 @@ class StoreDocumentRequest extends FormRequest if (Document::query()->where('id', $this->document_id)->exists() && $this->type) { $this->merge([ 'directory_id' => Document::query()->where('id', $this->document_id)->value('directory_id'), - 'type' => TypeEnum::make($this->type, 'name')->value(), + 'type' => TypeEnum::make($this->type, 'name')->name(), ]); } } diff --git a/app/Http/Requests/Bo/Formularies/StoreFormularyRequest.php b/app/Http/Requests/Bo/Formularies/StoreFormularyRequest.php index dbf5cb6..78e2eab 100644 --- a/app/Http/Requests/Bo/Formularies/StoreFormularyRequest.php +++ b/app/Http/Requests/Bo/Formularies/StoreFormularyRequest.php @@ -85,6 +85,7 @@ class StoreFormularyRequest extends FormRequest ]; foreach ($this->mobileAppLocales as $locale) { $attributes["placeholder.{$locale}"] = trans('placeholder (:lang)', ['lang' => $locale]); + $attributes["details.*.{$locale}"] = trans('details (:lang)', ['lang' => $locale]); } return $attributes; } diff --git a/app/Http/Requests/Bo/Tags/StoreTagRequest.php b/app/Http/Requests/Bo/Tags/StoreTagRequest.php index 7910cff..fb9115b 100644 --- a/app/Http/Requests/Bo/Tags/StoreTagRequest.php +++ b/app/Http/Requests/Bo/Tags/StoreTagRequest.php @@ -5,8 +5,6 @@ namespace App\Http\Requests\Bo\Tags; use App\Models\Tag; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Support\Facades\Gate; -use Illuminate\Support\Str; -use Illuminate\Validation\Rule; class StoreTagRequest extends FormRequest { @@ -20,18 +18,6 @@ class StoreTagRequest extends FormRequest return Gate::check('create', Tag::class); } - /** - * Prepare the data for validation. - * - * @return void - */ - protected function prepareForValidation(): void - { - $this->merge([ - 'slug' => Str::slug($this->name), - ]); - } - /** * Get the validation rules that apply to the request. * @@ -41,11 +27,6 @@ class StoreTagRequest extends FormRequest { return [ 'name' => 'required|string|min:2|max:25', - 'slug' => [ - 'required', - 'string', - Rule::unique('tags', 'slug')->where('tenant_id', tenant('id')) - ] ]; } @@ -58,7 +39,6 @@ class StoreTagRequest extends FormRequest { return [ 'name' => trans('models.classes.tag'), - 'slug' => trans('validation.custom.slug'), ]; } } diff --git a/app/Http/Requests/Bo/Tenants/StoreTenantRequest.php b/app/Http/Requests/Bo/Tenants/StoreTenantRequest.php index a4e347f..c7c384a 100644 --- a/app/Http/Requests/Bo/Tenants/StoreTenantRequest.php +++ b/app/Http/Requests/Bo/Tenants/StoreTenantRequest.php @@ -5,7 +5,6 @@ namespace App\Http\Requests\Bo\Tenants; use App\Models\Tenant; use Illuminate\Foundation\Http\FormRequest; use Illuminate\Support\Facades\Gate; -use Illuminate\Support\Str; class StoreTenantRequest extends FormRequest { @@ -19,18 +18,6 @@ class StoreTenantRequest extends FormRequest return Gate::allows('create', Tenant::class); } - /** - * Prepare the data for validation. - * - * @return void - */ - protected function prepareForValidation(): void - { - $this->merge([ - 'id' => Str::slug($this->name), - ]); - } - /** * Get the validation rules that apply to the request. * @@ -39,7 +26,6 @@ class StoreTenantRequest extends FormRequest public function rules(): array { return [ - 'id' => 'required|string|min:2|max:25', 'name' => 'required|string|min:2|max:25', ]; } diff --git a/app/Models/AppUser.php b/app/Models/AppUser.php index b60e63d..a3eac8d 100644 --- a/app/Models/AppUser.php +++ b/app/Models/AppUser.php @@ -101,7 +101,7 @@ class AppUser extends Model private static function setOrder(self $model): void { $model->order = \intval( - self::query()->where('tenant_id', \tenant() ?? Tenant::first()->getKey())->max('order') + self::query()->where('tenant_id', \tenant()->getKey() ?? Tenant::first()->getKey())->max('order') ) + 1; } diff --git a/app/Models/Document.php b/app/Models/Document.php index a45508e..0969e75 100644 --- a/app/Models/Document.php +++ b/app/Models/Document.php @@ -3,6 +3,7 @@ namespace App\Models; use App\Enums\Documents\LangEnum; +use App\Traits\Models\IsRelatedToTenant; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Facades\Storage; @@ -27,6 +28,7 @@ use Uwil\LaravelCommon\Helpers\ToolboxHelper; class Document extends Model { use BelongsToTenant; + use IsRelatedToTenant; use HasFactory; /** @@ -68,14 +70,16 @@ class Document extends Model self::setOrder($model); }); static::updating(function (self $model) { - $path = \ltrim(\urldecode(sprintf( - 'docs/%s/%s.%s', - \tenant()->getKey(), - $model->getOriginal('uuid'), - $model->getOriginal('type') - )), '/'); - if (Storage::disk('public')->exists($path)) { - Storage::disk('public')->delete($path); + if ($model->getOriginal('uuid') !== $model->uuid) { + $path = \ltrim(\urldecode(sprintf( + 'docs/%s/%s.%s', + \tenant()->getKey(), + $model->getOriginal('uuid'), + $model->getOriginal('type') + )), '/'); + if (Storage::disk('public')->exists($path)) { + Storage::disk('public')->delete($path); + } } }); static::deleting(function (self $model) { @@ -96,7 +100,7 @@ class Document extends Model private static function assertFieldIsUnique(string $nameField, string $valueField, ?int $id = null): void { $table = (new self())->getTable(); - ToolboxHelper::assertFieldIsUnique($table, $nameField, $valueField, $id); + ToolboxHelper::assertFieldIsUnique($table, $nameField, $valueField, $id, self::whereTenantQuery()); } /** @@ -108,7 +112,7 @@ class Document extends Model private static function setOrder(self $model): void { $model->order = \intval( - self::query()->where('tenant_id', \tenant() ?? Tenant::first()->getKey())->max('order') + self::query()->where(self::whereTenantQuery())->max('order') ) + 1; } diff --git a/app/Models/Formulary.php b/app/Models/Formulary.php index 244fc04..ad8e527 100644 --- a/app/Models/Formulary.php +++ b/app/Models/Formulary.php @@ -4,10 +4,12 @@ namespace App\Models; use App\Enums\Formularies\InputStatusEnum; use App\Enums\Formularies\InputTypeEnum; +use App\Traits\Models\IsRelatedToTenant; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Illuminate\Support\Str; use Stancl\Tenancy\Database\Concerns\BelongsToTenant; +use Uwil\LaravelCommon\Helpers\ToolboxHelper; /** * @property integer $id Formulary id. @@ -27,6 +29,7 @@ use Stancl\Tenancy\Database\Concerns\BelongsToTenant; class Formulary extends Model { use BelongsToTenant; + use IsRelatedToTenant; use HasFactory; /** @@ -68,12 +71,20 @@ class Formulary extends Model protected static function booted(): void { static::creating(function (self $model) { + // * ASSERTIONS + self::assertNameIsUnique($model->name); + + // * TRANSFORMATIONS self::setSlug($model); self::setStatusField($model); self::setOrder($model); self::makeRequiredSense($model); }); static::updating(function (self $model) { + // * ASSERTIONS + self::assertNameIsUnique($model->name, $model->id); + + // * TRANSFORMATIONS self::setSlug($model); self::makeRequiredSense($model); }); @@ -81,6 +92,21 @@ class Formulary extends Model // * METHODS + /** + * Asserts using validation that the name is unique + * + * @param string|null $name + * @param integer|null $id + * @return void + * @throws \Illuminate\Validation\ValidationException If name already exists. + */ + private static function assertNameIsUnique(string|null $name, ?int $id = null) + { + $table = (new self())->getTable(); + ToolboxHelper::assertFieldIsUnique($table, 'name', $name, $id, self::whereTenantQuery()); + ToolboxHelper::assertFieldIsUnique($table, 'slug', Str::slug($name), $id, self::whereTenantQuery()); + } + /** * Set the slug. * @@ -128,7 +154,7 @@ class Formulary extends Model private static function setOrder(self $model): void { $model->order = \intval( - self::query()->where('tenant_id', \tenant() ?? Tenant::first()->getKey())->max('order') + self::query()->where(self::whereTenantQuery())->max('order') ) + 1; } diff --git a/app/Models/Tag.php b/app/Models/Tag.php index ab5573c..68415e8 100644 --- a/app/Models/Tag.php +++ b/app/Models/Tag.php @@ -2,9 +2,12 @@ namespace App\Models; +use App\Traits\Models\IsRelatedToTenant; use Illuminate\Database\Eloquent\Factories\HasFactory; use Illuminate\Database\Eloquent\Model; use Stancl\Tenancy\Database\Concerns\BelongsToTenant; +use Uwil\LaravelCommon\Helpers\ToolboxHelper; +use Illuminate\Support\Str; /** * @property integer $id Tag id. @@ -18,6 +21,7 @@ use Stancl\Tenancy\Database\Concerns\BelongsToTenant; class Tag extends Model { use BelongsToTenant; + use IsRelatedToTenant; use HasFactory; /** @@ -37,16 +41,54 @@ class Tag extends Model */ protected static function booted(): void { - static::creating(function (self $tag) { - self::setOrder($tag); + static::creating(function (self $model) { + // * ASSERTIONS + self::assertNameIsUnique($model->name); + + // * TRANSFORMATIONS + self::setSlug($model); + self::setOrder($model); }); - static::deleting(function (self $tag) { - $tag->documents()->detach(); + static::updating(function (self $model) { + // * ASSERTIONS + self::assertNameIsUnique($model->name); + + // * TRANSFORMATIONS + self::setSlug($model); + }); + static::deleting(function (self $model) { + $model->documents()->detach(); }); } // * METHODS + /** + * Asserts using validation that the name is unique + * + * @param string|null $name + * @param integer|null $id + * @return void + * @throws \Illuminate\Validation\ValidationException If name already exists. + */ + private static function assertNameIsUnique(string|null $name, ?int $id = null) + { + $table = (new self())->getTable(); + ToolboxHelper::assertFieldIsUnique($table, 'name', $name, $id, self::whereTenantQuery()); + ToolboxHelper::assertFieldIsUnique($table, 'slug', Str::slug($name), $id, self::whereTenantQuery()); + } + + /** + * Set the slug. + * + * @param self $model + * @return void + */ + private static function setSlug(self $model): void + { + $model->slug = Str::slug($model->name); + } + /** * Set order after the last element of the list. * @@ -56,7 +98,7 @@ class Tag extends Model private static function setOrder(Tag $tag): void { $tag->order = \intval( - self::query()->where('tenant_id', \tenant() ?? Tenant::first()->getKey())->max('order') + self::query()->where(self::whereTenantQuery())->max('order') ) + 1; } diff --git a/app/Traits/Models/IsRelatedToTenant.php b/app/Traits/Models/IsRelatedToTenant.php new file mode 100644 index 0000000..8ff5691 --- /dev/null +++ b/app/Traits/Models/IsRelatedToTenant.php @@ -0,0 +1,20 @@ +where('tenant_id', \tenant()->getKey() ?? Tenant::first()->getKey()); + }; + } +} diff --git a/database/migrations/2023_03_27_112237_update_users_table.php b/database/migrations/2023_03_27_112237_update_users_table.php index fe17a2f..b9c0f0f 100644 --- a/database/migrations/2023_03_27_112237_update_users_table.php +++ b/database/migrations/2023_03_27_112237_update_users_table.php @@ -23,7 +23,7 @@ class UpdateUsersTable extends Migration Schema::table('users', function (Blueprint $table) { $table->renameColumn('name', 'firstname'); $table->string('lastname')->nullable()->after('firstname'); - $table->dateTime('created_at')->default(Carbon::now())->nullable()->change(); + $table->dateTime('created_at')->default(DB::raw('CURRENT_TIMESTAMP'))->nullable()->change(); }); $usersNew = User::get(); diff --git a/resources/ts/bo/components/CrudDocumentInputComponent.vue b/resources/ts/bo/components/CrudDocumentInputComponent.vue index c9c075a..75d705d 100644 --- a/resources/ts/bo/components/CrudDocumentInputComponent.vue +++ b/resources/ts/bo/components/CrudDocumentInputComponent.vue @@ -47,7 +47,7 @@ name="title" class="form-control need-word-counter" :placeholder="trans.methods.__('Un beau titre de document')" - :value="intModel?.title" + v-model="documentTitle" > {{ trans.methods.__("Doit posséder 3 caractères minimum, 255 maximum.") }} @@ -262,6 +262,7 @@ const intDocumentDatas = ref<{ }); const intCsrf = ref(""); const intTooltipList = ref([]); +let documentTitle = ref(""); onMounted(() => { const json = String(attrs.json ?? "{}"), @@ -272,6 +273,9 @@ onMounted(() => { intDocuments.value = data.documents; intDirectories.value = data.directories; intModel.value = data.model; + if (intModel.value) { + documentTitle.value = String(intModel.value.title ?? ""); + } if (intModel.value != null) { if (intModel.value.lang === undefined) { intIsDocFR.value = true; diff --git a/resources/ts/bo/components/FormulariesSelectInputComponent.vue b/resources/ts/bo/components/FormulariesSelectInputComponent.vue index 1b2d523..ae17615 100644 --- a/resources/ts/bo/components/FormulariesSelectInputComponent.vue +++ b/resources/ts/bo/components/FormulariesSelectInputComponent.vue @@ -71,7 +71,7 @@

{{ parseLaravelErrorMessages.methods.parseValidationInput(`name`, allErrors) }}

- {{ trans.methods.__('Doit posséder 3 caractères minimum, 255 maximum.') }} + {{ trans.methods.__('Doit posséder 3 caractères minimum, 70 maximum.') }} @@ -103,7 +103,7 @@

{{ parseLaravelErrorMessages.methods.parseValidationInput(`placeholder.fr`, allErrors) }}

- {{ trans.methods.__('Doit posséder 3 caractères minimum, 255 maximum.') }} + {{ trans.methods.__('Doit posséder 3 caractères minimum, 100 maximum.') }}
@@ -223,7 +223,7 @@