laravel-6 support

This commit is contained in:
RafficMohammed
2023-01-08 01:17:22 +05:30
parent 1a5c16ae4b
commit 774eed8b0e
4962 changed files with 279380 additions and 297961 deletions

View File

@@ -0,0 +1,12 @@
<?php
namespace DaveJamesMiller\Breadcrumbs;
use Exception;
/**
* Base class for exceptions in Laravel Breadcrumbs.
*/
abstract class BreadcrumbsException extends Exception
{
}

View File

@@ -0,0 +1,98 @@
<?php
namespace DaveJamesMiller\Breadcrumbs;
use DaveJamesMiller\Breadcrumbs\Exceptions\InvalidBreadcrumbException;
use Illuminate\Support\Collection;
/**
* Generate a set of breadcrumbs for a page.
*
* This is passed as the first parameter to all breadcrumb-generating closures. In the documentation it is named
* `$breadcrumbs`.
*/
class BreadcrumbsGenerator
{
/**
* @var Collection Breadcrumbs currently being generated.
*/
protected $breadcrumbs;
/**
* @var array The registered breadcrumb-generating callbacks.
*/
protected $callbacks = [];
/**
* Generate breadcrumbs.
*
* @param array $callbacks The registered breadcrumb-generating closures.
* @param array $before The registered 'before' callbacks.
* @param array $after The registered 'after' callbacks.
* @param string $name The name of the current page.
* @param array $params The parameters to pass to the closure for the current page.
* @return Collection The generated breadcrumbs.
* @throws InvalidBreadcrumbException if the name is (or any ancestor names are) not registered.
*/
public function generate(array $callbacks, array $before, array $after, string $name, array $params): Collection
{
$this->breadcrumbs = new Collection;
$this->callbacks = $callbacks;
foreach ($before as $callback) {
$callback($this);
}
$this->call($name, $params);
foreach ($after as $callback) {
$callback($this);
}
return $this->breadcrumbs;
}
/**
* Call the closure to generate breadcrumbs for a page.
*
* @param string $name The name of the page.
* @param array $params The parameters to pass to the closure.
* @throws InvalidBreadcrumbException if the name is not registered.
*/
protected function call(string $name, array $params): void
{
if (! isset($this->callbacks[ $name ])) {
throw new InvalidBreadcrumbException($name);
}
$this->callbacks[$name]($this, ...$params);
}
/**
* Add breadcrumbs for a parent page.
*
* Should be called from the closure for a page, before `push()` is called.
*
* @param string $name The name of the parent page.
* @param array ...$params The parameters to pass to the closure.
* @throws InvalidBreadcrumbException
*/
public function parent(string $name, ...$params): void
{
$this->call($name, $params);
}
/**
* Add a breadcrumb.
*
* Should be called from the closure for each page. May be called more than once.
*
* @param string $title The title of the page.
* @param string|null $url The URL of the page.
* @param array $data Optional associative array of additional data to pass to the view.
*/
public function push(string $title, string $url = null, array $data = []): void
{
$this->breadcrumbs->push((object) array_merge($data, compact('title', 'url')));
}
}

View File

