Subiendo proyecto completo sin restricciones de git ignore

This commit is contained in:
Jose Sanchez
2023-08-17 11:44:02 -04:00
parent a0d4f5ba3b
commit 20f1c60600
19921 changed files with 2509159 additions and 45 deletions

View File

@@ -0,0 +1,671 @@
<?php
namespace Illuminate\Pagination;
use ArrayAccess;
use Closure;
use Exception;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\Pivot;
use Illuminate\Http\Resources\Json\JsonResource;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Illuminate\Support\Traits\ForwardsCalls;
use Illuminate\Support\Traits\Tappable;
use Traversable;
/**
* @mixin \Illuminate\Support\Collection
*/
abstract class AbstractCursorPaginator implements Htmlable
{
use ForwardsCalls, Tappable;
/**
* All of the items being paginated.
*
* @var \Illuminate\Support\Collection
*/
protected $items;
/**
* The number of items to be shown per page.
*
* @var int
*/
protected $perPage;
/**
* The base path to assign to all URLs.
*
* @var string
*/
protected $path = '/';
/**
* The query parameters to add to all URLs.
*
* @var array
*/
protected $query = [];
/**
* The URL fragment to add to all URLs.
*
* @var string|null
*/
protected $fragment;
/**
* The cursor string variable used to store the page.
*
* @var string
*/
protected $cursorName = 'cursor';
/**
* The current cursor.
*
* @var \Illuminate\Pagination\Cursor|null
*/
protected $cursor;
/**
* The paginator parameters for the cursor.
*
* @var array
*/
protected $parameters;
/**
* The paginator options.
*
* @var array
*/
protected $options;
/**
* The current cursor resolver callback.
*
* @var \Closure
*/
protected static $currentCursorResolver;
/**
* Get the URL for a given cursor.
*
* @param \Illuminate\Pagination\Cursor|null $cursor
* @return string
*/
public function url($cursor)
{
// If we have any extra query string key / value pairs that need to be added
// onto the URL, we will put them in query string form and then attach it
// to the URL. This allows for extra information like sortings storage.
$parameters = is_null($cursor) ? [] : [$this->cursorName => $cursor->encode()];
if (count($this->query) > 0) {
$parameters = array_merge($this->query, $parameters);
}
return $this->path()
.(str_contains($this->path(), '?') ? '&' : '?')
.Arr::query($parameters)
.$this->buildFragment();
}
/**
* Get the URL for the previous page.
*
* @return string|null
*/
public function previousPageUrl()
{
if (is_null($previousCursor = $this->previousCursor())) {
return null;
}
return $this->url($previousCursor);
}
/**
* The URL for the next page, or null.
*
* @return string|null
*/
public function nextPageUrl()
{
if (is_null($nextCursor = $this->nextCursor())) {
return null;
}
return $this->url($nextCursor);
}
/**
* Get the "cursor" that points to the previous set of items.
*
* @return \Illuminate\Pagination\Cursor|null
*/
public function previousCursor()
{
if (is_null($this->cursor) ||
($this->cursor->pointsToPreviousItems() && ! $this->hasMore)) {
return null;
}
if ($this->items->isEmpty()) {
return null;
}
return $this->getCursorForItem($this->items->first(), false);
}
/**
* Get the "cursor" that points to the next set of items.
*
* @return \Illuminate\Pagination\Cursor|null
*/
public function nextCursor()
{
if ((is_null($this->cursor) && ! $this->hasMore) ||
(! is_null($this->cursor) && $this->cursor->pointsToNextItems() && ! $this->hasMore)) {
return null;
}
if ($this->items->isEmpty()) {
return null;
}
return $this->getCursorForItem($this->items->last(), true);
}
/**
* Get a cursor instance for the given item.
*
* @param \ArrayAccess|\stdClass $item
* @param bool $isNext
* @return \Illuminate\Pagination\Cursor
*/
public function getCursorForItem($item, $isNext = true)
{
return new Cursor($this->getParametersForItem($item), $isNext);
}
/**
* Get the cursor parameters for a given object.
*
* @param \ArrayAccess|\stdClass $item
* @return array
*
* @throws \Exception
*/
public function getParametersForItem($item)
{
return collect($this->parameters)
->flip()
->map(function ($_, $parameterName) use ($item) {
if ($item instanceof JsonResource) {
$item = $item->resource;
}
if ($item instanceof Model &&
! is_null($parameter = $this->getPivotParameterForItem($item, $parameterName))) {
return $parameter;
} elseif ($item instanceof ArrayAccess || is_array($item)) {
return $this->ensureParameterIsPrimitive(
$item[$parameterName] ?? $item[Str::afterLast($parameterName, '.')]
);
} elseif (is_object($item)) {
return $this->ensureParameterIsPrimitive(
$item->{$parameterName} ?? $item->{Str::afterLast($parameterName, '.')}
);
}
throw new Exception('Only arrays and objects are supported when cursor paginating items.');
})->toArray();
}
/**
* Get the cursor parameter value from a pivot model if applicable.
*
* @param \ArrayAccess|\stdClass $item
* @param string $parameterName
* @return string|null
*/
protected function getPivotParameterForItem($item, $parameterName)
{
$table = Str::beforeLast($parameterName, '.');
foreach ($item->getRelations() as $relation) {
if ($relation instanceof Pivot && $relation->getTable() === $table) {
return $this->ensureParameterIsPrimitive(
$relation->getAttribute(Str::afterLast($parameterName, '.'))
);
}
}
}
/**
* Ensure the parameter is a primitive type.
*
* This can resolve issues that arise the developer uses a value object for an attribute.
*
* @param mixed $parameter
* @return mixed
*/
protected function ensureParameterIsPrimitive($parameter)
{
return is_object($parameter) && method_exists($parameter, '__toString')
? (string) $parameter
: $parameter;
}
/**
* Get / set the URL fragment to be appended to URLs.
*
* @param string|null $fragment
* @return $this|string|null
*/
public function fragment($fragment = null)
{
if (is_null($fragment)) {
return $this->fragment;
}
$this->fragment = $fragment;
return $this;
}
/**
* Add a set of query string values to the paginator.
*
* @param array|string|null $key
* @param string|null $value
* @return $this
*/
public function appends($key, $value = null)
{
if (is_null($key)) {
return $this;
}
if (is_array($key)) {
return $this->appendArray($key);
}
return $this->addQuery($key, $value);
}
/**
* Add an array of query string values.
*
* @param array $keys
* @return $this
*/
protected function appendArray(array $keys)
{
foreach ($keys as $key => $value) {
$this->addQuery($key, $value);
}
return $this;
}
/**
* Add all current query string values to the paginator.
*
* @return $this
*/
public function withQueryString()
{
if (! is_null($query = Paginator::resolveQueryString())) {
return $this->appends($query);
}
return $this;
}
/**
* Add a query string value to the paginator.
*
* @param string $key
* @param string $value
* @return $this
*/
protected function addQuery($key, $value)
{
if ($key !== $this->cursorName) {
$this->query[$key] = $value;
}
return $this;
}
/**
* Build the full fragment portion of a URL.
*
* @return string
*/
protected function buildFragment()
{
return $this->fragment ? '#'.$this->fragment : '';
}
/**
* Load a set of relationships onto the mixed relationship collection.
*
* @param string $relation
* @param array $relations
* @return $this
*/
public function loadMorph($relation, $relations)
{
$this->getCollection()->loadMorph($relation, $relations);
return $this;
}
/**
* Load a set of relationship counts onto the mixed relationship collection.
*
* @param string $relation
* @param array $relations
* @return $this
*/
public function loadMorphCount($relation, $relations)
{
$this->getCollection()->loadMorphCount($relation, $relations);
return $this;
}
/**
* Get the slice of items being paginated.
*
* @return array
*/
public function items()
{
return $this->items->all();
}
/**
* Transform each item in the slice of items using a callback.
*
* @param callable $callback
* @return $this
*/
public function through(callable $callback)
{
$this->items->transform($callback);
return $this;
}
/**
* Get the number of items shown per page.
*
* @return int
*/
public function perPage()
{
return $this->perPage;
}
/**
* Get the current cursor being paginated.
*
* @return \Illuminate\Pagination\Cursor|null
*/
public function cursor()
{
return $this->cursor;
}
/**
* Get the query string variable used to store the cursor.
*
* @return string
*/
public function getCursorName()
{
return $this->cursorName;
}
/**
* Set the query string variable used to store the cursor.
*
* @param string $name
* @return $this
*/
public function setCursorName($name)
{
$this->cursorName = $name;
return $this;
}
/**
* Set the base path to assign to all URLs.
*
* @param string $path
* @return $this
*/
public function withPath($path)
{
return $this->setPath($path);
}
/**
* Set the base path to assign to all URLs.
*
* @param string $path
* @return $this
*/
public function setPath($path)
{
$this->path = $path;
return $this;
}
/**
* Get the base path for paginator generated URLs.
*
* @return string|null
*/
public function path()
{
return $this->path;
}
/**
* Resolve the current cursor or return the default value.
*
* @param string $cursorName
* @return \Illuminate\Pagination\Cursor|null
*/
public static function resolveCurrentCursor($cursorName = 'cursor', $default = null)
{
if (isset(static::$currentCursorResolver)) {
return call_user_func(static::$currentCursorResolver, $cursorName);
}
return $default;
}
/**
* Set the current cursor resolver callback.
*
* @param \Closure $resolver
* @return void
*/
public static function currentCursorResolver(Closure $resolver)
{
static::$currentCursorResolver = $resolver;
}
/**
* Get an instance of the view factory from the resolver.
*
* @return \Illuminate\Contracts\View\Factory
*/
public static function viewFactory()
{
return Paginator::viewFactory();
}
/**
* Get an iterator for the items.
*
* @return \ArrayIterator
*/
public function getIterator(): Traversable
{
return $this->items->getIterator();
}
/**
* Determine if the list of items is empty.
*
* @return bool
*/
public function isEmpty()
{
return $this->items->isEmpty();
}
/**
* Determine if the list of items is not empty.
*
* @return bool
*/
public function isNotEmpty()
{
return $this->items->isNotEmpty();
}
/**
* Get the number of items for the current page.
*
* @return int
*/
public function count(): int
{
return $this->items->count();
}
/**
* Get the paginator's underlying collection.
*
* @return \Illuminate\Support\Collection
*/
public function getCollection()
{
return $this->items;
}
/**
* Set the paginator's underlying collection.
*
* @param \Illuminate\Support\Collection $collection
* @return $this
*/
public function setCollection(Collection $collection)
{
$this->items = $collection;
return $this;
}
/**
* Get the paginator options.
*
* @return array
*/
public function getOptions()
{
return $this->options;
}
/**
* Determine if the given item exists.
*
* @param mixed $key
* @return bool
*/
public function offsetExists($key): bool
{
return $this->items->has($key);
}
/**
* Get the item at the given offset.
*
* @param mixed $key
* @return mixed
*/
public function offsetGet($key): mixed
{
return $this->items->get($key);
}
/**
* Set the item at the given offset.
*
* @param mixed $key
* @param mixed $value
* @return void
*/
public function offsetSet($key, $value): void
{
$this->items->put($key, $value);
}
/**
* Unset the item at the given key.
*
* @param mixed $key
* @return void
*/
public function offsetUnset($key): void
{
$this->items->forget($key);
}
/**
* Render the contents of the paginator to HTML.
*
* @return string
*/
public function toHtml()
{
return (string) $this->render();
}
/**
* Make dynamic calls into the collection.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
return $this->forwardCallTo($this->getCollection(), $method, $parameters);
}
/**
* Render the contents of the paginator when casting to a string.
*
* @return string
*/
public function __toString()
{
return (string) $this->render();
}
}

