# Kreator treści

# Zdefiniowane rodzaje sekcji

  • Tekst
  • Obrazek
  • Tekst z obrazkiem
  • Youtube
  • Współdzielone sekcje

# Tworzenie rodzajów sekcji

# Tworzenie edytowalnych rodzajów sekcji

Należy stworzyć model, który będzie rozszerzać klasę Modules\ContentBuilder\Models\SectionType.

class Text extends SectionType

Następnie należy zdefiniować zasady walidacji w metodzie rules(), wiadomości błędów w metodzie messages() oraz nazwy atrybutów w metodzie attributes().

public function rules(): array
{
    return [
        'content' => 'required',
    ];
}

public function messages(): array
{
    return [
        'content.required' => 'pole treść jest wymagane',
    ];
}

public function attributes(): array
{
    return [
        'content' => 'treść',
    ];
}

Opcjonalnym krokiem jest zdefiniowanie publicznej metody sectionData(), która będzie zwracać tablicę zawierającą pola sekcji. Pełni ona rolę transformera.

public function sectionData(): array
{
    return [
        'content' => $this->content,
    ];
}

Domyślnie sectionData() zwraca dane modelu w postaci tablicy, korzystając z metody toArray().

public function sectionData(): array
{
    return $this->toArray();
}

Następnie w pliku konfiguracyjnym Modules/ContentBuilder/Config/config.php wewnątrz section-types, należy dodać alias typu sekcji.

'section-types' => [
    'text',
],

TIP

Jeśli dane dostępne publicznie powinny różnić się od tych, które zwraca metoda sectionData() należy dodać kolejną metodę o nazwie publicSectionData()zawierającą publiczne dane.

public function publicSectionData(): array
{
    return $this->toArray();
}

# Tworzenie sekcji na podstawie modelu

Model, który ma stanowić nowy rodzaj sekcji musi implementować interfejs Modules\ContentBuilder\Contracts\Sectionable.

Należy zdefiniować metodę o nazwie sectionData(), która zwróci tablicę z danymi, które powinna zawierać sekcja.

use Illuminate\Database\Eloquent\Model;
use Modules\ContentBuilder\Contracts\Sectionable;

class Page extends Model implements Sectionable
{
    public function sectionData(): array
    {
        return [
            'title' => $this->title,
            'slug' => $this->slug,
        ];
    }
}

W pliku konfiguracyjnym Modules/ContentBuilder/Config/config.php wewnątrz section-types należy dodać alias typu sekcji oraz dodatkowo dodać wpis do custom-sectionable-types, gdzie kluczem jest typ sekcji, a wartością tablica z klasą kontrolera i jego metodą, która zwróci listę pozycji zawierających identyfikator id oraz wyświetlaną nazwę name.

// Modules/ContentBuilder/Config/config.php

'section-types' => [
    'page',
],

'sectionable-types' => [
    'page' => [PageController::class, 'getToSelect'],
],
class PageController
{
    public function getToSelect(Request $request)
    {
        $builder = $this->page->getBuilder($request);

        return $this->getResponse($builder, PageSelectResource::class);
    }
}
class PageSelectResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'id' => $this->id,
            'name' => $this->title,
        ];
    }
}

# Tworzenie sekcji na podstawie klasy

Niestandardowe typy sekcji służą do podłączenia dynamicznie wygenerowanych danych. Przykładem takich typów sekcji mogą być najnowsze wpisy bloga, polecane produkty, itd.

W pliku konfiguracyjnym Modules/ContentBuilder/Config/config.php wewnątrz custom-sectionable-types należy dodać alias rodzaju niestandardowego pola.

'custom-sectionable-types' => [
    'new-products',
],

Następnie należy stworzyć klasę, która zwróci odpowiednie dane.

class ProductService
{
    public function getItemData(array $options = null)
    {
        return ProductResource::collection(
            Product::take(3)->latest()->get()
        );
    }
}

# Dodatkowe opcje

use Modules\Core\Models\Option;

class ProductService
{
    public function options(): array
    {
        return [
            Option::number('count'),
            Option::select('order_by', [
                'asc' => 'Ascending',
                'desc' => 'Descending'
            ]),
        ];
    }
}

# Walidacja pól z opcjami

Reguły walidacji dla opcji należy zdefiniować poprzez dodanie publicznej metody rules():

class ProductService
{
    public function rules(): array
    {
        return [
            'count' => 'integer|min:1',
            'order_by' => 'in:asc,desc|string',
        ];
    }
}

# Obsługa kreatora treści

# Dodawanie kreatora treści do modelu

Dodawanie kreatora treśći odbywa się poprzez dodanie trait Modules\ContentBuilder\Traits\HasContentBuilder do klasy modelu.

use Modules\ContentBuilder\Contracts\Sectionable;
use Modules\ContentBuilder\Traits\HasContentBuilder;

class Page extends Model implements Sectionable
{
    use HasContentBuilder;

    ...
}

# Walidacja

Obsługa walidacji dla kreatora treści polega na dodaniu trait Modules\ContentBuilder\Traits\HasContentBuilderRules do klasy rozszerzającej Modules\Core\Http\Requests\BaseFormRequest.

Uwaga

Roszerzenie klasy BaseFormRequest pozwala wykonać funkcję wewnątrz zaimplementowanego trait, której nazwa jest konkatenacją słowa validate oraz nazwy implementowanego trait.

use Modules\Core\Http\Requests\BaseFormRequest;
use Modules\ContentBuilder\Traits\HasContentBuilderRules;

class CreatePageRequest extends BaseFormRequest
{
    use HasContentBuilderRules;
}

# Wyświetlanie sekcji

Sekcje modelu można załadować korzystając z metody loadSections(), która jest zdefiniowana wewnątrz trait HasContentBuilder.

public function show(Page $page)
{
    $page->loadSections();

    return response()->json(new PageResource($page));
}

Następnie należy skorzystać z transformera SectionResource, który zwróci dane sekcji.

use Illuminate\Http\Resources\Json\JsonResource;
use Modules\ContentBuilder\Http\Transformers\SectionResource;

class PageResource extends JsonResource
{
    public function toArray($request)
    {
        return [
            'sections' => SectionResource::collection($this->whenLoaded('sections')),
        ];
    }
}

TIP

W przypadku zwracania publicznych danych należy skorzystać z transformera Modules\ContentBuilder\Http\Transformers\PublicSectionResource.