Extend Laravel Router - php

I implemented a role/permission system. Now I want to add a method to Laravel router so I can make something like this:
Route::get('sales', 'SaleController#index')->allow('Salesman');
I know that I can use #can('Salesman') (View) and $user->can('Salesman') (Controller) but I found so much readable the way I'm trying to do it since I'll be able to see all role permission access in the routes file.

You can override the router class, then register it into service container to be used by Route facade.
To be more clear:
Write a class that extends Laravel's router (I think Router class). To find this, open the Route facade, then find its service provider. From there, it should be easy to find the router class.
Write a class that overwrites that router. Make sure to extend the class you found before.
Write a service provider that overwrites the router services. The practically means to register your service under the same key name you find in Route facade.
And that should be it. Your service is now picked by Route facade automatically.

As you're using the facade to generate the routes. This should be quite easy. The facade can be overruled in the config/app.php facades array.
You can generate your own Facade class and replace the native one with yours. Which in fact is a Router class. In order to implement the functionality you need to extend and override the following in sequence:
Facade
Router::newRoute
Route
By extending the last one and returning those in the newRoute method of the Router, you'll be able to overrule the logic of Laravel.

Related

ZF3 route with access to db

I am new to zend framework 3 and I am trying to create a new route type that can search in the database to match the route path. I am using doctrine orm and unfortunately I don't know how to inject the entity manager inside the route class.
I tried defining a factory class for the route to have access to the service manager but that didn't work because the route classes must implement Zend\Router\Http\RouteInterface which states that the route class must contain it's own factory defined as "function factory($options)".
Can anyone please help?
Thank you very much.
In the way you ask the question you have to write your custom Router strategy relying on zend-router's interfaces and abstractions.
For eg. ZF support different router strategies to match the URL (as in any modern framework) but you need to write the custom router strategy to access the DB and return what controller/action should be executed.
To be honest if you are new to ZF3 maybe try to solve the problem on little bit less advanced way.
Other solution, maybe you can create dynamic router and pass URL_SLUG.
Than you will have one action where you will check what content you should load from the DB by URL_SLUG (or any other ID you choose).

How to access Tracker (antonioribeiro/tracker) object In Laravel

I am using AntonioRiveiro/Tracker repo for my laravel app. I would like to add some more functionality to it that it doesn't have out of the box.
But I can't find where its instance gets created, or how to access the Tracker object in my Controllers.
Or how do I extend the tracker object?
So I think the easiest way for you to go about this is the following:
First, make your own ServiceProvider
php artisan make:provider CustomTrackerServiceProvider
Now open up that file, we'll need to make some modifications.
Firstly, we'll need to extend the ServiceProvider that Tracker provides.
use PragmaRX\Tracker\Vendor\Laravel\ServiceProvider as TrackerServiceProvider
class CustomTrackerServiceProvider extends TrackerServiceProvider
The use alias above is not required, but I prefer it for clarity given the similar naming convention to the core framework.
Now you'll need to replace your usage of the PragmaRX\Tracker\Vendor\Laravel\ServiceProvider in your config/app.php file under the providers array
config/app.php
'providers' => [
//other providers and what have you
App\Http\Providers\CustomTrackerServiceProvider::class
]
Now you have the ability to make changes. You can override the default functionality of the core class as long as it's member is not private.
Have a look at the vendor provided file and identify a similar architecture pattern to the vendor maintainer, and you'll be good to go.
The answer to this question provides a solution for (2), I found the answer to (1) here.
To access the tracker object you need to include:
use PragmaRX\Tracker\Vendor\Laravel\Facade as tracker;
Then you'll do something like:
$visitor = Tracker::currentSession();
as described in the documentation.

Private functions in Laravel 5 service containers

I'm building an app with Laravel 5.1 using my own service providers to separate some business logic, but I can't seem to find a way to acces other methods of the service provider from within itself.
Using the function name tries to look for something in the namespace App\Providers and there's no $this because it's singleton pattern, so how can I do it? Does it have to "use" itself?
I also don't want an external helper as this function would be specific to this service.
Simply enough it can be done using self::method() or static::method() but your method has to be declared as static.

Laravel - override default facade bindings - how?

http://laravel.com/docs/5.1/facades
Facades are listed on the linked page at the bottom. My question is... How do I override these service container bindings?
Example, the Request facade binds Illuminate\Http\Request with the key request. I want to create my own class which inherits from Illuminate\Http\Request and bind it with the request key, instead of the current class. And I can't find which service provider binds this.
So, I kind of did it. First I noticed these bindings were hardcoded in Illuminate\Foundation\Application::registerCoreContainerAliases() so I extended this class and overrode this method to change it. I also had to call this class now in bootstrap\app.php, but doing all this didn't help, I was still getting an instance of Illuminate\Http\Request.
So then I discovered that Illuminate\Http\Request was directly referenced in public\index.php so I tried changing it there to My\Very\Own\Http\Request and this worked, finally my implementation was being used.
Finally, I deleted my version of Application::registedCoreContainerAliases() and reverted bootstrap\app.php because everything is also working without this change.
I think the following answer would be very useful for you
https://stackoverflow.com/a/39648307/3912276
I quoted the most important part of the answer. It explains how you can replace/extend the Mailer facade
Write your own implementation of Mailer, extending Illuminate\Mail\Mailer, in which you can override the send method, implement your checks and call parent::send().
Write your own service provider (Extending Illuminate\Mail\MailServiceProvider), in particular re-implement the register method. It should create an instance of your own Mailer in place of Laravel's own. (You can copy most of the code from Laravel's register method).
Now, in your config/app.php file, in the providers array, replace Illuminate\Mail\MailServiceProvider::class, with your own provider.

Laravel/Lumen: View::share() alternative?

I've been using Laravel for a long time, and I'm now writing a micro-project using Lumen.
I need to pass some variables to all views. In Laravel I can use the View::share() function in a middleware or in the controller's constructor, but in Lumen there is no View class, and it looks like all view functionality is simply View::make() alias.
Is there a way to share variables to all views?
For performance reasons, Lumen doesn't register facades and service providers the way Laravel does. While the Laravel facades are included with Lumen, only some are aliased (View not being one of them), and only if you uncomment the $app->withFacedes(); line in bootstrap/app.php (you can check the Laravel\Lumen\Application::withFacades method to see which ones). So in order to use other facades such as View, you either need to alias the facade class yourself:
// "bootstrap/app.php" is a good place to add this
class_alias('Illuminate\Support\Facades\View', 'View');
Or you can include it with use wherever needed:
use Illuminate\Support\Facades\View;
The correct way to share data with views in Lumen is:
app('view')->share(...);
Some of Laravel's functionality that is not explicitly described in Lumen documentation can be accessed with Lumen's app() helper function.

Categories