View File

@@ -0,0 +1,797 @@
<?php
namespace Illuminate\Pagination;
use Closure;
use Illuminate\Contracts\Support\Htmlable;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Traits\ForwardsCalls;
use Illuminate\Support\Traits\Tappable;
use Traversable;
/**
* @mixin \Illuminate\Support\Collection
*/
abstract class AbstractPaginator implements Htmlable
{
use ForwardsCalls, Tappable;
/**
* All of the items being paginated.
*
* @var \Illuminate\Support\Collection
*/
protected $items;
/**
* The number of items to be shown per page.
*
* @var int
*/
protected $perPage;
/**
* The current page being "viewed".
*
* @var int
*/
protected $currentPage;
/**
* The base path to assign to all URLs.
*
* @var string
*/
protected $path = '/';
/**
* The query parameters to add to all URLs.
*
* @var array
*/
protected $query = [];
/**
* The URL fragment to add to all URLs.
*
* @var string|null
*/
protected $fragment;
/**
* The query string variable used to store the page.
*
* @var string
*/
protected $pageName = 'page';
/**
* The number of links to display on each side of current page link.
*
* @var int
*/
public $onEachSide = 3;
/**
* The paginator options.
*
* @var array
*/
protected $options;
/**
* The current path resolver callback.
*
* @var \Closure
*/
protected static $currentPathResolver;
/**
* The current page resolver callback.
*
* @var \Closure
*/
protected static $currentPageResolver;
/**
* The query string resolver callback.
*
* @var \Closure
*/
protected static $queryStringResolver;
/**
* The view factory resolver callback.
*
* @var \Closure
*/
protected static $viewFactoryResolver;
/**
* The default pagination view.
*
* @var string
*/
public static $defaultView = 'pagination::tailwind';
/**
* The default "simple" pagination view.
*
* @var string
*/
public static $defaultSimpleView = 'pagination::simple-tailwind';
/**
* Determine if the given value is a valid page number.
*
* @param int $page
* @return bool
*/
protected function isValidPageNumber($page)
{
return $page >= 1 && filter_var($page, FILTER_VALIDATE_INT) !== false;
}
/**
* Get the URL for the previous page.
*
* @return string|null
*/
public function previousPageUrl()
{
if ($this->currentPage() > 1) {
return $this->url($this->currentPage() - 1);
}
}
/**
* Create a range of pagination URLs.
*
* @param int $start
* @param int $end
* @return array
*/
public function getUrlRange($start, $end)
{
return collect(range($start, $end))->mapWithKeys(function ($page) {
return [$page => $this->url($page)];
})->all();
}
/**
* Get the URL for a given page number.
*
* @param int $page
* @return string
*/
public function url($page)
{
if ($page <= 0) {
$page = 1;
}
// If we have any extra query string key / value pairs that need to be added
// onto the URL, we will put them in query string form and then attach it
// to the URL. This allows for extra information like sortings storage.
$parameters = [$this->pageName => $page];
if (count($this->query) > 0) {
$parameters = array_merge($this->query, $parameters);
}
return $this->path()
.(str_contains($this->path(), '?') ? '&' : '?')
.Arr::query($parameters)
.$this->buildFragment();
}
/**
* Get / set the URL fragment to be appended to URLs.
*
* @param string|null $fragment
* @return $this|string|null
*/
public function fragment($fragment = null)
{
if (is_null($fragment)) {
return $this->fragment;
}
$this->fragment = $fragment;
return $this;
}
/**
* Add a set of query string values to the paginator.
*
* @param array|string|null $key
* @param string|null $value
* @return $this
*/
public function appends($key, $value = null)
{
if (is_null($key)) {
return $this;
}
if (is_array($key)) {
return $this->appendArray($key);
}
return $this->addQuery($key, $value);
}
/**
* Add an array of query string values.
*
* @param array $keys
* @return $this
*/
protected function appendArray(array $keys)
{
foreach ($keys as $key => $value) {
$this->addQuery($key, $value);
}
return $this;
}
/**
* Add all current query string values to the paginator.
*
* @return $this
*/
public function withQueryString()
{
if (isset(static::$queryStringResolver)) {
return $this->appends(call_user_func(static::$queryStringResolver));
}
return $this;
}
/**
* Add a query string value to the paginator.
*
* @param string $key
* @param string $value
* @return $this
*/
protected function addQuery($key, $value)
{
if ($key !== $this->pageName) {
$this->query[$key] = $value;
}
return $this;
}
/**
* Build the full fragment portion of a URL.
*
* @return string
*/
protected function buildFragment()
{
return $this->fragment ? '#'.$this->fragment : '';
}
/**
* Load a set of relationships onto the mixed relationship collection.
*
* @param string $relation
* @param array $relations
* @return $this
*/
public function loadMorph($relation, $relations)
{
$this->getCollection()->loadMorph($relation, $relations);
return $this;
}
/**
* Load a set of relationship counts onto the mixed relationship collection.
*
* @param string $relation
* @param array $relations
* @return $this
*/
public function loadMorphCount($relation, $relations)
{
$this->getCollection()->loadMorphCount($relation, $relations);
return $this;
}
/**
* Get the slice of items being paginated.
*
* @return array
*/
public function items()
{
return $this->items->all();
}
/**
* Get the number of the first item in the slice.
*
* @return int
*/
public function firstItem()
{
return count($this->items) > 0 ? ($this->currentPage - 1) * $this->perPage + 1 : null;
}
/**
* Get the number of the last item in the slice.
*
* @return int
*/
public function lastItem()
{
return count($this->items) > 0 ? $this->firstItem() + $this->count() - 1 : null;
}
/**
* Transform each item in the slice of items using a callback.
*
* @param callable $callback
* @return $this
*/
public function through(callable $callback)
{
$this->items->transform($callback);
return $this;
}
/**
* Get the number of items shown per page.
*
* @return int
*/
public function perPage()
{
return $this->perPage;
}
/**
* Determine if there are enough items to split into multiple pages.
*
* @return bool
*/
public function hasPages()
{
return $this->currentPage() != 1 || $this->hasMorePages();
}
/**
* Determine if the paginator is on the first page.
*
* @return bool
*/
public function onFirstPage()
{
return $this->currentPage() <= 1;
}
/**
* Determine if the paginator is on the last page.
*
* @return bool
*/
public function onLastPage()
{
return ! $this->hasMorePages();
}
/**
* Get the current page.
*
* @return int
*/
public function currentPage()
{
return $this->currentPage;
}
/**
* Get the query string variable used to store the page.
*
* @return string
*/
public function getPageName()
{
return $this->pageName;
}
/**
* Set the query string variable used to store the page.
*
* @param string $name
* @return $this
*/
public function setPageName($name)
{
$this->pageName = $name;
return $this;
}
/**
* Set the base path to assign to all URLs.
*
* @param string $path
* @return $this
*/
public function withPath($path)
{
return $this->setPath($path);
}
/**
* Set the base path to assign to all URLs.
*
* @param string $path
* @return $this
*/
public function setPath($path)
{
$this->path = $path;
return $this;
}
/**
* Set the number of links to display on each side of current page link.
*
* @param int $count
* @return $this
*/
public function onEachSide($count)
{
$this->onEachSide = $count;
return $this;
}
/**
* Get the base path for paginator generated URLs.
*
* @return string|null
*/
public function path()
{
return $this->path;
}
/**
* Resolve the current request path or return the default value.
*
* @param string $default
* @return string
*/
public static function resolveCurrentPath($default = '/')
{
if (isset(static::$currentPathResolver)) {
return call_user_func(static::$currentPathResolver);
}
return $default;
}
/**
* Set the current request path resolver callback.
*
* @param \Closure $resolver
* @return void
*/
public static function currentPathResolver(Closure $resolver)
{
static::$currentPathResolver = $resolver;
}
/**
* Resolve the current page or return the default value.
*
* @param string $pageName
* @param int $default
* @return int
*/
public static function resolveCurrentPage($pageName = 'page', $default = 1)
{
if (isset(static::$currentPageResolver)) {
return (int) call_user_func(static::$currentPageResolver, $pageName);
}
return $default;
}
/**
* Set the current page resolver callback.
*
* @param \Closure $resolver
* @return void
*/
public static function currentPageResolver(Closure $resolver)
{
static::$currentPageResolver = $resolver;
}
/**
* Resolve the query string or return the default value.
*
* @param string|array|null $default
* @return string
*/
public static function resolveQueryString($default = null)
{
if (isset(static::$queryStringResolver)) {
return (static::$queryStringResolver)();
}
return $default;
}
/**
* Set with query string resolver callback.
*
* @param \Closure $resolver
* @return void
*/
public static function queryStringResolver(Closure $resolver)
{
static::$queryStringResolver = $resolver;
}
/**
* Get an instance of the view factory from the resolver.
*
* @return \Illuminate\Contracts\View\Factory
*/
public static function viewFactory()
{
return call_user_func(static::$viewFactoryResolver);
}
/**
* Set the view factory resolver callback.
*
* @param \Closure $resolver
* @return void
*/
public static function viewFactoryResolver(Closure $resolver)
{
static::$viewFactoryResolver = $resolver;
}
/**
* Set the default pagination view.
*
* @param string $view
* @return void
*/
public static function defaultView($view)
{
static::$defaultView = $view;
}
/**
* Set the default "simple" pagination view.
*
* @param string $view
* @return void
*/
public static function defaultSimpleView($view)
{
static::$defaultSimpleView = $view;
}
/**
* Indicate that Tailwind styling should be used for generated links.
*
* @return void
*/
public static function useTailwind()
{
static::defaultView('pagination::tailwind');
static::defaultSimpleView('pagination::simple-tailwind');
}
/**
* Indicate that Bootstrap 4 styling should be used for generated links.
*
* @return void
*/
public static function useBootstrap()
{
static::useBootstrapFour();
}
/**
* Indicate that Bootstrap 3 styling should be used for generated links.
*
* @return void
*/
public static function useBootstrapThree()
{
static::defaultView('pagination::default');
static::defaultSimpleView('pagination::simple-default');
}
/**
* Indicate that Bootstrap 4 styling should be used for generated links.
*
* @return void
*/
public static function useBootstrapFour()
{
static::defaultView('pagination::bootstrap-4');
static::defaultSimpleView('pagination::simple-bootstrap-4');
}
/**
* Indicate that Bootstrap 5 styling should be used for generated links.
*
* @return void
*/
public static function useBootstrapFive()
{
static::defaultView('pagination::bootstrap-5');
static::defaultSimpleView('pagination::simple-bootstrap-5');
}
/**
* Get an iterator for the items.
*
* @return \ArrayIterator
*/
public function getIterator(): Traversable
{
return $this->items->getIterator();
}
/**
* Determine if the list of items is empty.
*
* @return bool
*/
public function isEmpty()
{
return $this->items->isEmpty();
}
/**
* Determine if the list of items is not empty.
*
* @return bool
*/
public function isNotEmpty()
{
return $this->items->isNotEmpty();
}
/**
* Get the number of items for the current page.
*
* @return int
*/
public function count(): int
{
return $this->items->count();
}
/**
* Get the paginator's underlying collection.
*
* @return \Illuminate\Support\Collection
*/
public function getCollection()
{
return $this->items;
}
/**
* Set the paginator's underlying collection.
*
* @param \Illuminate\Support\Collection $collection
* @return $this
*/
public function setCollection(Collection $collection)
{
$this->items = $collection;
return $this;
}
/**
* Get the paginator options.
*
* @return array
*/
public function getOptions()
{
return $this->options;
}
/**
* Determine if the given item exists.
*
* @param mixed $key
* @return bool
*/
public function offsetExists($key): bool
{
return $this->items->has($key);
}
/**
* Get the item at the given offset.
*
* @param mixed $key
* @return mixed
*/
public function offsetGet($key): mixed
{
return $this->items->get($key);
}
/**
* Set the item at the given offset.
*
* @param mixed $key
* @param mixed $value
* @return void
*/
public function offsetSet($key, $value): void
{
$this->items->put($key, $value);
}
/**
* Unset the item at the given key.
*
* @param mixed $key
* @return void
*/
public function offsetUnset($key): void
{
$this->items->forget($key);
}
/**
* Render the contents of the paginator to HTML.
*
* @return string
*/
public function toHtml()
{
return (string) $this->render();
}
/**
* Make dynamic calls into the collection.
*
* @param string $method
* @param array $parameters
* @return mixed
*/
public function __call($method, $parameters)
{
return $this->forwardCallTo($this->getCollection(), $method, $parameters);
}
/**
* Render the contents of the paginator when casting to a string.
*
* @return string
*/
public function __toString()
{
return (string) $this->render();
}
}

