Block.php 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061
  1. <?php
  2. namespace App\Models;
  3. /*
  4. * Block — блок контента с привязанным макетом и структурированными полями.
  5. *
  6. * Таблица: blocks
  7. * layout — ключ макета из BlockLayoutRegistry (why_us, hero_banner и т.д.)
  8. * data — значения полей в виде массива (хранится как JSON)
  9. *
  10. * getByName() — получить активный блок по системному имени
  11. * render() — рендерит блок через Blade-шаблон blocks/{layout}.blade.php
  12. */
  13. use App\Support\BlockLayoutRegistry;
  14. use Illuminate\Database\Eloquent\Model;
  15. use Illuminate\Database\Eloquent\Relations\BelongsToMany;
  16. class Block extends Model
  17. {
  18. protected $fillable = ['name', 'title', 'layout', 'content', 'data', 'is_active'];
  19. protected $casts = [
  20. 'is_active' => 'boolean',
  21. 'data' => 'array',
  22. ];
  23. public static function getByName(string $name): ?self
  24. {
  25. return static::where('name', $name)->where('is_active', true)->first();
  26. }
  27. // Рендерит блок через соответствующий Blade-шаблон, возвращает готовый HTML
  28. public function render(): string
  29. {
  30. if (!$this->layout || !$this->data) {
  31. return '';
  32. }
  33. $view = 'blocks.' . $this->layout;
  34. if (!view()->exists($view)) {
  35. return '';
  36. }
  37. return view($view, ['data' => $this->data])->render();
  38. }
  39. // Определение макета из реестра (null если макет не задан или не найден)
  40. public function layoutDefinition(): ?array
  41. {
  42. return $this->layout ? BlockLayoutRegistry::get($this->layout) : null;
  43. }
  44. // Страницы, на которых размещён этот блок
  45. public function pages(): BelongsToMany
  46. {
  47. return $this->belongsToMany(Page::class, 'page_sections')->withPivot('sort_order');
  48. }
  49. }