@@ -0,0 +1,315 @@
<?php
namespace DaveJamesMiller\Breadcrumbs;
use DaveJamesMiller\Breadcrumbs\Exceptions\DuplicateBreadcrumbException;
use DaveJamesMiller\Breadcrumbs\Exceptions\InvalidBreadcrumbException;
use DaveJamesMiller\Breadcrumbs\Exceptions\UnnamedRouteException;
use DaveJamesMiller\Breadcrumbs\Exceptions\ViewNotSetException;
use Illuminate\Contracts\View\Factory as ViewFactory;
use Illuminate\Routing\Router;
use Illuminate\Support\Collection;
use Illuminate\Support\HtmlString;
use Illuminate\Support\Traits\Macroable;
/**
* The main Breadcrumbs singleton class, responsible for registering, generating and rendering breadcrumbs.
*/
class BreadcrumbsManager
{
use Macroable;
/**
* @var BreadcrumbsGenerator
*/
protected $generator;
/**
* @var Router
*/
protected $router;
/**
* @var ViewFactory
*/
protected $viewFactory;
/**
* @var array The registered breadcrumb-generating callbacks.
*/
protected $callbacks = [];
/**
* @var array Closures to call before generating breadcrumbs for the current page.
*/
protected $before = [];
/**
* @var array Closures to call after generating breadcrumbs for the current page.
*/
protected $after = [];
/**
* @var array|null The current route name and parameters.
*/
protected $route;
public function __construct(BreadcrumbsGenerator $generator, Router $router, ViewFactory $viewFactory)
{
$this->generator = $generator;
$this->router = $router;
$this->viewFactory = $viewFactory;
}
/**
* Register a breadcrumb-generating callback for a page.
*
* @param string $name The name of the page.
* @param callable $callback The callback, which should accept a Generator instance as the first parameter and may
* accept additional parameters.
* @return void
* @throws \DaveJamesMiller\Breadcrumbs\Exceptions\DuplicateBreadcrumbException If the given name has already been
* used.
*/
public function for(string $name, callable $callback): void
{
if (isset($this->callbacks[$name])) {
throw new DuplicateBreadcrumbException($name);
}
$this->callbacks[$name] = $callback;
}
/**
* Register a breadcrumb-generating callback for a page.
*
* For backwards-compatibility with v5.0.0 and below.
*
* @param string $name The name of the page.
* @param callable $callback The callback, which should accept a Generator instance as the first parameter and may
* accept additional parameters.
* @return void
* @throws \DaveJamesMiller\Breadcrumbs\Exceptions\DuplicateBreadcrumbException If the given name has already been
* used.
* @see self::for()
*/
public function register(string $name, callable $callback): void
{
$this->for($name, $callback);
}
/**
* Register a closure to call before generating breadcrumbs for the current page.
*
* For example, this can be used to always prepend the homepage without needing to manually add it to each page.
*
* @param callable $callback The callback, which should accept a Generator instance as the first and only parameter.
* @return void
*/
public function before(callable $callback): void
{
$this->before[] = $callback;
}
/**
* Register a closure to call after generating breadcrumbs for the current page.
*
* For example, this can be used to append the current page number when using pagination.
*
* @param callable $callback The callback, which should accept a Generator instance as the first and only parameter.
* @return void
*/
public function after(callable $callback): void
{
$this->after[] = $callback;
}
/**
* Check if a breadcrumb with the given name exists.
*
* If no name is given, defaults to the current route name.
*
* @param string|null $name The page name.
* @return bool Whether there is a registered callback with that name.
*/
public function exists(string $name = null): bool
{
if (is_null($name)) {
try {
[$name] = $this->getCurrentRoute();
} catch (UnnamedRouteException $e) {
return false;
}
}
return isset($this->callbacks[$name]);
}
/**
* Generate a set of breadcrumbs for a page.
*
* @param string|null $name The name of the current page.
* @param mixed ...$params The parameters to pass to the closure for the current page.
* @return \Illuminate\Support\Collection The generated breadcrumbs.
* @throws \DaveJamesMiller\Breadcrumbs\Exceptions\UnnamedRouteException if no name is given and the current route
* doesn't have an associated name.
* @throws \DaveJamesMiller\Breadcrumbs\Exceptions\InvalidBreadcrumbException if the name is (or any ancestor names
* are) not registered.
*/
public function generate(string $name = null, ...$params): Collection
{
$origName = $name;
// Route-bound breadcrumbs
if ($name === null) {
try {
[$name, $params] = $this->getCurrentRoute();
} catch (UnnamedRouteException $e) {
if (config('breadcrumbs.unnamed-route-exception')) {
throw $e;
}
return new Collection;
}
}
// Generate breadcrumbs
try {
return $this->generator->generate($this->callbacks, $this->before, $this->after, $name, $params);
} catch (InvalidBreadcrumbException $e) {
if ($origName === null && config('breadcrumbs.missing-route-bound-breadcrumb-exception')) {
$e->setIsRouteBound();
throw $e;
}
if ($origName !== null && config('breadcrumbs.invalid-named-breadcrumb-exception')) {
throw $e;
}
return new Collection;
}
}
/**
* Render breadcrumbs for a page with the specified view.
*
* @param string $view The name of the view to render.
* @param string|null $name The name of the current page.
* @param mixed ...$params The parameters to pass to the closure for the current page.
* @return \Illuminate\Support\HtmlString The generated HTML.
* @throws \DaveJamesMiller\Breadcrumbs\Exceptions\InvalidBreadcrumbException if the name is (or any ancestor names are) not registered.
* @throws \DaveJamesMiller\Breadcrumbs\Exceptions\UnnamedRouteException if no name is given and the current route doesn't have an associated name.
* @throws \DaveJamesMiller\Breadcrumbs\Exceptions\ViewNotSetException if no view has been set.
*/
public function view(string $view, string $name = null, ...$params): HtmlString
{
$breadcrumbs = $this->generate($name, ...$params);
// TODO: After dropping support for Laravel 5.8 and below, change this to return the view directly
// https://github.com/laravel/framework/pull/29600
$html = $this->viewFactory->make($view, compact('breadcrumbs'))->render();
return new HtmlString($html);
}
/**
* Render breadcrumbs for a page with the default view.
*
* @param string|null $name The name of the current page.
* @param mixed ...$params The parameters to pass to the closure for the current page.
* @return \Illuminate\Support\HtmlString The generated HTML.
* @throws \DaveJamesMiller\Breadcrumbs\Exceptions\InvalidBreadcrumbException if the name is (or any ancestor names are) not registered.
* @throws \DaveJamesMiller\Breadcrumbs\Exceptions\UnnamedRouteException if no name is given and the current route doesn't have an associated name.
* @throws \DaveJamesMiller\Breadcrumbs\Exceptions\ViewNotSetException if no view has been set.
*/
public function render(string $name = null, ...$params): HtmlString
{
$view = config('breadcrumbs.view');
if (!$view) {
throw new ViewNotSetException('Breadcrumbs view not specified (check config/breadcrumbs.php)');
}
return $this->view($view, $name, ...$params);
}
/**
* Get the last breadcrumb for the current page.
*
* Optionally pass a
*
* @return \stdClass|null The breadcrumb for the current page.
* @throws \DaveJamesMiller\Breadcrumbs\Exceptions\UnnamedRouteException if the current route doesn't have an associated name.
* @throws \DaveJamesMiller\Breadcrumbs\Exceptions\InvalidBreadcrumbException if the name is (or any ancestor names are) not registered.
*/
public function current(): ?\stdClass
{
return $this->generate()->where('current', '!==', false)->last();
}
/**
* Get the current route name and parameters.
*
* This may be the route set manually with the setCurrentRoute() method, but normally is the route retrieved from
* the Laravel Router.
*
* #### Example
* ```php
* [$name, $params] = $this->getCurrentRoute();
* ```
*
* @return array A two-element array consisting of the route name (string) and any parameters (array).
* @throws \DaveJamesMiller\Breadcrumbs\Exceptions\UnnamedRouteException if the current route doesn't have an associated name.
*/
protected function getCurrentRoute()
{
// Manually set route
if ($this->route) {
return $this->route;
}
// Determine the current route
$route = $this->router->current();
// No current route - must be the 404 page
if ($route === null) {
return ['errors.404', []];
}
// Convert route to name
$name = $route->getName();
if ($name === null) {
throw new UnnamedRouteException($route);
}
// Get the current route parameters
$params = array_values($route->parameters());
return [$name, $params];
}
/**
* Set the current route name and parameters to use when calling render() or generate() with no parameters.
*
* @param string $name The name of the current page.
* @param mixed ...$params The parameters to pass to the closure for the current page.
* @return void
*/
public function setCurrentRoute(string $name, ...$params): void
{
$this->route = [$name, $params];
}
/**
* Clear the previously set route name and parameters to use when calling render() or generate() with no parameters.
*
* Next time it will revert to the default behaviour of using the current route from Laravel.
*
* @return void
*/
public function clearCurrentRoute(): void
{
$this->route = null;
}
}