View File

@@ -0,0 +1,132 @@
<?php
namespace Illuminate\Pagination;
use Illuminate\Contracts\Support\Arrayable;
use UnexpectedValueException;
class Cursor implements Arrayable
{
/**
* The parameters associated with the cursor.
*
* @var array
*/
protected $parameters;
/**
* Determine whether the cursor points to the next or previous set of items.
*
* @var bool
*/
protected $pointsToNextItems;
/**
* Create a new cursor instance.
*
* @param array $parameters
* @param bool $pointsToNextItems
*/
public function __construct(array $parameters, $pointsToNextItems = true)
{
$this->parameters = $parameters;
$this->pointsToNextItems = $pointsToNextItems;
}
/**
* Get the given parameter from the cursor.
*
* @param string $parameterName
* @return string|null
*
* @throws \UnexpectedValueException
*/
public function parameter(string $parameterName)
{
if (! array_key_exists($parameterName, $this->parameters)) {
throw new UnexpectedValueException("Unable to find parameter [{$parameterName}] in pagination item.");
}
return $this->parameters[$parameterName];
}
/**
* Get the given parameters from the cursor.
*
* @param array $parameterNames
* @return array
*/
public function parameters(array $parameterNames)
{
return collect($parameterNames)->map(function ($parameterName) {
return $this->parameter($parameterName);
})->toArray();
}
/**
* Determine whether the cursor points to the next set of items.
*
* @return bool
*/
public function pointsToNextItems()
{
return $this->pointsToNextItems;
}
/**
* Determine whether the cursor points to the previous set of items.
*
* @return bool
*/
public function pointsToPreviousItems()
{
return ! $this->pointsToNextItems;
}
/**
* Get the array representation of the cursor.
*
* @return array
*/
public function toArray()
{
return array_merge($this->parameters, [
'_pointsToNextItems' => $this->pointsToNextItems,
]);
}
/**
* Get the encoded string representation of the cursor to construct a URL.
*
* @return string
*/
public function encode()
{
return str_replace(['+', '/', '='], ['-', '_', ''], base64_encode(json_encode($this->toArray())));
}
/**
* Get a cursor instance from the encoded string representation.
*
* @param string|null $encodedString
* @return static|null
*/
public static function fromEncoded($encodedString)
{
if (! is_string($encodedString)) {
return null;
}
$parameters = json_decode(base64_decode(str_replace(['-', '_'], ['+', '/'], $encodedString)), true);
if (json_last_error() !== JSON_ERROR_NONE) {
return null;
}
$pointsToNextItems = $parameters['_pointsToNextItems'];
unset($parameters['_pointsToNextItems']);
return new static($parameters, $pointsToNextItems);
}
}

