Merge pull request #3372 from CachetHQ/laravel-upgrade

Upgraded to Laravel 5.7
This commit is contained in:
Graham Campbell
2018-12-28 16:32:56 +00:00
committed by GitHub
36 changed files with 1321 additions and 317 deletions

View File

@@ -0,0 +1,88 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Foundation\Exceptions\Displayers;
use CachetHQ\Cachet\Settings\ReadException;
use Exception;
use GrahamCampbell\Exceptions\Displayers\DisplayerInterface;
use Illuminate\Http\Request;
class SettingsDisplayer implements DisplayerInterface
{
/**
* The request instance.
*
* @var \Illuminate\Http\Request
*/
protected $request;
/**
* Create a new redirect displayer instance.
*
* @param \Illuminate\Http\Request $request
*
* @return void
*/
public function __construct(Request $request)
{
$this->request = $request;
}
/**
* Get the error response associated with the given exception.
*
* @param \Exception $exception
* @param string $id
* @param int $code
* @param string[] $headers
*
* @return \Symfony\Component\HttpFoundation\Response
*/
public function display(Exception $exception, string $id, int $code, array $headers)
{
return cachet_redirect('setup');
}
/**
* Get the supported content type.
*
* @return string
*/
public function contentType()
{
return 'text/html';
}
/**
* Can we display the exception?
*
* @param \Exception $original
* @param \Exception $transformed
* @param int $code
*
* @return bool
*/
public function canDisplay(Exception $original, Exception $transformed, int $code)
{
return ($transformed instanceof ReadException) && !$this->request->is('setup*');
}
/**
* Do we provide verbose information about the exception?
*
* @return bool
*/
public function isVerbose()
{
return false;
}
}

View File