View File

@@ -0,0 +1,97 @@
<?php
namespace DaveJamesMiller\Breadcrumbs;
// Not available until Laravel 5.8
//use Illuminate\Contracts\Support\DeferrableProvider;
use Illuminate\Support\ServiceProvider;
/**
* The Laravel service provider, which registers, configures and bootstraps the package.
*/
class BreadcrumbsServiceProvider extends ServiceProvider //implements DeferrableProvider
{
public function isDeferred()
{
// Remove this and uncomment DeferrableProvider after dropping support
// for Laravel 5.7 and below
return true;
}
/**
* Get the services provided for deferred loading.
*
* @return array
*/
public function provides(): array
{
return [BreadcrumbsManager::class];
}
/**
* Register the service provider.
*
* @return void
*/
public function register(): void
{
// Load the default config values
$configFile = __DIR__ . '/../config/breadcrumbs.php';
$this->mergeConfigFrom($configFile, 'breadcrumbs');
// Publish the config/breadcrumbs.php file
$this->publishes([$configFile => config_path('breadcrumbs.php')], 'breadcrumbs-config');
// Register Manager class singleton with the app container
$this->app->singleton(BreadcrumbsManager::class, config('breadcrumbs.manager-class'));
// Register Generator class so it can be overridden
$this->app->bind(BreadcrumbsGenerator::class, config('breadcrumbs.generator-class'));
// Register 'breadcrumbs::' view namespace
$this->loadViewsFrom(__DIR__ . '/../views/', 'breadcrumbs');
}
/**
* Bootstrap the application events.
*
* @return void
*/
public function boot(): void
{
// Load the routes/breadcrumbs.php file
$this->registerBreadcrumbs();
}
/**
* Load the routes/breadcrumbs.php file (if it exists) which registers available breadcrumbs.
*
* This method can be overridden in a child class. It is called by the boot() method, which Laravel calls
* automatically when bootstrapping the application.
*
* @return void
*/
public function registerBreadcrumbs(): void
{
// Load the routes/breadcrumbs.php file, or other configured file(s)
$files = config('breadcrumbs.files');
if (! $files) {
return;
}
// If it is set to the default value and that file doesn't exist, skip loading it rather than causing an error
if ($files === base_path('routes/breadcrumbs.php') && ! is_file($files)) {
return;
}
// Support both Breadcrumbs:: and $breadcrumbs-> syntax by making $breadcrumbs variable available
/** @noinspection PhpUnusedLocalVariableInspection */
$breadcrumbs = $this->app->make(BreadcrumbsManager::class);
// Support both a single string filename and an array of filenames (e.g. returned by glob())
foreach ((array) $files as $file) {
require $file;
}
}
}