View File

@@ -0,0 +1,172 @@
<?php
namespace Illuminate\Pagination;
use ArrayAccess;
use Countable;
use Illuminate\Contracts\Pagination\CursorPaginator as PaginatorContract;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Contracts\Support\Jsonable;
use Illuminate\Support\Collection;
use IteratorAggregate;
use JsonSerializable;
class CursorPaginator extends AbstractCursorPaginator implements Arrayable, ArrayAccess, Countable, IteratorAggregate, Jsonable, JsonSerializable, PaginatorContract
{
/**
* Indicates whether there are more items in the data source.
*
* @return bool
*/
protected $hasMore;
/**
* Create a new paginator instance.
*
* @param mixed $items
* @param int $perPage
* @param \Illuminate\Pagination\Cursor|null $cursor
* @param array $options (path, query, fragment, pageName)
* @return void
*/
public function __construct($items, $perPage, $cursor = null, array $options = [])
{
$this->options = $options;
foreach ($options as $key => $value) {
$this->{$key} = $value;
}
$this->perPage = (int) $perPage;
$this->cursor = $cursor;
$this->path = $this->path !== '/' ? rtrim($this->path, '/') : $this->path;
$this->setItems($items);
}
/**
* Set the items for the paginator.
*
* @param mixed $items
* @return void
*/
protected function setItems($items)
{
$this->items = $items instanceof Collection ? $items : Collection::make($items);
$this->hasMore = $this->items->count() > $this->perPage;
$this->items = $this->items->slice(0, $this->perPage);
if (! is_null($this->cursor) && $this->cursor->pointsToPreviousItems()) {
$this->items = $this->items->reverse()->values();
}
}
/**
* Render the paginator using the given view.
*
* @param string|null $view
* @param array $data
* @return \Illuminate\Contracts\Support\Htmlable
*/
public function links($view = null, $data = [])
{
return $this->render($view, $data);
}
/**
* Render the paginator using the given view.
*
* @param string|null $view
* @param array $data
* @return \Illuminate\Contracts\Support\Htmlable
*/
public function render($view = null, $data = [])
{
return static::viewFactory()->make($view ?: Paginator::$defaultSimpleView, array_merge($data, [
'paginator' => $this,
]));
}
/**
* Determine if there are more items in the data source.
*
* @return bool
*/
public function hasMorePages()
{
return (is_null($this->cursor) && $this->hasMore) ||
(! is_null($this->cursor) && $this->cursor->pointsToNextItems() && $this->hasMore) ||
(! is_null($this->cursor) && $this->cursor->pointsToPreviousItems());
}
/**
* Determine if there are enough items to split into multiple pages.
*
* @return bool
*/
public function hasPages()
{
return ! $this->onFirstPage() || $this->hasMorePages();
}
/**
* Determine if the paginator is on the first page.
*
* @return bool
*/
public function onFirstPage()
{
return is_null($this->cursor) || ($this->cursor->pointsToPreviousItems() && ! $this->hasMore);
}
/**
* Determine if the paginator is on the last page.
*
* @return bool
*/
public function onLastPage()
{
return ! $this->hasMorePages();
}
/**
* Get the instance as an array.
*
* @return array
*/
public function toArray()
{
return [
'data' => $this->items->toArray(),
'path' => $this->path(),
'per_page' => $this->perPage(),
'next_cursor' => $this->nextCursor()?->encode(),
'next_page_url' => $this->nextPageUrl(),
'prev_cursor' => $this->previousCursor()?->encode(),
'prev_page_url' => $this->previousPageUrl(),
];
}
/**
* Convert the object into something JSON serializable.
*
* @return array
*/
public function jsonSerialize(): array
{
return $this->toArray();
}
/**
* Convert the object to its JSON representation.
*
* @param int $options
* @return string
*/
public function toJson($options = 0)
{
return json_encode($this->jsonSerialize(), $options);
}
}