@@ -53,7 +53,7 @@ class ReadyForUse
*/
public function handle(Request $request, Closure $next)
{
if (!$this->settings->get('app_name')) {
if (!$request->is('setup*') && !$this->settings->get('app_name')) {
return cachet_redirect('setup');
}

View File

@@ -11,6 +11,7 @@
namespace CachetHQ\Cachet\Http\Middleware;
use CachetHQ\Cachet\Settings\ReadException;
use CachetHQ\Cachet\Settings\Repository;
use Closure;
use Illuminate\Http\Request;
@@ -53,8 +54,12 @@ class SetupAlreadyCompleted
*/
public function handle(Request $request, Closure $next)
{
if ($this->settings->get('app_name')) {
return cachet_redirect('dashboard');
try {
if ($this->settings->get('app_name')) {
return cachet_redirect('dashboard');
}
} catch (ReadException $e) {
// not setup then!
}
return $next($request);

View File

@@ -0,0 +1,34 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Settings;
use Exception;
/**
* This is the read exception class.
*
* @author Graham Campbell <graham@alt-three.com>
*/
class ReadException extends SettingsException
{
/**
* Create a new read exception instance.
*
* @param \Exception $e
*
* @return void
*/
public function __construct(Exception $e)
{
parent::__construct('Unable to read Cachet settings', $e);
}
}

View File

@@ -12,6 +12,7 @@
namespace CachetHQ\Cachet\Settings;
use CachetHQ\Cachet\Models\Setting;
use Exception;
/**
* This is the settings repository class.
@@ -59,13 +60,19 @@ class Repository
/**
* Returns a setting from the database.
*
* @throws \CachetHQ\Cachet\Settings\ReadException
*
* @return array
*/
public function all()
{
return $this->model->all(['name', 'value'])->pluck('value', 'name')->map(function ($value, $name) {
return $this->castSetting($name, $value);
})->toArray();
try {
return $this->model->all(['name', 'value'])->pluck('value', 'name')->map(function ($value, $name) {
return $this->castSetting($name, $value);
})->toArray();
} catch (Exception $e) {
throw new ReadException($e);
}
}
/**
@@ -74,16 +81,22 @@ class Repository
* @param string $name
* @param string|null $value
*
* @throws \CachetHQ\Cachet\Settings\WriteException
*
* @return void
*/
public function set($name, $value)
{
$this->stale = true;
if ($value === null) {
$this->model->where('name', '=', $name)->delete();
} else {
$this->model->updateOrCreate(compact('name'), compact('value'));
try {
if ($value === null) {
$this->model->where('name', '=', $name)->delete();
} else {
$this->model->updateOrCreate(compact('name'), compact('value'));
}
} catch (Exception $e) {
throw new WriteException($e);
}
}
@@ -93,15 +106,21 @@ class Repository
* @param string $name
* @param mixed $default
*
* @throws \CachetHQ\Cachet\Settings\ReadException
*
* @return mixed
*/
public function get($name, $default = null)
{
if ($setting = $this->model->where('name', '=', $name)->first()) {
return $this->castSetting($name, $setting->value);
}
try {
if ($setting = $this->model->where('name', '=', $name)->first()) {
return $this->castSetting($name, $setting->value);
}
return $default;
return $default;
} catch (Exception $e) {
throw new ReadException($e);
}
}
/**
@@ -109,25 +128,37 @@ class Repository
*
* @param string $name
*
* @throws \CachetHQ\Cachet\Settings\WriteException
*
* @return void
*/
public function delete($name)
{
$this->stale = true;
$this->model->where('name', '=', $name)->delete();
try {
$this->model->where('name', '=', $name)->delete();
} catch (Exception $e) {
throw new WriteException($e);
}
}
/**
* Clear all settings.
*
* @throws \CachetHQ\Cachet\Settings\WriteException
*
* @return void
*/
public function clear()
{
$this->stale = true;
$this->model->query()->delete();
try {
$this->model->query()->delete();
} catch (Exception $e) {
throw new WriteException($e);
}
}
/**

View File

@@ -0,0 +1,35 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Settings;
use Exception;
/**
* This is the settings exception class.
*
* @author Graham Campbell <graham@alt-three.com>
*/
class SettingsException extends Exception
{
/**
* Create a new write exception instance.
*
* @param string $m
* @param \Exception $e
*
* @return void
*/
public function __construct(string $m, Exception $e)
{
parent::__construct($m, 0, $e);
}
}

View File

@@ -0,0 +1,34 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
namespace CachetHQ\Cachet\Settings;
use Exception;
/**
* This is the write exception class.
*
* @author Graham Campbell <graham@alt-three.com>
*/
class WriteException extends SettingsException
{
/**
* Create a new write exception instance.
*
* @param \Exception $e
*
* @return void
*/
public function __construct(Exception $e)
{
parent::__construct('Unable to write Cachet settings', $e);
}
}

View File

@@ -48,7 +48,7 @@
"graham-campbell/markdown": "^10.2",
"guzzlehttp/guzzle": "^6.3.3",
"jenssegers/date": "^3.4",
"laravel/framework": "5.6.*",
"laravel/framework": "5.7.*",
"laravel/tinker": "^1.0",
"laravolt/avatar": "^2.1",
"mccool/laravel-auto-presenter": "^7.1",

301
composer.lock generated
View File

@@ -4,7 +4,7 @@
"Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
"This file is @generated automatically"
],
"content-hash": "308d1d432d962c06cdd2ae7df5544ca9",
"content-hash": "72d1c09394a4734e13155112d3c5c547",
"packages": [
{
"name": "alt-three/badger",
@@ -2034,42 +2034,45 @@
},
{
"name": "laravel/framework",
"version": "v5.6.39",
"version": "v5.7.19",
"source": {
"type": "git",
"url": "https://github.com/laravel/framework.git",
"reference": "37bb306f516669ab4f888c16003f694313ab299e"
"reference": "5c1d1ec7e8563ea31826fd5eb3f6791acf01160c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/framework/zipball/37bb306f516669ab4f888c16003f694313ab299e",
"reference": "37bb306f516669ab4f888c16003f694313ab299e",
"url": "https://api.github.com/repos/laravel/framework/zipball/5c1d1ec7e8563ea31826fd5eb3f6791acf01160c",
"reference": "5c1d1ec7e8563ea31826fd5eb3f6791acf01160c",
"shasum": ""
},
"require": {
"doctrine/inflector": "~1.1",
"dragonmantank/cron-expression": "~2.0",
"erusev/parsedown": "~1.7",
"doctrine/inflector": "^1.1",
"dragonmantank/cron-expression": "^2.0",
"erusev/parsedown": "^1.7",
"ext-mbstring": "*",
"ext-openssl": "*",
"laravel/nexmo-notification-channel": "^1.0",
"laravel/slack-notification-channel": "^1.0",
"league/flysystem": "^1.0.8",
"monolog/monolog": "~1.12",
"nesbot/carbon": "1.25.*",
"monolog/monolog": "^1.12",
"nesbot/carbon": "^1.26.3",
"opis/closure": "^3.1",
"php": "^7.1.3",
"psr/container": "~1.0",
"psr/container": "^1.0",
"psr/simple-cache": "^1.0",
"ramsey/uuid": "^3.7",
"swiftmailer/swiftmailer": "~6.0",
"symfony/console": "~4.0",
"symfony/debug": "~4.0",
"symfony/finder": "~4.0",
"symfony/http-foundation": "~4.0",
"symfony/http-kernel": "~4.0",
"symfony/process": "~4.0",
"symfony/routing": "~4.0",
"symfony/var-dumper": "~4.0",
"swiftmailer/swiftmailer": "^6.0",
"symfony/console": "^4.1",
"symfony/debug": "^4.1",
"symfony/finder": "^4.1",
"symfony/http-foundation": "^4.1",
"symfony/http-kernel": "^4.1",
"symfony/process": "^4.1",
"symfony/routing": "^4.1",
"symfony/var-dumper": "^4.1",
"tijsverkoyen/css-to-inline-styles": "^2.2.1",
"vlucas/phpdotenv": "~2.2"
"vlucas/phpdotenv": "^2.2"
},
"conflict": {
"tightenco/collect": "<5.5.33"
@@ -2105,43 +2108,47 @@
"illuminate/view": "self.version"
},
"require-dev": {
"aws/aws-sdk-php": "~3.0",
"doctrine/dbal": "~2.6",
"aws/aws-sdk-php": "^3.0",
"doctrine/dbal": "^2.6",
"filp/whoops": "^2.1.4",
"league/flysystem-cached-adapter": "~1.0",
"mockery/mockery": "~1.0",
"guzzlehttp/guzzle": "^6.3",
"league/flysystem-cached-adapter": "^1.0",
"mockery/mockery": "^1.0",
"moontoast/math": "^1.1",
"orchestra/testbench-core": "3.6.*",
"pda/pheanstalk": "~3.0",
"phpunit/phpunit": "~7.0",
"orchestra/testbench-core": "3.7.*",
"pda/pheanstalk": "^3.0",
"phpunit/phpunit": "^7.0",
"predis/predis": "^1.1.1",
"symfony/css-selector": "~4.0",
"symfony/dom-crawler": "~4.0"
"symfony/css-selector": "^4.1",
"symfony/dom-crawler": "^4.1",
"true/punycode": "^2.1"
},
"suggest": {
"aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (~3.0).",
"doctrine/dbal": "Required to rename columns and drop SQLite columns (~2.6).",
"aws/aws-sdk-php": "Required to use the SQS queue driver and SES mail driver (^3.0).",
"doctrine/dbal": "Required to rename columns and drop SQLite columns (^2.6).",
"ext-pcntl": "Required to use all features of the queue worker.",
"ext-posix": "Required to use all features of the queue worker.",
"fzaninotto/faker": "Required to use the eloquent factory builder (~1.4).",
"guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (~6.0).",
"laravel/tinker": "Required to use the tinker console command (~1.0).",
"league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (~1.0).",
"league/flysystem-cached-adapter": "Required to use the Flysystem cache (~1.0).",
"league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (~1.0).",
"league/flysystem-sftp": "Required to use the Flysystem SFTP driver (~1.0).",
"nexmo/client": "Required to use the Nexmo transport (~1.0).",
"pda/pheanstalk": "Required to use the beanstalk queue driver (~3.0).",
"predis/predis": "Required to use the redis cache and queue drivers (~1.0).",
"pusher/pusher-php-server": "Required to use the Pusher broadcast driver (~3.0).",
"symfony/css-selector": "Required to use some of the crawler integration testing tools (~4.0).",
"symfony/dom-crawler": "Required to use most of the crawler integration testing tools (~4.0).",
"symfony/psr-http-message-bridge": "Required to psr7 bridging features (~1.0)."
"filp/whoops": "Required for friendly error pages in development (^2.1.4).",
"fzaninotto/faker": "Required to use the eloquent factory builder (^1.4).",
"guzzlehttp/guzzle": "Required to use the Mailgun and Mandrill mail drivers and the ping methods on schedules (^6.0).",
"laravel/tinker": "Required to use the tinker console command (^1.0).",
"league/flysystem-aws-s3-v3": "Required to use the Flysystem S3 driver (^1.0).",
"league/flysystem-cached-adapter": "Required to use the Flysystem cache (^1.0).",
"league/flysystem-rackspace": "Required to use the Flysystem Rackspace driver (^1.0).",
"league/flysystem-sftp": "Required to use the Flysystem SFTP driver (^1.0).",
"moontoast/math": "Required to use ordered UUIDs (^1.1).",
"nexmo/client": "Required to use the Nexmo transport (^1.0).",
"pda/pheanstalk": "Required to use the beanstalk queue driver (^3.0).",
"predis/predis": "Required to use the redis cache and queue drivers (^1.0).",
"pusher/pusher-php-server": "Required to use the Pusher broadcast driver (^3.0).",
"symfony/css-selector": "Required to use some of the crawler integration testing tools (^4.1).",
"symfony/dom-crawler": "Required to use most of the crawler integration testing tools (^4.1).",
"symfony/psr-http-message-bridge": "Required to psr7 bridging features (^1.0)."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "5.6-dev"
"dev-master": "5.7-dev"
}
},
"autoload": {
@@ -2169,7 +2176,121 @@
"framework",
"laravel"
],
"time": "2018-10-04T14:50:41+00:00"
"time": "2018-12-18T14:00:38+00:00"
},
{
"name": "laravel/nexmo-notification-channel",
"version": "v1.0.1",
"source": {
"type": "git",
"url": "https://github.com/laravel/nexmo-notification-channel.git",
"reference": "03edd42a55b306ff980c9950899d5a2b03260d48"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/nexmo-notification-channel/zipball/03edd42a55b306ff980c9950899d5a2b03260d48",
"reference": "03edd42a55b306ff980c9950899d5a2b03260d48",
"shasum": ""
},
"require": {
"nexmo/client": "^1.0",
"php": "^7.1.3"
},
"require-dev": {
"illuminate/notifications": "~5.7",
"mockery/mockery": "^1.0",
"phpunit/phpunit": "^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
},
"laravel": {
"providers": [
"Illuminate\\Notifications\\NexmoChannelServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Illuminate\\Notifications\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "Nexmo Notification Channel for laravel.",
"keywords": [
"laravel",
"nexmo",
"notifications"
],
"time": "2018-12-04T12:57:08+00:00"
},
{
"name": "laravel/slack-notification-channel",
"version": "v1.0.3",
"source": {
"type": "git",
"url": "https://github.com/laravel/slack-notification-channel.git",
"reference": "6e164293b754a95f246faf50ab2bbea3e4923cc9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/laravel/slack-notification-channel/zipball/6e164293b754a95f246faf50ab2bbea3e4923cc9",
"reference": "6e164293b754a95f246faf50ab2bbea3e4923cc9",
"shasum": ""
},
"require": {
"guzzlehttp/guzzle": "^6.0",
"php": "^7.1.3"
},
"require-dev": {
"illuminate/notifications": "~5.7",
"mockery/mockery": "^1.0",
"phpunit/phpunit": "^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.0-dev"
},
"laravel": {
"providers": [
"Illuminate\\Notifications\\SlackChannelServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Illuminate\\Notifications\\": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Taylor Otwell",
"email": "taylor@laravel.com"
}
],
"description": "Slack Notification Channel for laravel.",
"keywords": [
"laravel",
"notifications",
"slack"
],
"time": "2018-12-12T13:12:06+00:00"
},
{
"name": "laravel/tinker",
@@ -2713,16 +2834,16 @@
},
{
"name": "nesbot/carbon",
"version": "1.25.0",
"version": "1.36.2",
"source": {
"type": "git",
"url": "https://github.com/briannesbitt/Carbon.git",
"reference": "cbcf13da0b531767e39eb86e9687f5deba9857b4"
"reference": "cd324b98bc30290f233dd0e75e6ce49f7ab2a6c9"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/cbcf13da0b531767e39eb86e9687f5deba9857b4",
"reference": "cbcf13da0b531767e39eb86e9687f5deba9857b4",
"url": "https://api.github.com/repos/briannesbitt/Carbon/zipball/cd324b98bc30290f233dd0e75e6ce49f7ab2a6c9",
"reference": "cd324b98bc30290f233dd0e75e6ce49f7ab2a6c9",
"shasum": ""
},
"require": {
@@ -2730,18 +2851,23 @@
"symfony/translation": "~2.6 || ~3.0 || ~4.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "~2",
"phpunit/phpunit": "^4.8.35 || ^5.7"
},
"suggest": {
"friendsofphp/php-cs-fixer": "Needed for the `composer phpcs` command. Allow to automatically fix code style.",
"phpstan/phpstan": "Needed for the `composer phpstan` command. Allow to detect potential errors."
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "1.23-dev"
"laravel": {
"providers": [
"Carbon\\Laravel\\ServiceProvider"
]
}
},
"autoload": {
"psr-4": {
"Carbon\\": "src/Carbon/"
"": "src/"
}
},
"notification-url": "https://packagist.org/downloads/",
@@ -2762,7 +2888,7 @@
"datetime",
"time"
],
"time": "2018-03-19T15:50:49+00:00"
"time": "2018-12-28T10:07:33+00:00"
},
{
"name": "nexmo/client",
@@ -2863,6 +2989,67 @@
],
"time": "2018-12-26T11:32:39+00:00"
},
{
"name": "opis/closure",
"version": "3.1.2",
"source": {
"type": "git",
"url": "https://github.com/opis/closure.git",
"reference": "de00c69a2328d3ee5baa71fc584dc643222a574c"
},
"dist": {
"type": "zip",
"url": "https://api.github.com/repos/opis/closure/zipball/de00c69a2328d3ee5baa71fc584dc643222a574c",
"reference": "de00c69a2328d3ee5baa71fc584dc643222a574c",
"shasum": ""
},
"require": {
"php": "^5.4 || ^7.0"
},
"require-dev": {
"jeremeamia/superclosure": "^2.0",
"phpunit/phpunit": "^4.0|^5.0|^6.0|^7.0"
},
"type": "library",
"extra": {
"branch-alias": {
"dev-master": "3.0.x-dev"
}
},
"autoload": {
"psr-4": {
"Opis\\Closure\\": "src/"
},
"files": [
"functions.php"
]
},
"notification-url": "https://packagist.org/downloads/",
"license": [
"MIT"
],
"authors": [
{
"name": "Marius Sarca",
"email": "marius.sarca@gmail.com"
},
{
"name": "Sorin Sarca",
"email": "sarca_sorin@hotmail.com"
}
],
"description": "A library that can be used to serialize closures (anonymous functions) and arbitrary objects.",
"homepage": "https://opis.io/closure",
"keywords": [
"anonymous functions",
"closure",
"function",
"serializable",
"serialization",
"serialize"
],
"time": "2018-12-16T21:48:23+00:00"
},
{
"name": "php-http/guzzle6-adapter",
"version": "v1.1.1",

View File

@@ -47,10 +47,11 @@ return [
*/
'displayers' => [
'CachetHQ\Cachet\Foundation\Exceptions\Displayers\JsonValidationDisplayer',
'CachetHQ\Cachet\Foundation\Exceptions\Displayers\MaintenanceDisplayer',
'CachetHQ\Cachet\Foundation\Exceptions\Displayers\SettingsDisplayer',
'CachetHQ\Cachet\Foundation\Exceptions\Displayers\RedirectDisplayer',
'CachetHQ\Cachet\Foundation\Exceptions\Displayers\ThrottleDisplayer',
'CachetHQ\Cachet\Foundation\Exceptions\Displayers\MaintenanceDisplayer',
'CachetHQ\Cachet\Foundation\Exceptions\Displayers\JsonValidationDisplayer',
'GrahamCampbell\Exceptions\Displayers\DebugDisplayer',
'GrahamCampbell\Exceptions\Displayers\HtmlDisplayer',
'GrahamCampbell\Exceptions\Displayers\JsonDisplayer',

53
config/trustedproxy.php Normal file
View File

@@ -0,0 +1,53 @@
<?php
/*
* This file is part of Cachet.
*
* (c) Alt Three Services Limited
*
* For the full copyright and license information, please view the LICENSE
* file that was distributed with this source code.
*/
return [
/*
* Set trusted proxy IP addresses.
*
* Both IPv4 and IPv6 addresses are
* supported, along with CIDR notation.
*
* The "*" character is syntactic sugar
* within TrustedProxy to trust any proxy
* that connects directly to your server,
* a requirement when you cannot know the address
* of your proxy (e.g. if using ELB or similar).
*
*/
'proxies' => null, // [<ip addresses>,], '*'
/*
* To trust one or more specific proxies that connect
* directly to your server, use an array of IP addresses:
*/
// 'proxies' => ['192.168.1.1'],
/*
* Or, to trust all proxies that connect
* directly to your server, use a "*"
*/
// 'proxies' => '*',
/*
* Which headers to use to detect proxy related data (For, Host, Proto, Port)
*
* Options include:
*
* - Illuminate\Http\Request::HEADER_X_FORWARDED_ALL (use all x-forwarded-* headers to establish trust)
* - Illuminate\Http\Request::HEADER_FORWARDED (use the FORWARDED header to establish trust)
*
* @link https://symfony.com/doc/current/deployment/proxies.html
*/
'headers' => Illuminate\Http\Request::HEADER_X_FORWARDED_ALL,
];

View File

@@ -0,0 +1,11 @@
@extends('errors::illustrated-layout')
@section('code', '401')
@section('title', __('Unauthorized'))
@section('image')
<div style="background-image: url({{ asset('/svg/403.svg') }});" class="absolute pin bg-cover bg-no-repeat md:bg-left lg:bg-center">
</div>
@endsection
@section('message', __('Sorry, you are not authorized to access this page.'))

View File

@@ -0,0 +1,11 @@
@extends('errors::illustrated-layout')
@section('code', '403')
@section('title', __('Forbidden'))
@section('image')
<div style="background-image: url({{ asset('/svg/403.svg') }});" class="absolute pin bg-cover bg-no-repeat md:bg-left lg:bg-center">
</div>
@endsection
@section('message', __($exception->getMessage() ?: __('Sorry, you are forbidden from accessing this page.')))

View File

@@ -0,0 +1,11 @@
@extends('errors::illustrated-layout')
@section('code', '404')
@section('title', __('Page Not Found'))
@section('image')
<div style="background-image: url({{ asset('/svg/404.svg') }});" class="absolute pin bg-cover bg-no-repeat md:bg-left lg:bg-center">
</div>
@endsection
@section('message', __('Sorry, the page you are looking for could not be found.'))

View File

@@ -0,0 +1,11 @@
@extends('errors::illustrated-layout')
@section('code', '419')
@section('title', __('Page Expired'))
@section('image')
<div style="background-image: url({{ asset('/svg/403.svg') }});" class="absolute pin bg-cover bg-no-repeat md:bg-left lg:bg-center">
</div>
@endsection
@section('message', __('Sorry, your session has expired. Please refresh and try again.'))

View File

@@ -0,0 +1,11 @@
@extends('errors::illustrated-layout')
@section('code', '429')
@section('title', __('Too Many Requests'))
@section('image')
<div style="background-image: url({{ asset('/svg/403.svg') }});" class="absolute pin bg-cover bg-no-repeat md:bg-left lg:bg-center">
</div>
@endsection
@section('message', __('Sorry, you are making too many requests to our servers.'))

View File

@@ -0,0 +1,11 @@
@extends('errors::illustrated-layout')
@section('code', '500')
@section('title', __('Error'))
@section('image')
<div style="background-image: url({{ asset('/svg/500.svg') }});" class="absolute pin bg-cover bg-no-repeat md:bg-left lg:bg-center">
</div>
@endsection
@section('message', __('Whoops, something went wrong on our servers.'))

View File

@@ -0,0 +1,11 @@
@extends('errors::illustrated-layout')
@section('code', '503')
@section('title', __('Service Unavailable'))
@section('image')
<div style="background-image: url({{ asset('/svg/503.svg') }});" class="absolute pin bg-cover bg-no-repeat md:bg-left lg:bg-center">
</div>
@endsection
@section('message', __($exception->getMessage() ?: __('Sorry, we are doing some maintenance. Please check back soon.')))

View File

@@ -0,0 +1,486 @@
<!doctype html>
<html lang="en">
<head>
<title>@yield('title')</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<!-- Fonts -->
<link rel="dns-prefetch" href="//fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css">
<!-- Styles -->
<style>
html {
line-height: 1.15;
-ms-text-size-adjust: 100%;
-webkit-text-size-adjust: 100%;
}
body {
margin: 0;
}
header,
nav,
section {
display: block;
}
figcaption,
main {
display: block;
}
a {
background-color: transparent;
-webkit-text-decoration-skip: objects;
}
strong {
font-weight: inherit;
}
strong {
font-weight: bolder;
}
code {
font-family: monospace, monospace;
font-size: 1em;
}
dfn {
font-style: italic;
}
svg:not(:root) {
overflow: hidden;
}
button,
input {
font-family: sans-serif;
font-size: 100%;
line-height: 1.15;
margin: 0;
}
button,
input {
overflow: visible;
}
button {
text-transform: none;
}
button,
html [type="button"],
[type="reset"],
[type="submit"] {
-webkit-appearance: button;
}
button::-moz-focus-inner,
[type="button"]::-moz-focus-inner,
[type="reset"]::-moz-focus-inner,
[type="submit"]::-moz-focus-inner {
border-style: none;
padding: 0;
}
button:-moz-focusring,
[type="button"]:-moz-focusring,
[type="reset"]:-moz-focusring,
[type="submit"]:-moz-focusring {
outline: 1px dotted ButtonText;
}
legend {
-webkit-box-sizing: border-box;
box-sizing: border-box;
color: inherit;
display: table;
max-width: 100%;
padding: 0;
white-space: normal;
}
[type="checkbox"],
[type="radio"] {
-webkit-box-sizing: border-box;
box-sizing: border-box;
padding: 0;
}
[type="number"]::-webkit-inner-spin-button,
[type="number"]::-webkit-outer-spin-button {
height: auto;
}
[type="search"] {
-webkit-appearance: textfield;
outline-offset: -2px;
}
[type="search"]::-webkit-search-cancel-button,
[type="search"]::-webkit-search-decoration {
-webkit-appearance: none;
}
::-webkit-file-upload-button {
-webkit-appearance: button;
font: inherit;
}
menu {
display: block;
}
canvas {
display: inline-block;
}
template {
display: none;
}
[hidden] {
display: none;
}
html {
-webkit-box-sizing: border-box;
box-sizing: border-box;
font-family: sans-serif;
}
*,
*::before,
*::after {
-webkit-box-sizing: inherit;
box-sizing: inherit;
}
p {
margin: 0;
}
button {
background: transparent;
padding: 0;
}
button:focus {
outline: 1px dotted;
outline: 5px auto -webkit-focus-ring-color;
}
*,
*::before,
*::after {
border-width: 0;
border-style: solid;
border-color: #dae1e7;
}
button,
[type="button"],
[type="reset"],
[type="submit"] {
border-radius: 0;
}
button,
input {
font-family: inherit;
}
input::-webkit-input-placeholder {
color: inherit;
opacity: .5;
}
input:-ms-input-placeholder {
color: inherit;
opacity: .5;
}
input::-ms-input-placeholder {
color: inherit;
opacity: .5;
}
input::placeholder {
color: inherit;
opacity: .5;
}
button,
[role=button] {
cursor: pointer;
}
.bg-transparent {
background-color: transparent;
}
.bg-white {
background-color: #fff;
}
.bg-teal-light {
background-color: #64d5ca;
}
.bg-blue-dark {
background-color: #2779bd;
}
.bg-indigo-light {
background-color: #7886d7;
}
.bg-purple-light {
background-color: #a779e9;
}
.bg-no-repeat {
background-repeat: no-repeat;
}
.bg-cover {
background-size: cover;
}
.border-grey-light {
border-color: #dae1e7;
}
.hover\:border-grey:hover {
border-color: #b8c2cc;
}
.rounded-lg {
border-radius: .5rem;
}
.border-2 {
border-width: 2px;
}
.hidden {
display: none;
}
.flex {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
.items-center {
-webkit-box-align: center;
-ms-flex-align: center;
align-items: center;
}
.justify-center {
-webkit-box-pack: center;
-ms-flex-pack: center;
justify-content: center;
}
.font-sans {
font-family: Nunito, sans-serif;
}
.font-light {
font-weight: 300;
}
.font-bold {
font-weight: 700;
}
.font-black {
font-weight: 900;
}
.h-1 {
height: .25rem;
}
.leading-normal {
line-height: 1.5;
}
.m-8 {
margin: 2rem;
}
.my-3 {
margin-top: .75rem;
margin-bottom: .75rem;
}
.mb-8 {
margin-bottom: 2rem;
}
.max-w-sm {
max-width: 30rem;
}
.min-h-screen {
min-height: 100vh;
}
.py-3 {
padding-top: .75rem;
padding-bottom: .75rem;
}
.px-6 {
padding-left: 1.5rem;
padding-right: 1.5rem;
}
.pb-full {
padding-bottom: 100%;
}
.absolute {
position: absolute;
}
.relative {
position: relative;
}
.pin {
top: 0;
right: 0;
bottom: 0;
left: 0;
}
.text-black {
color: #22292f;
}
.text-grey-darkest {
color: #3d4852;
}
.text-grey-darker {
color: #606f7b;
}
.text-2xl {
font-size: 1.5rem;
}
.text-5xl {
font-size: 3rem;
}
.uppercase {
text-transform: uppercase;
}
.antialiased {
-webkit-font-smoothing: antialiased;
-moz-osx-font-smoothing: grayscale;
}
.tracking-wide {
letter-spacing: .05em;
}
.w-16 {
width: 4rem;
}
.w-full {
width: 100%;
}
@media (min-width: 768px) {
.md\:bg-left {
background-position: left;
}
.md\:bg-right {
background-position: right;
}
.md\:flex {
display: -webkit-box;
display: -ms-flexbox;
display: flex;
}
.md\:my-6 {
margin-top: 1.5rem;
margin-bottom: 1.5rem;
}
.md\:min-h-screen {
min-height: 100vh;
}
.md\:pb-0 {
padding-bottom: 0;
}
.md\:text-3xl {
font-size: 1.875rem;
}
.md\:text-15xl {
font-size: 9rem;
}
.md\:w-1\/2 {
width: 50%;
}
}
@media (min-width: 992px) {
.lg\:bg-center {
background-position: center;
}
}
</style>
</head>
<body class="antialiased font-sans">
<div class="md:flex min-h-screen">
<div class="w-full md:w-1/2 bg-white flex items-center justify-center">
<div class="max-w-sm m-8">
<div class="text-black text-5xl md:text-15xl font-black">
@yield('code', __('Oh no'))
</div>
<div class="w-16 h-1 bg-purple-light my-3 md:my-6"></div>
<p class="text-grey-darker text-2xl md:text-3xl font-light mb-8 leading-normal">
@yield('message')
</p>
<a href="{{ url('/') }}">
<button class="bg-transparent text-grey-darkest font-bold uppercase tracking-wide py-3 px-6 border-2 border-grey-light hover:border-grey rounded-lg">
{{ __('Go Home') }}
</button>
</a>
</div>
</div>
<div class="relative pb-full md:flex md:pb-0 md:min-h-screen w-full md:w-1/2">
@yield('image')
</div>
</div>
</body>
</html>

View File

@@ -0,0 +1,57 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1">
<title>@yield('title')</title>
<!-- Fonts -->
<link rel="dns-prefetch" href="//fonts.gstatic.com">
<link href="https://fonts.googleapis.com/css?family=Nunito" rel="stylesheet" type="text/css">
<!-- Styles -->
<style>
html, body {
background-color: #fff;
color: #636b6f;
font-family: 'Nunito', sans-serif;
font-weight: 100;
height: 100vh;
margin: 0;
}
.full-height {
height: 100vh;
}
.flex-center {
align-items: center;
display: flex;
justify-content: center;
}
.position-ref {
position: relative;
}
.content {
text-align: center;
}
.title {
font-size: 36px;
padding: 20px;
}
</style>
</head>
<body>
<div class="flex-center position-ref full-height">
<div class="content">
<div class="title">
@yield('message')
</div>
</div>
</div>
</body>
</html>

View File

@@ -20,7 +20,7 @@
<link rel="apple-touch-icon" sizes="144x144" href="{{ asset('/img/apple-touch-icon-144x144.png') }}">
<link rel="apple-touch-icon" sizes="152x152" href="{{ asset('/img/apple-touch-icon-152x152.png') }}">
<title>{{ $pageTitle or $siteTitle }}</title>
<title>{{ $pageTitle ?? $siteTitle }}</title>
@if($enableExternalDependencies)
{{-- <link href="https://fonts.googleapis.com/css?family=Open+Sans:300,400,700&subset={{ $fontSubset }}" rel="stylesheet" type="text/css"> --}}

View File

@@ -20,7 +20,7 @@
<link rel="apple-touch-icon" sizes="144x144" href="{{ asset('/img/apple-touch-icon-144x144.png') }}">
<link rel="apple-touch-icon" sizes="152x152" href="{{ asset('/img/apple-touch-icon-152x152.png') }}">
<title>{{ $pageTitle or $siteTitle }}</title>
<title>{{ $pageTitle ?? $siteTitle }}</title>
<script>
window.Global = {}

View File

@@ -7,7 +7,7 @@
<table border="0" cellpadding="0" cellspacing="0">
<tr>
<td>
<a href="{{ $url }}" class="button button-{{ $color or 'blue' }}" target="_blank">{{ $slot }}</a>
<a href="{{ $url }}" class="button button-{{ $color ?? 'primary' }}" target="_blank">{{ $slot }}</a>
</td>
</tr>
</table>

View File

@@ -27,7 +27,7 @@
<tr>
<td align="center">
<table class="content" width="100%" cellpadding="0" cellspacing="0">
{{ $header or '' }}
{{ $header ?? '' }}
<!-- Email Body -->
<tr>
@@ -38,14 +38,14 @@
<td class="content-cell">
{{ Illuminate\Mail\Markdown::parse($slot) }}
{{ $subcopy or '' }}
{{ $subcopy ?? '' }}
</td>
</tr>
</table>
</td>
</tr>
{{ $footer or '' }}
{{ $footer ?? '' }}
</table>
</td>
</tr>

View File

@@ -21,7 +21,7 @@
{{-- Footer --}}
@slot('footer')
@component('mail::footer')
&copy; {{ date('Y') }} {{ setting('app_name', config('app.name')) }}. All rights reserved.
© {{ date('Y') }} {{ setting('app_name', config('app.name')) }}. @lang('All rights reserved.')
@endcomponent
@endslot
@endcomponent

View File

@@ -182,6 +182,7 @@ img {
.table th {
border-bottom: 1px solid #EDEFF2;
padding-bottom: 8px;
margin: 0;
}
.table td {
@@ -189,6 +190,7 @@ img {
font-size: 15px;
line-height: 18px;
padding: 10px 0;
margin: 0;
}
.content-cell {
@@ -216,7 +218,8 @@ img {
-webkit-text-size-adjust: none;
}
.button-blue {
.button-blue,
.button-primary {
background-color: #3097D1;
border-top: 10px solid #3097D1;
border-right: 18px solid #3097D1;
@@ -224,7 +227,8 @@ img {
border-left: 18px solid #3097D1;
}
.button-green {
.button-green,
.button-success {
background-color: #2ab27b;
border-top: 10px solid #2ab27b;
border-right: 18px solid #2ab27b;
@@ -232,7 +236,8 @@ img {
border-left: 18px solid #2ab27b;
}
.button-red {
.button-red,
.button-error {
background-color: #bf5329;
border-top: 10px solid #bf5329;
border-right: 18px solid #bf5329;

View File

@@ -21,7 +21,7 @@
{{-- Footer --}}
@slot('footer')
@component('mail::footer')
© {{ date('Y') }} {{ setting('app_name', config('app.name')) }}. All rights reserved.
© {{ date('Y') }} {{ setting('app_name', config('app.name')) }}. @lang('All rights reserved.')
@endcomponent
@endslot
@endcomponent

View File

@@ -1,22 +0,0 @@
<?php
if (! empty($greeting)) {
echo $greeting, "\n\n";
} else {
echo $level == 'error' ? 'Whoops!' : 'Hello!', "\n\n";
}
if (! empty($introLines)) {
echo implode("\n", $introLines), "\n\n";
}
if (isset($actionText)) {
echo "{$actionText}: {$actionUrl}", "\n\n";
}
if (! empty($outroLines)) {
echo implode("\n", $outroLines), "\n\n";
}
echo 'Regards,', "\n";
echo config('app.name'), "\n";

View File

@@ -1,192 +1,62 @@
<!DOCTYPE html>
<html>
@component('mail::message')
{{-- Greeting --}}
@if (! empty($greeting))
# {{ $greeting }}
@else
@if ($level === 'error')
# @lang('Whoops!')
@else
# @lang('Hello!')
@endif
@endif
<head>
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
{{-- Intro Lines --}}
@foreach ($introLines as $line)
{{ $line }}
<style type="text/css" rel="stylesheet" media="all">
/* Media Queries */
@media only screen and (max-width: 500px) {
.button {
width: 100% !important;
}
}
</style>
</head>
@endforeach
{{-- Action Button --}}
@isset($actionText)
<?php
$style = [
/* Layout ------------------------------ */
'body' => 'margin: 0; padding: 0; width: 100%; background-color: #F2F4F6;',
'email-wrapper' => 'width: 100%; margin: 0; padding: 0; background-color: #F2F4F6;',
/* Masthead ----------------------- */
'email-masthead' => 'padding: 25px 0; text-align: center;',
'email-masthead_name' => 'font-size: 16px; font-weight: bold; color: #2F3133; text-decoration: none; text-shadow: 0 1px 0 white;',
'email-body' => 'width: 100%; margin: 0; padding: 0; border-top: 1px solid #EDEFF2; border-bottom: 1px solid #EDEFF2; background-color: #FFF;',
'email-body_inner' => 'width: auto; max-width: 570px; margin: 0 auto; padding: 0;',
'email-body_cell' => 'padding: 35px;',
'email-footer' => 'width: auto; max-width: 570px; margin: 0 auto; padding: 0; text-align: center;',
'email-footer_cell' => 'color: #AEAEAE; padding: 35px; text-align: center;',
/* Body ------------------------------ */
'body_action' => 'width: 100%; margin: 30px auto; padding: 0; text-align: center;',
'body_sub' => 'margin-top: 25px; padding-top: 25px; border-top: 1px solid #EDEFF2;',
/* Type ------------------------------ */
'anchor' => "color: {$themeLinks};",
'header-1' => 'margin-top: 0; color: #2F3133; font-size: 19px; font-weight: bold; text-align: left;',
'paragraph' => 'margin-top: 0; color: #74787E; font-size: 16px; line-height: 1.5em;',
'paragraph-sub' => 'margin-top: 0; color: #74787E; font-size: 12px; line-height: 1.5em;',
'paragraph-center' => 'text-align: center;',
/* Buttons ------------------------------ */
'button' => 'display: block; display: inline-block; width: 200px; min-height: 20px; padding: 10px;
background-color: #3869D4; border-radius: 3px; color: #ffffff; font-size: 15px; line-height: 25px;
text-align: center; text-decoration: none; -webkit-text-size-adjust: none;',
'button--green' => "background-color: {$themeGreens};",
'button--red' => "background-color: {$themeReds};",
'button--blue' => "background-color: {$themeBlues};",
];
switch ($level) {
case 'success':
case 'error':
$color = $level;
break;
default:
$color = 'primary';
}
?>
@component('mail::button', ['url' => $actionUrl, 'color' => $color])
{{ $actionText }}
@endcomponent
@endisset
<?php $fontFamily = 'font-family: Arial, \'Helvetica Neue\', Helvetica, sans-serif;'; ?>
{{-- Outro Lines --}}
@foreach ($outroLines as $line)
{{ $line }}
<body style="{{ $style['body'] }}">
<table width="100%" cellpadding="0" cellspacing="0">
<tr>
<td style="{{ $style['email-wrapper'] }}" align="center">
<table width="100%" cellpadding="0" cellspacing="0">
<!-- Logo -->
<tr>
<td style="{{ $style['email-masthead'] }}">
<a style="{{ $fontFamily }} {{ $style['email-masthead_name'] }}" href="{{ url('/') }}" target="_blank">
{{ setting('app_name', config('app.name')) }}
</a>
</td>
</tr>
@endforeach
<!-- Email Body -->
<tr>
<td style="{{ $style['email-body'] }}" width="100%">
<table style="{{ $style['email-body_inner'] }}" align="center" width="570" cellpadding="0" cellspacing="0">
<tr>
<td style="{{ $fontFamily }} {{ $style['email-body_cell'] }}">
<!-- Greeting -->
<h1 style="{{ $style['header-1'] }}">
@if (! empty($greeting))
{{ $greeting }}
@else
@if ($level == 'error')
Whoops!
@else
Hello!
@endif
@endif
</h1>
{{-- Salutation --}}
@if (! empty($salutation))
{{ $salutation }}
@else
@lang('Regards'),<br>{{ setting('app_name', config('app.name')) }}
@endif
<!-- Intro -->
@foreach ($introLines as $line)
<p style="{{ $style['paragraph'] }}">
{{ $line }}
</p>
@endforeach
<!-- Action Button -->
@if (isset($actionText))
<table style="{{ $style['body_action'] }}" align="center" width="100%" cellpadding="0" cellspacing="0">
<tr>
<td align="center">
<?php
switch ($level) {
case 'success':
$actionColor = 'button--green';
break;
case 'error':
$actionColor = 'button--red';
break;
default:
$actionColor = 'button--blue';
}
?>
<a href="{{ $actionUrl }}"
style="{{ $fontFamily }} {{ $style['button'] }} {{ $style[$actionColor] }}"
class="button"
target="_blank">
{{ $actionText }}
</a>
</td>
</tr>
</table>
@endif
<!-- Outro -->
@foreach ($outroLines as $line)
<p style="{{ $style['paragraph'] }}">
{{ $line }}
</p>
@endforeach
<!-- Salutation -->
<p style="{{ $style['paragraph'] }}">
Regards,<br>{{ setting('app_name', config('app.name')) }}
</p>
<!-- Sub Copy -->
@if (isset($actionText))
<table style="{{ $style['body_sub'] }}">
<tr>
<td style="{{ $fontFamily }}">
<p style="{{ $style['paragraph-sub'] }}">
If youre having trouble clicking the "{{ $actionText }}" button,
copy and paste the URL below into your web browser:
</p>
<p style="{{ $style['paragraph-sub'] }}">
<a style="{{ $style['anchor'] }}" href="{{ $actionUrl }}" target="_blank">
{{ $actionUrl }}
</a>
</p>
</td>
</tr>
</table>
@endif
</td>
</tr>
</table>
</td>
</tr>
<!-- Footer -->
<tr>
<td>
<table style="{{ $style['email-footer'] }}" align="center" width="570" cellpadding="0" cellspacing="0">
<tr>
<td style="{{ $fontFamily }} {{ $style['email-footer_cell'] }}">
<p style="{{ $style['paragraph-sub'] }}">
&copy; {{ date('Y') }}
<a style="{{ $style['anchor'] }}" href="{{ url('/') }}" target="_blank">{{ setting('app_name', config('app.name')) }}</a>.
All rights reserved.
</p>
</td>
</tr>
</table>
</td>
</tr>
</table>
</td>
</tr>
</table>
</body>
</html>
{{-- Subcopy --}}
@isset($actionText)
@component('mail::subcopy')
@lang(
"If youre having trouble clicking the \":actionText\" button, copy and paste the URL below\n".
'into your web browser: [:actionURL](:actionURL)',
[
'actionText' => $actionText,
'actionURL' => $actionUrl,
]
)
@endcomponent
@endisset
@endcomponent

View File

@@ -1,24 +1,28 @@
@if ($paginator->hasPages())
<ul class="pagination">
<ul class="pagination" role="navigation">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="page-item disabled"><span class="page-link">&laquo;</span></li>
<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">&laquo;</a></li>
<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"><span class="page-link">{{ $element }}</span></li>
<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"><span class="page-link">{{ $page }}</span></li>
<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
@@ -28,9 +32,13 @@
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li class="page-item"><a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next">&raquo;</a></li>
<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"><span class="page-link">&raquo;</span></li>
<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>
@endif

View File

@@ -1,24 +1,28 @@
@if ($paginator->hasPages())
<ul class="pagination">
<ul class="pagination" role="navigation">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="disabled"><span>&laquo;</span></li>
<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">&laquo;</a></li>
<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"><span>{{ $element }}</span></li>
<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"><span>{{ $page }}</span></li>
<li class="active" aria-current="page"><span>{{ $page }}</span></li>
@else
<li><a href="{{ $url }}">{{ $page }}</a></li>
@endif
@@ -28,9 +32,13 @@
{{-- Next Page Link --}}
@if ($paginator->hasMorePages())
<li><a href="{{ $paginator->nextPageUrl() }}" rel="next">&raquo;</a></li>
<li>
<a href="{{ $paginator->nextPageUrl() }}" rel="next" aria-label="@lang('pagination.next')">&rsaquo;</a>
</li>
@else
<li class="disabled"><span>&raquo;</span></li>
<li class="disabled" aria-disabled="true" aria-label="@lang('pagination.next')">
<span aria-hidden="true">&rsaquo;</span>
</li>
@endif
</ul>
@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

@@ -1,17 +1,25 @@
@if ($paginator->hasPages())
<ul class="pagination">
<ul class="pagination" role="navigation">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="page-item disabled"><span class="page-link">&laquo;</span></li>
<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">&laquo;</a></li>
<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">&raquo;</a></li>
<li class="page-item">
<a class="page-link" href="{{ $paginator->nextPageUrl() }}" rel="next">@lang('pagination.next')</a>
</li>
@else
<li class="page-item disabled"><span class="page-link">&raquo;</span></li>
<li class="page-item disabled" aria-disabled="true">
<span class="page-link">@lang('pagination.next')</span>
</li>
@endif
</ul>
@endif

View File

@@ -1,17 +1,17 @@
@if ($paginator->hasPages())
<ul class="pagination">
<ul class="pagination" role="navigation">
{{-- Previous Page Link --}}
@if ($paginator->onFirstPage())
<li class="disabled"><span>&laquo;</span></li>
<li class="disabled" aria-disabled="true"><span>@lang('pagination.previous')</span></li>
@else
<li><a href="{{ $paginator->previousPageUrl() }}" rel="prev">&laquo;</a></li>
<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">&raquo;</a></li>
<li><a href="{{ $paginator->nextPageUrl() }}" rel="next">@lang('pagination.next')</a></li>
@else
<li class="disabled"><span>&raquo;</span></li>
<li class="disabled" aria-disabled="true"><span>@lang('pagination.next')</span></li>
@endif
</ul>
@endif

View File

@@ -1,2 +1,3 @@
*
!data/
!.gitignore

View File

@@ -0,0 +1,2 @@
*
!.gitignore