View File

@@ -1,47 +0,0 @@
<?php namespace DaveJamesMiller\Breadcrumbs;
use Illuminate\Contracts\Routing\Registrar as Router;
class CurrentRoute {
protected $route;
protected $router;
public function __construct(Router $router)
{
$this->router = $router;
}
public function get()
{
if ($this->route)
return $this->route;
$route = $this->router->current();
if (is_null($route))
return ['', []];
$name = $route->getName();
if (is_null($name)) {
$uri = head($route->methods()) . ' /' . $route->uri();
throw new Exception("The current route ($uri) is not named - please check routes.php for an \"as\" parameter");
}
$params = array_values($route->parameters());
return [$name, $params];
}
public function set($name, $params)
{
$this->route = [$name, $params];
}
public function clear()
{
$this->route = null;
}
}

View File

@@ -1,4 +0,0 @@
<?php namespace DaveJamesMiller\Breadcrumbs;
class Exception extends \Exception {
}

View File

@@ -0,0 +1,51 @@
<?php
namespace DaveJamesMiller\Breadcrumbs\Exceptions;
use DaveJamesMiller\Breadcrumbs\BreadcrumbsException;
use Facade\IgnitionContracts\Solution;
use Facade\IgnitionContracts\BaseSolution;
use Facade\IgnitionContracts\ProvidesSolution;
use Illuminate\Support\Str;
/**
* Exception that is thrown if the user attempts to register two breadcrumbs with the same name.
*
* @see \DaveJamesMiller\Breadcrumbs\BreadcrumbsManager::register()
*/
class DuplicateBreadcrumbException extends BreadcrumbsException implements ProvidesSolution
{
private $name;
public function __construct($name)
{
parent::__construct("Breadcrumb name \"{$name}\" has already been registered");
$this->name = $name;
}
public function getSolution(): Solution
{
// Determine the breadcrumbs file name(s)
$files = (array)config('breadcrumbs.files');
$basePath = base_path() . DIRECTORY_SEPARATOR;
foreach ($files as &$file) {
$file = Str::replaceFirst($basePath, '', $file);
}
if (count($files) === 1) {
$description = "Look in `$files[0]` for multiple breadcrumbs named `{$this->name}`.";
} else {
$description = "Look in the following files for multiple breadcrumbs named `{$this->name}`:\n\n- `" . implode("`\n -`", $files) . '`';
}
$links = [];
$links['Defining breadcrumbs'] = 'https://github.com/davejamesmiller/laravel-breadcrumbs#defining-breadcrumbs';
$links['Laravel Breadcrumbs documentation'] = 'https://github.com/davejamesmiller/laravel-breadcrumbs#laravel-breadcrumbs';
return BaseSolution::create('Remove the duplicate breadcrumb')
->setSolutionDescription($description)
->setDocumentationLinks($links);
}
}