View File

@@ -0,0 +1,21 @@
The MIT License (MIT)
Copyright (c) Taylor Otwell
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -0,0 +1,231 @@
<?php
namespace Illuminate\Pagination;
use ArrayAccess;
use Countable;
use Illuminate\Contracts\Pagination\LengthAwarePaginator as LengthAwarePaginatorContract;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Contracts\Support\Jsonable;
use Illuminate\Support\Collection;
use IteratorAggregate;
use JsonSerializable;
class LengthAwarePaginator extends AbstractPaginator implements Arrayable, ArrayAccess, Countable, IteratorAggregate, Jsonable, JsonSerializable, LengthAwarePaginatorContract
{
/**
* The total number of items before slicing.
*
* @var int
*/
protected $total;
/**
* The last available page.
*
* @var int
*/
protected $lastPage;
/**
* Create a new paginator instance.
*
* @param mixed $items
* @param int $total
* @param int $perPage
* @param int|null $currentPage
* @param array $options (path, query, fragment, pageName)
* @return void
*/
public function __construct($items, $total, $perPage, $currentPage = null, array $options = [])
{
$this->options = $options;
foreach ($options as $key => $value) {
$this->{$key} = $value;
}
$this->total = $total;
$this->perPage = (int) $perPage;
$this->lastPage = max((int) ceil($total / $perPage), 1);
$this->path = $this->path !== '/' ? rtrim($this->path, '/') : $this->path;
$this->currentPage = $this->setCurrentPage($currentPage, $this->pageName);
$this->items = $items instanceof Collection ? $items : Collection::make($items);
}
/**
* Get the current page for the request.
*
* @param int $currentPage
* @param string $pageName
* @return int
*/
protected function setCurrentPage($currentPage, $pageName)
{
$currentPage = $currentPage ?: static::resolveCurrentPage($pageName);
return $this->isValidPageNumber($currentPage) ? (int) $currentPage : 1;
}
/**
* Render the paginator using the given view.
*
* @param string|null $view
* @param array $data
* @return \Illuminate\Contracts\Support\Htmlable
*/
public function links($view = null, $data = [])
{
return $this->render($view, $data);
}
/**
* Render the paginator using the given view.
*
* @param string|null $view
* @param array $data
* @return \Illuminate\Contracts\Support\Htmlable
*/
public function render($view = null, $data = [])
{
return static::viewFactory()->make($view ?: static::$defaultView, array_merge($data, [
'paginator' => $this,
'elements' => $this->elements(),
]));
}
/**
* Get the paginator links as a collection (for JSON responses).
*
* @return \Illuminate\Support\Collection
*/
public function linkCollection()
{
return collect($this->elements())->flatMap(function ($item) {
if (! is_array($item)) {
return [['url' => null, 'label' => '...', 'active' => false]];
}
return collect($item)->map(function ($url, $page) {
return [
'url' => $url,
'label' => (string) $page,
'active' => $this->currentPage() === $page,
];
});
})->prepend([
'url' => $this->previousPageUrl(),
'label' => function_exists('__') ? __('pagination.previous') : 'Previous',
'active' => false,
])->push([
'url' => $this->nextPageUrl(),
'label' => function_exists('__') ? __('pagination.next') : 'Next',
'active' => false,
]);
}
/**
* Get the array of elements to pass to the view.
*
* @return array
*/
protected function elements()
{
$window = UrlWindow::make($this);
return array_filter([
$window['first'],
is_array($window['slider']) ? '...' : null,
$window['slider'],
is_array($window['last']) ? '...' : null,
$window['last'],
]);
}
/**
* Get the total number of items being paginated.
*
* @return int
*/
public function total()
{
return $this->total;
}
/**
* Determine if there are more items in the data source.
*
* @return bool
*/
public function hasMorePages()
{
return $this->currentPage() < $this->lastPage();
}
/**
* Get the URL for the next page.
*
* @return string|null
*/
public function nextPageUrl()
{
if ($this->hasMorePages()) {
return $this->url($this->currentPage() + 1);
}
}
/**
* Get the last page.
*
* @return int
*/
public function lastPage()
{
return $this->lastPage;
}
/**
* Get the instance as an array.
*
* @return array
*/
public function toArray()
{
return [
'current_page' => $this->currentPage(),
'data' => $this->items->toArray(),
'first_page_url' => $this->url(1),
'from' => $this->firstItem(),
'last_page' => $this->lastPage(),
'last_page_url' => $this->url($this->lastPage()),
'links' => $this->linkCollection()->toArray(),
'next_page_url' => $this->nextPageUrl(),
'path' => $this->path(),
'per_page' => $this->perPage(),
'prev_page_url' => $this->previousPageUrl(),
'to' => $this->lastItem(),
'total' => $this->total(),
];
}
/**
* Convert the object into something JSON serializable.
*
* @return array
*/
public function jsonSerialize(): array
{
return $this->toArray();
}
/**
* Convert the object to its JSON representation.
*
* @param int $options
* @return string
*/
public function toJson($options = 0)
{
return json_encode($this->jsonSerialize(), $options);
}
}

