Get current route inside service provider in Laravel - php

First of all, I have to tell that I am totally new on Laravel, so if you thing I am in the wrong way, please correct me.
Notice, that I have the Laravel 5.1 installed on my application.
I creating an application and I like to have my breadcrumbs inside an array, so I decide to create a Service Provider, and the code for the Service Provider is the following:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Route;
use Illuminate\Support\ServiceProvider;
class BreadCrumbsServiceProvider extends ServiceProvider
{
// This will contain all the breadcrumb crumbs
protected $crumbs = [];
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
$this->createBreadcrumb();
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
$this->app->singleton(
'crumbs',
function() {
return $this->crumbs;
}
);
}
protected function createBreadcrumb( ) {
dd( Route::current() );
}
}
So ,when I run my site, the dd returns just null. Can someone help me with this situation ?

Inside your service provider class Route::Class won't work. Try these for
current request uri - $this->app->request->getRequestUri()
Current request method - $this->app->request->getMethod()

Related

Laravel container returning multiple Singleton instances

I've created a CustomProvider, added it to the app.php array of providers and registered a class as singleton:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\ReserveCart;
class CustomProvider extends ServiceProvider
{
/**
* Bootstrap services.
*
* #return void
*/
public function boot()
{
//
}
/**
* Register services.
*
* #return void
*/
public function register()
{
$this->app->singleton('App\ReserveCart', function($app){
return new ReserveCart;
});
}
}
but everytime I request for the object with $rc = resolve('App\ReserveCart'); it keeps giving me different instances of the object instead of a single one (I've done some echo tracking).
Also tried passing the dependency to methods acording to Laravel Documentation. e.g
public function foo(App\ReserveCart $rc){
//
}
but the issue persists.
Is the output below same ?
$rc = resolve('App\ReserveCart');
$rc1 = resolve('App\ReserveCart');
dd(spl_object_hash($rc), spl_object_hash($rc1));

Laravel 5.6 Inject variable with Service Provider in a group of routes

I have a part of site that starts with specific prefix /manage.
Can I somehow like with AppServiceProvider view-composers inject a variable in all routes from that prefix?
I tried to do it by passing this variable to layout of all that routes. But then I met a problem. I use this variable in blade view of specific page, and it returns me variable not defined.
Then, I inspect laravel debugger and saw the order of loading of blade files. And it was :
1. Current page view
2. Layout view
3. Sidebars and other stuff
So, the fact that current page is loaded before layout, cause error of undefined variable.
So, how can I solve that ? Thanks.
Code from my Service provider :
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\CT;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
view()->composer(['website.implicare.ct.show', 'website.implicare.ct.petition.index', 'layouts.ct'], function($view) {
$ct = request()->ct;
$permissions = [];
foreach($ct->userPermissions(auth()->id()) as $userPermission) {
if($userPermission->pivot->ct_id == $ct->id) {
array_push($permissions, $userPermission->name);
}
}
$view->with('permissions', $permissions);
});
}
/**
* Register any application services.
*
* #return void
*/
public function register()
{
//
}
}
create ComposerServiceProvider
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public $theme = 'mytheme';
public function boot()
{
view()->composer($this->theme.'.includes.navbar', 'App\Http\ViewComposers\MenuComposer');
view()->composer($this->theme.'.includes.header', 'App\Http\ViewComposers\MenuComposer');
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
//
}
}

Laravel: why a registered service provider is not called when instantiating its provided class?

This is my service provider:
<?php
namespace App\Providers;
use Illuminate\Support\Facades\Config;
use Illuminate\Support\ServiceProvider;
class ESServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
$this->app->singleton('\Elastica\Search', function ($app) {
$client = new \Elastica\Client(array(
'host' => env('ES_HOST'),
'port' => env('ES_PORT')));
$search = new \Elastica\Search($client);
$search->addIndex(Config::get('constants.es_index'))->addType(Config::get('constants.es_type'));
return $search;
});
}
}
When injecting instances of \Elastica\Search\ the closure (2nd param to singleton()) doesn't get called (verified using var_dump() / dd()). The provider is registered correctly - verified as above. Why?
The reason, in Laravel 5.4 and above, is that the first param to singleton() (and similar binding functions) must not have a leading slash. So, changing it to 'Elastica\Search' fixes the problem. It took me about an hour of debugging to realize this - hopefully this post saves someone this time...
Laravel website post explaining this change: http://laravel-guide.readthedocs.io/en/latest/upgrade/ - search for Binding Classes With Leading Slashes.