View File

@@ -0,0 +1,72 @@
<?php
namespace DaveJamesMiller\Breadcrumbs\Exceptions;
use DaveJamesMiller\Breadcrumbs\BreadcrumbsException;
use Facade\IgnitionContracts\BaseSolution;
use Facade\IgnitionContracts\ProvidesSolution;
use Facade\IgnitionContracts\Solution;
use Illuminate\Support\Facades\Request;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\Str;
/**
* Exception that is thrown if the user attempts to generate breadcrumbs for a page that is not registered.
*/
class InvalidBreadcrumbException extends BreadcrumbsException implements ProvidesSolution
{
private $name;
private $isRouteBound = false;
public function __construct($name)
{
parent::__construct("Breadcrumb not found with name \"{$name}\"");
$this->name = $name;
}
public function setIsRouteBound()
{
$this->isRouteBound = true;
}
public function getSolution(): Solution
{
// Determine the breadcrumbs file name
$files = (array)config('breadcrumbs.files');
if (count($files) === 1) {
$file = Str::replaceFirst(base_path() . DIRECTORY_SEPARATOR, '', $files[0]);
} else {
$file = 'one of the files defined in config/breadcrumbs.php';
}
// Determine the current route name
$route = Route::current();
$routeName = $route ? $route->getName() : null;
if ($routeName) {
$url = "route('{$this->name}')";
} else {
$url = "url('" . Request::path() . "')";
}
$links = [];
$links['Defining breadcrumbs'] = 'https://github.com/davejamesmiller/laravel-breadcrumbs#defining-breadcrumbs';
if ($this->isRouteBound) {
$links['Route-bound breadcrumbs'] = 'https://github.com/davejamesmiller/laravel-breadcrumbs#route-bound-breadcrumbs';
}
$links['Silencing breadcrumb exceptions'] = 'https://github.com/davejamesmiller/laravel-breadcrumbs#configuration-file';
$links['Laravel Breadcrumbs documentation'] = 'https://github.com/davejamesmiller/laravel-breadcrumbs#laravel-breadcrumbs';
return BaseSolution::create("Add this to $file")
->setSolutionDescription("
```php
Breadcrumbs::for('{$this->name}', function (\$trail) {
\$trail->push('Title Here', $url);
});
```")
->setDocumentationLinks($links);
}
}

View File

@@ -0,0 +1,63 @@
<?php
namespace DaveJamesMiller\Breadcrumbs\Exceptions;
use DaveJamesMiller\Breadcrumbs\BreadcrumbsException;
use Facade\IgnitionContracts\BaseSolution;
use Facade\IgnitionContracts\ProvidesSolution;
use Facade\IgnitionContracts\Solution;
use Illuminate\Routing\Route;
use Illuminate\Support\Arr;
use Illuminate\Support\Facades\App;
use Illuminate\Support\Str;
/**
* Exception that is thrown if the user attempt to render breadcrumbs for the current route but the current route
* doesn't have a name.
*/
class UnnamedRouteException extends BreadcrumbsException implements ProvidesSolution
{
/**
* @var Route
*/
private $route;
public function __construct(Route $route)
{
$uri = Arr::first($route->methods()) . ' /' . ltrim($route->uri(), '/');
parent::__construct("The current route ($uri) is not named");
$this->route = $route;
}
public function getSolution(): Solution
{
$method = strtolower(Arr::first($this->route->methods()));
$uri = $this->route->uri();
$action = $this->route->getActionName();
if ($action === '\Illuminate\Routing\ViewController') {
$method = 'view';
$action = "'" . ($this->route->defaults['view'] ?? 'view-name') . "'";
} elseif ($action === 'Closure') {
$action = "function() {\n ...\n}";
} else {
$action = "'" . Str::replaceFirst(App::getNamespace() . 'Http\Controllers\\', '', $action) . "'";
}
$links = [];
$links['Route-bound breadcrumbs'] = 'https://github.com/davejamesmiller/laravel-breadcrumbs#route-bound-breadcrumbs';
$links['Silencing breadcrumb exceptions'] = 'https://github.com/davejamesmiller/laravel-breadcrumbs#configuration-file';
$links['Laravel Breadcrumbs documentation'] = 'https://github.com/davejamesmiller/laravel-breadcrumbs#laravel-breadcrumbs';
return BaseSolution::create('Give the route a name')
->setSolutionDescription("For example:
```php
Route::$method('$uri', $action)->name('sample-name');
```")
->setDocumentationLinks($links);
}
}

View File

@@ -0,0 +1,25 @@
<?php
namespace DaveJamesMiller\Breadcrumbs\Exceptions;
use DaveJamesMiller\Breadcrumbs\BreadcrumbsException;
use Facade\IgnitionContracts\Solution;
use Facade\IgnitionContracts\BaseSolution;
use Facade\IgnitionContracts\ProvidesSolution;
/**
* Exception that is thrown if the user attempts to render breadcrumbs without setting a view.
*/
class ViewNotSetException extends BreadcrumbsException implements ProvidesSolution
{
public function getSolution(): Solution
{
$links = [];
$links['Choosing a breadcrumbs template (view)'] = 'https://github.com/davejamesmiller/laravel-breadcrumbs#3-choose-a-template';
$links['Laravel Breadcrumbs documentation'] = 'https://github.com/davejamesmiller/laravel-breadcrumbs#laravel-breadcrumbs';
return BaseSolution::create('Set a view for Laravel Breadcrumbs')
->setSolutionDescription("Please check `config/breadcrumbs.php` for a valid `'view'` (e.g. `'breadcrumbs::bootstrap4'`)")
->setDocumentationLinks($links);
}
}

View File

@@ -1,18 +0,0 @@
<?php namespace DaveJamesMiller\Breadcrumbs;
use Illuminate\Support\Facades\Facade as BaseFacade;
class Facade extends BaseFacade {
/**
* Get the registered name of the component.
*
* @return string
*/
protected static function getFacadeAccessor()
{
// App::make('breadcrumbs')
return 'breadcrumbs';
}
}

View File

@@ -0,0 +1,37 @@
<?php
namespace DaveJamesMiller\Breadcrumbs\Facades;
use DaveJamesMiller\Breadcrumbs\BreadcrumbsManager;
use Illuminate\Support\Facades\Facade;
/**
* Breadcrumbs facade - allows easy access to the Manager instance.
*
* @method static void for(string $name, callable $callback)
* @method static void register(string $name, callable $callback)
* @method static void before(callable $callback)
* @method static void after(callable $callback)
* @method static bool exists(string $name = NULL)
* @method static \Illuminate\Support\Collection generate(string $name = NULL, ...$params)
* @method static \Illuminate\Support\HtmlString view(string $view, string $name = NULL, ...$params)
* @method static \Illuminate\Support\HtmlString render(string $name = NULL, ...$params)
* @method static \stdClass|null current()
* @method static array getCurrentRoute()
* @method static void setCurrentRoute(string $name, ...$params)
* @method static void clearCurrentRoute()
* @mixin \Illuminate\Support\Traits\Macroable
* @see BreadcrumbsManager
*/
class Breadcrumbs extends Facade
{
/**
* Get the name of the class registered in the Application container.
*
* @return string
*/
protected static function getFacadeAccessor(): string
{
return BreadcrumbsManager::class;
}
}

View File

@@ -1,63 +0,0 @@
<?php namespace DaveJamesMiller\Breadcrumbs;
class Generator {
protected $breadcrumbs = [];
protected $callbacks = [];
public function generate(array $callbacks, $name, $params)
{
$this->breadcrumbs = [];
$this->callbacks = $callbacks;
$this->call($name, $params);
return $this->toArray();
}
protected function call($name, $params)
{
if (!isset($this->callbacks[$name]))
throw new Exception("Breadcrumb not found with name \"{$name}\"");
array_unshift($params, $this);
call_user_func_array($this->callbacks[$name], $params);
}
public function parent($name)
{
$params = array_slice(func_get_args(), 1);
$this->call($name, $params);
}
public function parentArray($name, $params = [])
{
$this->call($name, $params);
}
public function push($title, $url = null, array $data = [])
{
$this->breadcrumbs[] = (object) array_merge($data, [
'title' => $title,
'url' => $url,
// These will be altered later where necessary:
'first' => false,
'last' => false,
]);
}
public function toArray()
{
$breadcrumbs = $this->breadcrumbs;
// Add first & last indicators
if ($breadcrumbs) {
$breadcrumbs[0]->first = true;
$breadcrumbs[count($breadcrumbs) - 1]->last = true;
}
return $breadcrumbs;
}
}

View File

@@ -1,170 +0,0 @@
<?php namespace DaveJamesMiller\Breadcrumbs;
class Manager {
protected $currentRoute;
protected $generator;
protected $view;
protected $callbacks = [];
protected $viewName;
protected $currentRouteManual;
public function __construct(CurrentRoute $currentRoute, Generator $generator, View $view)
{
$this->generator = $generator;
$this->currentRoute = $currentRoute;
$this->view = $view;
}
public function register($name, $callback)
{
if (isset($this->callbacks[$name]))
throw new Exception("Breadcrumb name \"{$name}\" has already been registered");
$this->callbacks[$name] = $callback;
}
public function exists($name = null)
{
if (is_null($name)) {
try {
list($name) = $this->currentRoute->get();
} catch (Exception $e) {
return false;
}
}
return isset($this->callbacks[$name]);
}
public function generate($name = null)
{
if (is_null($name))
list($name, $params) = $this->currentRoute->get();
else
$params = array_slice(func_get_args(), 1);
return $this->generator->generate($this->callbacks, $name, $params);
}
public function generateArray($name, $params = [])
{
return $this->generator->generate($this->callbacks, $name, $params);
}
public function generateIfExists($name = null)
{
if (is_null($name)) {
try {
list($name, $params) = $this->currentRoute->get();
} catch (Exception $e) {
return [];
}
} else {
$params = array_slice(func_get_args(), 1);
}
if (!$this->exists($name))
return [];
return $this->generator->generate($this->callbacks, $name, $params);
}
public function generateIfExistsArray($name, $params = [])
{
if (!$this->exists($name))
return [];
return $this->generator->generate($this->callbacks, $name, $params);
}
/**
* @deprecated Since 3.0.0
* @see generateIfExistsArray
*/
public function generateArrayIfExists()
{
return call_user_func_array([$this, 'generateIfExistsArray'], func_get_args());
}
public function render($name = null)
{
if (is_null($name))
list($name, $params) = $this->currentRoute->get();
else
$params = array_slice(func_get_args(), 1);
$breadcrumbs = $this->generator->generate($this->callbacks, $name, $params);
return $this->view->render($this->viewName, $breadcrumbs);
}
public function renderArray($name, $params = [])
{
$breadcrumbs = $this->generator->generate($this->callbacks, $name, $params);
return $this->view->render($this->viewName, $breadcrumbs);
}
public function renderIfExists($name = null)
{
if (is_null($name)) {
try {
list($name, $params) = $this->currentRoute->get();
} catch (Exception $e) {
return '';
}
} else {
$params = array_slice(func_get_args(), 1);
}
if (!$this->exists($name))
return '';
$breadcrumbs = $this->generator->generate($this->callbacks, $name, $params);
return $this->view->render($this->viewName, $breadcrumbs);
}
public function renderIfExistsArray($name, $params = [])
{
if (!$this->exists($name))
return '';
$breadcrumbs = $this->generator->generate($this->callbacks, $name, $params);
return $this->view->render($this->viewName, $breadcrumbs);
}
/**
* @deprecated Since 3.0.0
* @see renderIfExistsArray
*/
public function renderArrayIfExists()
{
return call_user_func_array([$this, 'renderIfExistsArray'], func_get_args());
}
public function setCurrentRoute($name)
{
$params = array_slice(func_get_args(), 1);
$this->currentRoute->set($name, $params);
}
public function setCurrentRouteArray($name, $params = [])
{
$this->currentRoute->set($name, $params);
}
public function clearCurrentRoute()
{
$this->currentRoute->clear();
}
public function setView($view)
{
$this->viewName = $view;
}
}

View File

@@ -1,83 +0,0 @@
<?php namespace DaveJamesMiller\Breadcrumbs;
use Illuminate\Support\ServiceProvider as BaseServiceProvider;
class ServiceProvider extends BaseServiceProvider {
/**
* Indicates if loading of the provider is deferred.
*
* @var bool
*/
// Can't enable this because there appears to be a bug in Laravel where a
// non-deferred service provider can't use a deferred one because the boot
// method is not called - see DependantServiceProviderTest.
// protected $defer = true;
/**
* Get the services provided by the provider.
*
* @return array
*/
public function provides()
{
return ['breadcrumbs'];
}
/**
* Register the service provider.
*
* @return void
*/
public function register()
{
$this->app->singleton('breadcrumbs', function ($app)
{
$breadcrumbs = $this->app->make('DaveJamesMiller\Breadcrumbs\Manager');
$viewPath = __DIR__ . '/../views/';
$this->loadViewsFrom($viewPath, 'breadcrumbs');
$this->loadViewsFrom($viewPath, 'laravel-breadcrumbs'); // Backwards-compatibility with 2.x
$breadcrumbs->setView($app['config']['breadcrumbs.view']);
return $breadcrumbs;
});
}
/**
* Bootstrap the application events.
*
* @return void
*/
public function boot()
{
$configFile = __DIR__ . '/../config/breadcrumbs.php';
$this->mergeConfigFrom($configFile, 'breadcrumbs');
$this->publishes([
$configFile => config_path('breadcrumbs.php')
]);
$this->registerBreadcrumbs();
}
// This method can be overridden in a child class
public function registerBreadcrumbs()
{
// Load the app breadcrumbs if they're in routes/breadcrumbs.php (Laravel 5.3)
if (file_exists($file = $this->app['path.base'].'/routes/breadcrumbs.php'))
{
require $file;
}
// Load the app breadcrumbs if they're in app/Http/breadcrumbs.php (Laravel 5.0-5.2)
elseif (file_exists($file = $this->app['path'].'/Http/breadcrumbs.php'))
{
require $file;
}
}
}

View File

@@ -1,22 +0,0 @@
<?php namespace DaveJamesMiller\Breadcrumbs;
use Illuminate\Contracts\View\Factory as ViewFactory;
class View {
protected $factory;
public function __construct(ViewFactory $factory)
{
$this->factory = $factory;
}
public function render($view, $breadcrumbs)
{
if (!$view)
throw new Exception('Breadcrumbs view not specified (check the view in config/breadcrumbs.php, and ensure DaveJamesMiller\Breadcrumbs\ServiceProvider is loaded before any dependants in config/app.php)');
return $this->factory->make($view, compact('breadcrumbs'))->render();
}
}