View File

@@ -0,0 +1,34 @@
<?php
namespace Illuminate\Pagination;
use Illuminate\Support\ServiceProvider;
class PaginationServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
$this->loadViewsFrom(__DIR__.'/resources/views', 'pagination');
if ($this->app->runningInConsole()) {
$this->publishes([
__DIR__.'/resources/views' => $this->app->resourcePath('views/vendor/pagination'),
], 'laravel-pagination');
}
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
PaginationState::resolveUsing($this->app);
}
}

View File

@@ -0,0 +1,35 @@
<?php
namespace Illuminate\Pagination;
class PaginationState
{
/**
* Bind the pagination state resolvers using the given application container as a base.
*
* @param \Illuminate\Contracts\Foundation\Application $app
* @return void
*/
public static function resolveUsing($app)
{
Paginator::viewFactoryResolver(fn () => $app['view']);
Paginator::currentPathResolver(fn () => $app['request']->url());
Paginator::currentPageResolver(function ($pageName = 'page') use ($app) {
$page = $app['request']->input($pageName);
if (filter_var($page, FILTER_VALIDATE_INT) !== false && (int) $page >= 1) {
return (int) $page;
}
return 1;
});
Paginator::queryStringResolver(fn () => $app['request']->query());
CursorPaginator::currentCursorResolver(function ($cursorName = 'cursor') use ($app) {
return Cursor::fromEncoded($app['request']->input($cursorName));
});
}
}

View File

@@ -0,0 +1,176 @@
<?php
namespace Illuminate\Pagination;
use ArrayAccess;
use Countable;
use Illuminate\Contracts\Pagination\Paginator as PaginatorContract;
use Illuminate\Contracts\Support\Arrayable;
use Illuminate\Contracts\Support\Jsonable;
use Illuminate\Support\Collection;
use IteratorAggregate;
use JsonSerializable;
class Paginator extends AbstractPaginator implements Arrayable, ArrayAccess, Countable, IteratorAggregate, Jsonable, JsonSerializable, PaginatorContract
{
/**
* Determine if there are more items in the data source.
*
* @return bool
*/
protected $hasMore;
/**
* Create a new paginator instance.
*
* @param mixed $items
* @param int $perPage
* @param int|null $currentPage
* @param array $options (path, query, fragment, pageName)
* @return void
*/
public function __construct($items, $perPage, $currentPage = null, array $options = [])
{
$this->options = $options;
foreach ($options as $key => $value) {
$this->{$key} = $value;
}
$this->perPage = $perPage;
$this->currentPage = $this->setCurrentPage($currentPage);
$this->path = $this->path !== '/' ? rtrim($this->path, '/') : $this->path;
$this->setItems($items);
}
/**
* Get the current page for the request.
*
* @param int $currentPage
* @return int
*/
protected function setCurrentPage($currentPage)
{
$currentPage = $currentPage ?: static::resolveCurrentPage();
return $this->isValidPageNumber($currentPage) ? (int) $currentPage : 1;
}
/**
* Set the items for the paginator.
*
* @param mixed $items
* @return void
*/
protected function setItems($items)
{
$this->items = $items instanceof Collection ? $items : Collection::make($items);
$this->hasMore = $this->items->count() > $this->perPage;
$this->items = $this->items->slice(0, $this->perPage);
}
/**
* Get the URL for the next page.
*
* @return string|null
*/
public function nextPageUrl()
{
if ($this->hasMorePages()) {
return $this->url($this->currentPage() + 1);
}
}
/**
* Render the paginator using the given view.
*
* @param string|null $view
* @param array $data
* @return string
*/
public function links($view = null, $data = [])
{
return $this->render($view, $data);
}
/**
* Render the paginator using the given view.
*
* @param string|null $view
* @param array $data
* @return \Illuminate\Contracts\Support\Htmlable
*/
public function render($view = null, $data = [])
{
return static::viewFactory()->make($view ?: static::$defaultSimpleView, array_merge($data, [
'paginator' => $this,
]));
}
/**
* Manually indicate that the paginator does have more pages.
*
* @param bool $hasMore
* @return $this
*/
public function hasMorePagesWhen($hasMore = true)
{
$this->hasMore = $hasMore;
return $this;
}
/**
* Determine if there are more items in the data source.
*
* @return bool
*/
public function hasMorePages()
{
return $this->hasMore;
}
/**
* Get the instance as an array.
*
* @return array
*/
public function toArray()
{
return [
'current_page' => $this->currentPage(),
'data' => $this->items->toArray(),
'first_page_url' => $this->url(1),
'from' => $this->firstItem(),
'next_page_url' => $this->nextPageUrl(),
'path' => $this->path(),
'per_page' => $this->perPage(),
'prev_page_url' => $this->previousPageUrl(),
'to' => $this->lastItem(),
];
}
/**
* Convert the object into something JSON serializable.
*
* @return array
*/
public function jsonSerialize(): array
{
return $this->toArray();
}
/**
* Convert the object to its JSON representation.
*
* @param int $options
* @return string
*/
public function toJson($options = 0)
{
return json_encode($this->jsonSerialize(), $options);
}
}

View File

