Livewire SqlPaginationトレイトを作ってみました

ショコラ
ショコラ

Livewire SqlPaginationトレイトを作ってみました

モデルを使わないでページネーションするやり方です。
これで開発が速くなります。

もっさん先輩
もっさん先輩

SqlPagination トレイトを追加します。

<?php

namespace App\Livewire;
use Livewire\Attributes\On;
use Livewire\WithPagination;
use Illuminate\Pagination\LengthAwarePaginator;

trait SqlPagination
{
  use WithPagination;

  public int $per_page = 10;
  public string $select_sql = '';
  public array $select_params = [];
  public string $view_template = '';

  // item を修正できます
  public function render_item( $item )
  {
    return $item;
  }

  public function render()
  {
    $page = 1;
    if (isset($this->paginators['page'])) {
      $page = $this->paginators['page'];
    }

    if ('' == $this->select_sql) {
      return view($this->view_template, [
        'paginator' => new LengthAwarePaginator(0,0,$this->per_page,$page),
        'items' => [],
      ]);
    }

    // 一覧数
    $item_count = \XDB::getOne("SELECT COUNT(*) FROM (".$this->select_sql.") tmp_ct",$this->select_params);

    // ページ数
    $page_count = intval(ceil($item_count / $this->per_page));

    // SQLで一覧を取得する
    $select_sql = $this->select_sql.' OFFSET ? LIMIT ?';
    $offset = ($page <= 1) ? 0 : ($page - 1) * $this->per_page;
    $select_params = array_merge($this->select_params,[$offset,$this->per_page]);
    $tmp_items = \XDB::select($select_sql,$select_params);

    $items = [];
    foreach ($tmp_items as $i => $item) {
      $n = ($page - 1) * $page_count + $i + 1;
      $items[$n] = $this->render_item($item);
    }
    $paginator = new LengthAwarePaginator(collect($items), $item_count, $this->per_page, $page);

    return view($this->view_template,[
      'paginator' => $paginator,
      'items' => $items,
    ]);
  }
}

SqlPagination トレイトを使用するクラスです。

<?php

namespace App\Livewire;
use Livewire\Component;

class List extends Component
{
  use SqlPagination;

  public function mount()
  {
    $this->per_page = 2;
    $this->select_sql = "SELECT * FROM items";
    $this->view_template = 'livewire.list';
  }
}

ビュー側です。

@empty($items)
  情報はありません。
@else
  <div class="ui basic center aligned segment">
    {{ $paginator->onEachSide(1)->links('pagination::semantic-ui-livewire') }}
  </div>
  @foreach ($items as $i => $row)
  @endforeach
@endif

以上

Scroll to Top