*/ protected $fillable = [ 'section', 'h2_title', 'text', 'data', 'page_id', 'id', 'created_at', 'updated_at' ]; /** * The attributes that should be cast. * * @var array */ protected $casts = [ 'section' => PageSectionEnum::class, 'data' => 'array', ]; /** * Perform any actions required after the model boots. * * @return void */ protected static function booted(): void { static::creating(function () { throw new \RuntimeException("Creating a new section is not authorized"); }); static::updating(function (self $model) { // * ASSERTIONS ToolboxHelper::assertNoInternalBoUrls('text', $model->text); // * TRANSFORMATIONS $model->text = FileStorageHelper::storeModelFilesFromHtml($model, $model->text); }); static::updated(function (self $model) { FileStorageHelper::removeOldModelFilesFromHtml( $model->text, ToolboxHelper::getOriginal($model, 'text') ); }); static::deleting(function () { throw new \RuntimeException('Deleting a section is not authorized'); }); } // * METHODS. // * EMPTY BLOCS. /** * Empty bloc for picture. * * @param array $data * @param string $img * @param string $imgAlt * @param string $imgTitle * @param integer $width * @param integer $height * @param boolean $required * @param string $name * @return array */ public static function emptyPictureBloc( array $data, string $img = '', string $imgAlt = '', string $imgTitle = '', int $width = 100, int $height = 100, bool $required = false, string $name = 'image', ): array { $data[sprintf('bloc_%s', Str::of($name)->snake()->ascii()->remove(['\'', '-']))] = [ 'label' => $name, 'dimensions' => ['width' => $width, 'height' => $height], 'inputType' => InputType::image->value, 'alt' => $imgAlt, 'title' => $imgTitle, 'value' => $img, 'validate' => $required ? 'required' : 'nullable', 'required' => $required ]; return $data; } /** * Empty bloc for link. * * @param array $data * @param string $url * @param boolean $required * @param string $name * @return array */ public static function emptyLinkBloc( array $data, string $url = '', bool $required = false, string $name = "URL à ouvrir", ): array { $data[sprintf('bloc_%s', Str::of($name)->snake()->ascii()->remove(['\'', '-']))] = [ 'label' => $name, 'inputType' => InputType::url->value, 'value' => $url, 'validate' => 'url|' . ($required ? 'required' : 'nullable'), 'required' => $required ]; return $data; } /** * Empty bloc for boolean new tab link. * * @param array $data * @param string $name * @return array */ public static function emptyLinkNewTabBloc( array $data, string $name = 'le lien', ): array { $data["bloc_link_new_tab"] = [ 'label' => "Ouvrir dans un nouvel onglet {$name}", 'inputType' => InputType::boolean->value, 'value' => true, ]; return $data; } /** * Empty bloc for key numbers. * * @param array $data * @param string $name * @param integer $value * @param boolean $required * * @return array */ public static function emptyKeyNumberBloc( array $data, string $name, int $value = 0, bool $required = false, ): array { $data['bloc_key_' . Str::of($name)->snake()->ascii()->remove(['\'', '-'])] = [ 'label' => "Chiffre clé {$name}", 'inputType' => InputType::number->value, 'value' => $value, 'validate' => $required ? 'required' : 'nullable', 'required' => $required ]; return $data; } /** * Empty bloc for the button boolean. * * @param array $data * @param string $name * @return array */ public static function emptyButtonBooleanBloc( array $data, string $name ): array { $data['bloc_button_' . Str::of($name)->snake()->ascii()->remove(['\'', '-'])] = [ 'label' => "Afficher le bouton '{$name}' ?", 'inputType' => InputType::boolean->value, 'value' => false ]; return $data; } /** * Empty bloc for the h3 title. * * @param array $data * @param string $name * @param string $value * @param boolean $required * @return array */ public static function emptyStringBloc( array $data, string $name, string $value = '', bool $required = false ): array { $data['bloc_string_' . Str::of($name)->snake()->ascii()->remove(['\'', '-'])] = [ 'label' => $name, 'inputType' => InputType::string->value, 'validate' => 'max:255|' . ($required ? 'required' : 'nullable'), 'value' => $value, 'required' => $required ]; return $data; } /** * Empty bloc for the WYSIWYG content. * * @param array $data * @param string $name * @param string $value * @param \App\Enums\CkEditorConfigName $config * @param boolean $required * @return array */ public static function emptyWysiwygBloc( array $data, string $name, string $value = '', CkEditorConfigName $config = CkEditorConfigName::base, bool $required = false ): array { $data['bloc_' . Str::of($name)->snake()->ascii()->remove(['\'', '-']) . '_content'] = [ 'label' => "Contenu de la section {$name}", 'inputType' => InputType::text->value, 'validate' => $required ? 'required' : 'nullable', 'value' => $value, 'required' => $required, 'config' => $config->name ]; return $data; } /** * Add part piece * * @return void */ public function addPartPiece(): void { $pieceTemplateLinesCount = self::countPartPieces(); $pieceToAdd = self::getAddablePartPieceBlock( $this->section, $this->countPartPieces() + 1 ); $linesToSkip = 1; $data = collect($this->data); $groupedPieces = $data->skip($linesToSkip)->splitIn($data->count() / ($pieceTemplateLinesCount ?: 1)) ->concat([$pieceToAdd]) ->sort(function ($aCollect, $bCollect) { if ($this->section->equals(PageSectionEnum::produce_rhd)) { return strcmp( strrev(collect(collect($aCollect)->first())->first()), strrev(collect(collect($bCollect)->first())->first()) ); } return 0; }); $groupedPieces->prepend([$data->keys()->first() => $data->first()]); $this->data = $groupedPieces->collapse()->all(); } /** * Remove part piece * * @param integer $index * @return integer Elements count removed. */ public function removePartPiece(int $index): int { $pieceTemplate = self::getPartPieces(); $pieceTemplateLinesCount = self::countPartPieces(); if (!$pieceTemplateLinesCount) { return 0; } $linesToSkip = 1; $data = collect($this->data); $groupedPieces = $data->skip($linesToSkip)->splitIn($data->count() / count($pieceTemplate)); $removedGroup = $groupedPieces->splice($index - 1, 1); $this->data = $groupedPieces->collapse() ->prepend($data->first(), $data->keys()->first()) ->all(); return $removedGroup->count(); } /** * Count part pieces * * @return integer */ public function countPartPieces(): int { $pieceTemplate = self::getPartPieces(); $data = collect($this->data); $templateKeys = collect($pieceTemplate)->keys(); $dataCount = $data->count(); $repetitionCount = 0; for ($i = 1; $i <= $dataCount; $i++) { $indexKeys = $templateKeys->map(fn ($key) => str_replace('__index', strval($i), $key)); if ($indexKeys->every(fn ($key) => $data->has($key))) { $repetitionCount++; } } return $repetitionCount; } /** * Get part pieces * * @return array */ private function getPartPieces(): array { $pieceTemplate = self::getAddablePartPieceBlockTemplate($this->section); return is_null($pieceTemplate) ? [] : $pieceTemplate; } /** * Addable part piece block * * @param \App\Enums\Sections\PageSectionEnum $sectionEnum * @param integer $index * @return array */ public static function getAddablePartPieceBlock(PageSectionEnum $sectionEnum, int $index = 1): array|null { $data = null; $pieceTemplate = self::getAddablePartPieceBlockTemplate($sectionEnum); if (!is_null($pieceTemplate)) { $data = json_decode(Str::of(json_encode($pieceTemplate))->replace('__index', strval($index)), true); /** @var array $data */ } return $data; } /** * Addable part piece block * * @param \App\Enums\Sections\PageSectionEnum $sectionEnum * @return array */ public static function getAddablePartPieceBlockIndexes(PageSectionEnum $sectionEnum): array|null { $data = self::getAddablePartPieceBlockTemplate($sectionEnum); if (!is_null($data)) { return array_keys($data); } return $data; } /** * @param \App\Enums\Sections\PageSectionEnum $sectionEnum * @return array|null */ private static function getAddablePartPieceBlockTemplate(PageSectionEnum $sectionEnum): array|null { $data = null; switch ($sectionEnum) { case PageSectionEnum::produce_export: $data = array_merge( self::emptyWysiwygBloc( [], "accompagnant l'image __index de la partie", '' ), self::emptyPictureBloc([], '', '', '', 100, 100, true, "Image __index de la partie"), self::emptyLinkBloc([], '', false, "Lien de l'image__index de la partie") ); break; case PageSectionEnum::produce_rhd: $data = array_merge( self::emptyWysiwygBloc( [], "accompagnant l'image __index de la partie 1", '' ), self::emptyPictureBloc([], '', '', '', 100, 100, true, "Image __index de la partie 1"), self::emptyLinkBloc([], '', false, "Lien de l'image__index de la partie 1") ); break; default: } //end switch return $data; } // * RELATIONS /** * Get the page that owns the section. * * @return \Illuminate\Database\Eloquent\Relations\BelongsTo */ public function page(): \Illuminate\Database\Eloquent\Relations\BelongsTo { return $this->belongsTo(StaticPage::class); } }