@@ -0,0 +1,220 @@
<?php
namespace Illuminate\Pagination;
use Illuminate\Contracts\Pagination\LengthAwarePaginator as PaginatorContract;
class UrlWindow
{
/**
* The paginator implementation.
*
* @var \Illuminate\Contracts\Pagination\LengthAwarePaginator
*/
protected $paginator;
/**
* Create a new URL window instance.
*
* @param \Illuminate\Contracts\Pagination\LengthAwarePaginator $paginator
* @return void
*/
public function __construct(PaginatorContract $paginator)
{
$this->paginator = $paginator;
}
/**
* Create a new URL window instance.
*
* @param \Illuminate\Contracts\Pagination\LengthAwarePaginator $paginator
* @return array
*/
public static function make(PaginatorContract $paginator)
{
return (new static($paginator))->get();
}
/**
* Get the window of URLs to be shown.
*
* @return array
*/
public function get()
{
$onEachSide = $this->paginator->onEachSide;
if ($this->paginator->lastPage() < ($onEachSide * 2) + 8) {
return $this->getSmallSlider();
}
return $this->getUrlSlider($onEachSide);
}
/**
* Get the slider of URLs there are not enough pages to slide.
*
* @return array
*/
protected function getSmallSlider()
{
return [
'first' => $this->paginator->getUrlRange(1, $this->lastPage()),
'slider' => null,
'last' => null,
];
}
/**
* Create a URL slider links.
*
* @param int $onEachSide
* @return array
*/
protected function getUrlSlider($onEachSide)
{
$window = $onEachSide + 4;
if (! $this->hasPages()) {
return ['first' => null, 'slider' => null, 'last' => null];
}
// If the current page is very close to the beginning of the page range, we will
// just render the beginning of the page range, followed by the last 2 of the
// links in this list, since we will not have room to create a full slider.
if ($this->currentPage() <= $window) {
return $this->getSliderTooCloseToBeginning($window, $onEachSide);
}
// If the current page is close to the ending of the page range we will just get
// this first couple pages, followed by a larger window of these ending pages
// since we're too close to the end of the list to create a full on slider.
elseif ($this->currentPage() > ($this->lastPage() - $window)) {
return $this->getSliderTooCloseToEnding($window, $onEachSide);
}
// If we have enough room on both sides of the current page to build a slider we
// will surround it with both the beginning and ending caps, with this window
// of pages in the middle providing a Google style sliding paginator setup.
return $this->getFullSlider($onEachSide);
}
/**
* Get the slider of URLs when too close to the beginning of the window.
*
* @param int $window
* @param int $onEachSide
* @return array
*/
protected function getSliderTooCloseToBeginning($window, $onEachSide)
{
return [
'first' => $this->paginator->getUrlRange(1, $window + $onEachSide),
'slider' => null,
'last' => $this->getFinish(),
];
}
/**
* Get the slider of URLs when too close to the ending of the window.
*
* @param int $window
* @param int $onEachSide
* @return array
*/
protected function getSliderTooCloseToEnding($window, $onEachSide)
{
$last = $this->paginator->getUrlRange(
$this->lastPage() - ($window + ($onEachSide - 1)),
$this->lastPage()
);
return [
'first' => $this->getStart(),
'slider' => null,
'last' => $last,
];
}
/**
* Get the slider of URLs when a full slider can be made.
*
* @param int $onEachSide
* @return array
*/
protected function getFullSlider($onEachSide)
{
return [
'first' => $this->getStart(),
'slider' => $this->getAdjacentUrlRange($onEachSide),
'last' => $this->getFinish(),
];
}
/**
* Get the page range for the current page window.
*
* @param int $onEachSide
* @return array
*/
public function getAdjacentUrlRange($onEachSide)
{
return $this->paginator->getUrlRange(
$this->currentPage() - $onEachSide,
$this->currentPage() + $onEachSide
);
}
/**
* Get the starting URLs of a pagination slider.
*
* @return array
*/
public function getStart()
{
return $this->paginator->getUrlRange(1, 2);
}
/**
* Get the ending URLs of a pagination slider.
*
* @return array
*/
public function getFinish()
{
return $this->paginator->getUrlRange(
$this->lastPage() - 1,
$this->lastPage()
);
}
/**
* Determine if the underlying paginator being presented has pages to show.
*
* @return bool
*/
public function hasPages()
{
return $this->paginator->lastPage() > 1;
}
/**
* Get the current page from the paginator.
*
* @return int
*/
protected function currentPage()
{
return $this->paginator->currentPage();
}
/**
* Get the last page from the paginator.
*
* @return int
*/
protected function lastPage()
{
return $this->paginator->lastPage();
}
}

View File

@@ -0,0 +1,37 @@
{
"name": "illuminate/pagination",
"description": "The Illuminate Pagination package.",
"license": "MIT",
"homepage": "https://laravel.com",
"support": {
"issues": "https://github.com/laravel/framework/issues",
"source": "https://github.com/laravel/framework"
},
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"require": {
"php": "^8.0.2",
"ext-filter": "*",
"illuminate/collections": "^9.0",
"illuminate/contracts": "^9.0",
"illuminate/support": "^9.0"
},
"autoload": {
"psr-4": {
"Illuminate\\Pagination\\": ""
}
},
"extra": {
"branch-alias": {
"dev-master": "9.x-dev"
}
},
"config": {
"sort-packages": true
},
"minimum-stability": "dev"
}

View File

@@ -0,0 +1,46 @@
@if ($paginator->hasPages())
<nav>
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
<span class="page-link" aria-hidden="true">&lsaquo;</span>
</li>
@else
<li class="page-item">
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">&lsaquo;</a>
</li>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<li class="page-item disabled" aria-disabled="true"><span class="page-link">{{ $element }}</span></li>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<li class="page-item active" aria-current="page"><span class="page-link">{{ $page }}</span></li>
@else
<li class="page-item"><a class="page-link" href="{{ $url }}">{{ $page }}</a></li>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li class="page-item">
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">&rsaquo;</a>
</li>
@else
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
<span class="page-link" aria-hidden="true">&rsaquo;</span>
</li>
@endif
</ul>
</nav>
@endif

View File

@@ -0,0 +1,88 @@
@if ($paginator->hasPages())
<nav class="d-flex justify-items-center justify-content-between">
<div class="d-flex justify-content-between flex-fill d-sm-none">
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="page-item disabled" aria-disabled="true">
<span class="page-link">@lang('pagination.previous')</span>
</li>
@else
<li class="page-item">
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev">@lang('pagination.previous')</a>
</li>
@endif
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li class="page-item">
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next">@lang('pagination.next')</a>
</li>
@else
<li class="page-item disabled" aria-disabled="true">
<span class="page-link">@lang('pagination.next')</span>
</li>
@endif
</ul>
</div>
<div class="d-none flex-sm-fill d-sm-flex align-items-sm-center justify-content-sm-between">
<div>
<p class="small text-muted">
{!! __('Showing') !!}
<span class="fw-semibold">{{ $paginator->firstItem() }}</span>
{!! __('to') !!}
<span class="fw-semibold">{{ $paginator->lastItem() }}</span>
{!! __('of') !!}
<span class="fw-semibold">{{ $paginator->total() }}</span>
{!! __('results') !!}
</p>
</div>
<div>
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
<span class="page-link" aria-hidden="true">&lsaquo;</span>
</li>
@else
<li class="page-item">
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">&lsaquo;</a>
</li>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<li class="page-item disabled" aria-disabled="true"><span class="page-link">{{ $element }}</span></li>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<li class="page-item active" aria-current="page"><span class="page-link">{{ $page }}</span></li>
@else
<li class="page-item"><a class="page-link" href="{{ $url }}">{{ $page }}</a></li>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li class="page-item">
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">&rsaquo;</a>
</li>
@else
<li class="page-item disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
<span class="page-link" aria-hidden="true">&rsaquo;</span>
</li>
@endif
</ul>
</div>
</div>
</nav>
@endif

View File

@@ -0,0 +1,46 @@
@if ($paginator->hasPages())
<nav>
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="disabled" aria-disabled="true" aria-label="@lang('pagination.previous')">
<span aria-hidden="true">&lsaquo;</span>
</li>
@else
<li>
<a href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')">&lsaquo;</a>
</li>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<li class="disabled" aria-disabled="true"><span>{{ $element }}</span></li>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<li class="active" aria-current="page"><span>{{ $page }}</span></li>
@else
<li><a href="{{ $url }}">{{ $page }}</a></li>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li>
<a href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">&rsaquo;</a>
</li>
@else
<li class="disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
<span aria-hidden="true">&rsaquo;</span>
</li>
@endif
</ul>
</nav>
@endif

View File