View composer not working properly in testing mode in Laravel 5.2

I've a view composer written like this
view()->composer('masterbox.partials.pipeline', function($view) {
// Some vars and code
});
In one of my view I do as follow
#include('masterbox.partials.pipeline', ['my_var' => 1])
When i'm trying it on my browser everything is fine, but when I run a simple test everything blows up ... After some debugging I found out the closure wasn't executed at all.
$this->visit('/connect/customer/subscribe')
->type($faker->firstName, 'first_name')
->type($faker->firstName, 'first_name')
->type($faker->lastName, 'last_name')
->type($faker->email, 'email')
->type($faker->phoneNumber, 'phone')
->type($password, 'password')
->type($password, 'password_confirmation')
->press("S'inscrire");
Note : It visits a page, fills the form and subscribe, then it redirects on the page with the #include and it returns a big error, part of it is
exception 'ErrorException' with message 'Undefined variable: my_var' in /Users/Loschcode/Google Drive/projects/my_project_lo/website/storage/framework/views/7e11f284c02bc38adc60b5f8a0545df65d7cf5ec.php:7
I'm afraid it an issue, it's a fresh Laravel 5.2 I downloaded a few days ago. Any guess ? Any method to debug this ? Thanks
Working solution
I ended up trying anything. My problem was my service provider organization.
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
foreach (glob(app_path().'/Http/ViewComposers/*.php') as $filename){
require_once($filename);
}
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
//
}
}
If you have a similar organization and problem, replace the require_once by a simple require and everything will go fine.
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider
{
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
foreach (glob(app_path().'/Http/ViewComposers/*.php') as $filename){
require($filename);
}
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
//
}
}

PHP - Laravel dependency injection: pass parameters to dependency constructor

I'm building a Laravel project and in one of the controllers I'm injecting two dependencies in a method:
public function pusherAuth(Request $request, ChannelAuth $channelAuth) { ... }
My question is really simple: How do I pass parameters to the $channelAuth dependency?
At the moment I'm using some setters to pass the needed dependencies:
public function pusherAuth(Request $request, ChannelAuth $channelAuth)
{
$channelAuth
->setChannel($request->input('channel'))
->setUser(Auth::user());
What are the alternatives to this approach?
P.S. The code needs to be testable.
Thanks to the help I received on this Laracast discussion I was able to answer this question. Using a service provider it's possible to initialize the dependency by passing the right parameters to the constructor. This is the service provider I created:
<?php namespace App\Providers;
use Security\ChannelAuth;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Http\Request;
use Illuminate\Support\ServiceProvider;
class ChannelAuthServiceProvider extends ServiceProvider {
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
$this->app->bind('Bloom\Security\ChannelAuthInterface', function()
{
$request = $this->app->make(Request::class);
$guard = $this->app->make(Guard::class);
return new ChannelAuth($request->input('channel_name'), $guard->user());
});
}
}
You can pass parameters (as a string indexed array) when resolving a dependence like this:
<?php namespace App\Providers;
use Security\ChannelAuth;
use Illuminate\Contracts\Auth\Guard;
use Illuminate\Support\ServiceProvider;
class ChannelAuthServiceProvider extends ServiceProvider {
/**
* Bootstrap the application services.
*
* #return void
*/
public function boot()
{
//
}
/**
* Register the application services.
*
* #return void
*/
public function register()
{
$this->app->bind('Bloom\Security\ChannelAuthInterface', function($params)
{
$channelName = $params['channelName'];
$guard = $this->app->make(Guard::class);
return new ChannelAuth($channelName, $guard->user());
});
}
}
Then when resolving eg in a controller:
public function pusherAuth()
{
$channelAuth = app()->makeWith('Bloom\Security\ChannelAuthInterface', [
'channelName' => $request->input('channel_name')
]);
// ... use $channelAuth ...
}
You can create and register your own service provider and create object with constructor's requests parameters.
I don't know how to do this in Laravel, but in Symfony2 you can inject in your own service something like RequestStack. It's the best way, because you have small service providers that are fully testable.

Categories