@@ -0,0 +1,36 @@
@if ($paginator->hasPages())
<div class="ui pagination menu" role="navigation">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<a class="icon item disabled" aria-disabled="true" aria-label="@lang('pagination.previous')"> <i class="left chevron icon"></i> </a>
@else
<a class="icon item" href="{{ $paginator->previousPageUrl() }}" rel="prev" aria-label="@lang('pagination.previous')"> <i class="left chevron icon"></i> </a>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<a class="icon item disabled" aria-disabled="true">{{ $element }}</a>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<a class="item active" href="{{ $url }}" aria-current="page">{{ $page }}</a>
@else
<a class="item" href="{{ $url }}">{{ $page }}</a>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<a class="icon item" href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')"> <i class="right chevron icon"></i> </a>
@else
<a class="icon item disabled" aria-disabled="true" aria-label="@lang('pagination.next')"> <i class="right chevron icon"></i> </a>
@endif
</div>
@endif

View File

@@ -0,0 +1,27 @@
@if ($paginator->hasPages())
<nav>
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="page-item disabled" aria-disabled="true">
<span class="page-link">@lang('pagination.previous')</span>
</li>
@else
<li class="page-item">
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev">@lang('pagination.previous')</a>
</li>
@endif
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li class="page-item">
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next">@lang('pagination.next')</a>
</li>
@else
<li class="page-item disabled" aria-disabled="true">
<span class="page-link">@lang('pagination.next')</span>
</li>
@endif
</ul>
</nav>
@endif

View File

@@ -0,0 +1,29 @@
@if ($paginator->hasPages())
<nav role="navigation" aria-label="Pagination Navigation">
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="page-item disabled" aria-disabled="true">
<span class="page-link">{!! __('pagination.previous') !!}</span>
</li>
@else
<li class="page-item">
<a class="page-link" href="{{ $paginator->previousPageUrl() }}" rel="prev">
{!! __('pagination.previous') !!}
</a>
</li>
@endif
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li class="page-item">
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next">{!! __('pagination.next') !!}</a>
</li>
@else
<li class="page-item disabled" aria-disabled="true">
<span class="page-link">{!! __('pagination.next') !!}</span>
</li>
@endif
</ul>
</nav>
@endif

View File

@@ -0,0 +1,19 @@
@if ($paginator->hasPages())
<nav>
<ul class="pagination">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="disabled" aria-disabled="true"><span>@lang('pagination.previous')</span></li>
@else
<li><a href="{{ $paginator->previousPageUrl() }}" rel="prev">@lang('pagination.previous')</a></li>
@endif
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li><a href="{{ $paginator->nextPageUrl() }}" rel="next">@lang('pagination.next')</a></li>
@else
<li class="disabled" aria-disabled="true"><span>@lang('pagination.next')</span></li>
@endif
</ul>
</nav>
@endif

View File

@@ -0,0 +1,25 @@
@if ($paginator->hasPages())
<nav role="navigation" aria-label="Pagination Navigation" class="flex justify-between">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md">
{!! __('pagination.previous') !!}
</span>
@else
<a href="{{ $paginator->previousPageUrl() }}" rel="prev" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
{!! __('pagination.previous') !!}
</a>
@endif
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<a href="{{ $paginator->nextPageUrl() }}" rel="next" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
{!! __('pagination.next') !!}
</a>
@else
<span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md">
{!! __('pagination.next') !!}
</span>
@endif
</nav>
@endif

View File

@@ -0,0 +1,106 @@
@if ($paginator->hasPages())
<nav role="navigation" aria-label="{{ __('Pagination Navigation') }}" class="flex items-center justify-between">
<div class="flex justify-between flex-1 sm:hidden">
@if ($paginator->onFirstPage())
<span class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md">
{!! __('pagination.previous') !!}
</span>
@else
<a href="{{ $paginator->previousPageUrl() }}" class="relative inline-flex items-center px-4 py-2 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
{!! __('pagination.previous') !!}
</a>
@endif
@if ($paginator->hasMorePages())
<a href="{{ $paginator->nextPageUrl() }}" class="relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 rounded-md hover:text-gray-500 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150">
{!! __('pagination.next') !!}
</a>
@else
<span class="relative inline-flex items-center px-4 py-2 ml-3 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5 rounded-md">
{!! __('pagination.next') !!}
</span>
@endif
</div>
<div class="hidden sm:flex-1 sm:flex sm:items-center sm:justify-between">
<div>
<p class="text-sm text-gray-700 leading-5">
{!! __('Showing') !!}
@if ($paginator->firstItem())
<span class="font-medium">{{ $paginator->firstItem() }}</span>
{!! __('to') !!}
<span class="font-medium">{{ $paginator->lastItem() }}</span>
@else
{{ $paginator->count() }}
@endif
{!! __('of') !!}
<span class="font-medium">{{ $paginator->total() }}</span>
{!! __('results') !!}
</p>
</div>
<div>
<span class="relative z-0 inline-flex shadow-sm rounded-md">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<span aria-disabled="true" aria-label="{{ __('pagination.previous') }}">
<span class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-l-md leading-5" aria-hidden="true">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
</svg>
</span>
</span>
@else
<a href="{{ $paginator->previousPageUrl() }}" rel="prev" class="relative inline-flex items-center px-2 py-2 text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-l-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.previous') }}">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M12.707 5.293a1 1 0 010 1.414L9.414 10l3.293 3.293a1 1 0 01-1.414 1.414l-4-4a1 1 0 010-1.414l4-4a1 1 0 011.414 0z" clip-rule="evenodd" />
</svg>
</a>
@endif
{{-- Pagination Elements --}}
@foreach ($elements as $element)
{{-- "Three Dots" Separator --}}
@if (is_string($element))
<span aria-disabled="true">
<span class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 cursor-default leading-5">{{ $element }}</span>
</span>
@endif
{{-- Array Of Links --}}
@if (is_array($element))
@foreach ($element as $page => $url)
@if ($page == $paginator->currentPage())
<span aria-current="page">
<span class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default leading-5">{{ $page }}</span>
</span>
@else
<a href="{{ $url }}" class="relative inline-flex items-center px-4 py-2 -ml-px text-sm font-medium text-gray-700 bg-white border border-gray-300 leading-5 hover:text-gray-500 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-700 transition ease-in-out duration-150" aria-label="{{ __('Go to page :page', ['page' => $page]) }}">
{{ $page }}
</a>
@endif
@endforeach
@endif
@endforeach
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<a href="{{ $paginator->nextPageUrl() }}" rel="next" class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 rounded-r-md leading-5 hover:text-gray-400 focus:z-10 focus:outline-none focus:ring ring-gray-300 focus:border-blue-300 active:bg-gray-100 active:text-gray-500 transition ease-in-out duration-150" aria-label="{{ __('pagination.next') }}">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
</svg>
</a>
@else
<span aria-disabled="true" aria-label="{{ __('pagination.next') }}">
<span class="relative inline-flex items-center px-2 py-2 -ml-px text-sm font-medium text-gray-500 bg-white border border-gray-300 cursor-default rounded-r-md leading-5" aria-hidden="true">
<svg class="w-5 h-5" fill="currentColor" viewBox="0 0 20 20">
<path fill-rule="evenodd" d="M7.293 14.707a1 1 0 010-1.414L10.586 10 7.293 6.707a1 1 0 011.414-1.414l4 4a1 1 0 010 1.414l-4 4a1 1 0 01-1.414 0z" clip-rule="evenodd" />
</svg>
</span>
</span>
@endif
</span>
</div>
</div>
</nav>
@endif