How to share one method to all controllers in Laravel? - laravel

How to share one method to all controllers with different DI, view and parameters? I need something like this:
public function method(Model $model)
{
$baseData = [
'model' => $model,
'route' => route('$route', [$param => $model]),
];
return view($view);
}

All controllers extend App\Http\Controllers\Controller so you can just place it there
<?php
namespace App\Http\Controllers;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
public function method(Model $model, $route, $param, $view)
{
// Declared but not used
$baseData = [
'model' => $model,
'route' => route($route, [$param => $model]),
];
return view($view);
}
}
And use it with $this->method()
For example in HomeController
<?php
namespace App\Http\Controllers;
use App\User;
class HomeController extends Controller
{
/**
* Show the application dashboard.
*
* #return \Illuminate\Contracts\Support\Renderable
*/
public function index()
{
$user = User::first();
return $this->method($user, 'home', 'user', 'welcome');
}
}
Now accessing domain.tld/home will return the welcome view

If you want to share function to all controller best way will make service in service folder of app.
step to make service:-
1.create service using artisan command
php artisan make:service service_name and define function that to share to all controller in your project.
after making service your have to register this service with provider.make a provider using artisan command.
php artisan make provider:provider_name and you will see 2 function register and boot
register function is used to register your created service and boot for call already register service
register service like this
public function register()
{
$this->app->bind('App\Services\servicename', function( $app ){
return new serviceclassname;
});
}
3.Go config folder ,open app.php where you will get providers array. In this provider you have to define you provider like App\Providers\providerclassname::class,
call this service in controllers like use App\Services\serviceclassname;
public function functionname(serviceclassname serviceobject)
{
serviceobject->functionname();
}

Related

Where to use Event Logger Controller in Laravel

I create an Event Controller to log all the request to my APIs. I know that using a controller inside other controller is not a good idea, so... Where do I have to implement it?
EventController:
<?php
namespace App\Http\Controllers;
use App\Http\Controllers\Controller;
use App\Event;
class EventController extends Controller
{
protected static $instance = null;
/** call this method to get instance */
public static function instance(){
if (static::$instance === null){
static::$instance = new static();
}
return static::$instance;
}
/** protected to prevent cloning */
protected function __clone(){
}
/** protected to prevent instantiation from outside of the class */
protected function __construct(){
}
public function create($type, $description){
Event::create([
'id_type' => $type,
'date_time' => date('Y-m-d H:i:s'),
'id_users' => auth()->user()->id,
'description' => $description
]);
}
}
2 way i suggest:
1.make an event and fire it in all actions.
2.make a middleware and add it in your each routing(or add in routegroup)
Second one is better.because middlewares made exactly for this reason.All requests that sends to server should pass middleware first .
In brief:you should create middleware with php artisan make:middleware yourMiddlewareName and after add your controller code in it you should add name of this middleware in kernel.php in middlewares array.
Now its ready for assign it for every routes you want by append ->middleware("yourMiddlewareName") in end if each one.

Laravel - Custome Auth Throttlelogins

I have created a custom authentication and everything is working fine.
Now I am trying to add the Throttlelogins to prevent multiple incorrect login attempts. But The ThrottleLogins doesn't seem to load.
Q: What am I missing here? or am I doing something wrong?
The exception:
Method
App\Http\Controllers\Auth\CustomersLoginController::hasTooManyLoginAttempts
does not exist.
<?php
namespace App\Http\Controllers\Auth;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Foundation\Auth\AuthenticatesUsers;
use Illuminate\Validation\ValidationException;
use Illuminate\Foundation\Auth\ThrottlesLogins;
use Auth;
class CustomersLoginController extends Controller
{
public function __construct()
{
$this->middleware('guest:customers');
}
public function ShowLoginForm()
{
return view('auth.customer-login');
}
public function login(Request $request)
{
$v = $request->validate([
'email' => 'required|email',
'password' => 'required',
]);
if ($this->hasTooManyLoginAttempts($request)) {
$this->fireLockoutEvent($request);
return $this->sendLockoutResponse($request);
}
if(Auth::guard('customers')->attempt(['email'=>$request->email,'password'=>$request->password],$request->remember)){
return redirect()->intended(route('customerdashboard'));
};
return $this->sendFailedLoginResponse($request);
}
protected function sendFailedLoginResponse(Request $request)
{
throw ValidationException::withMessages([
$this->username() => [trans('auth.failed')],
]);
}
public function username()
{
return 'email';
}
}
Error Message
Can someone please explain what am I mssing?
The error says you are missing a function: hasTooManyLoginAttempts
In the function login you can see it's trying to call the function but it does not exist in your class. This is where it goes wrong.
update
In the AuthenticateUsers class, which you tried to copy, it's using ThrottlesLogins trait, which you are missing in your controller.
Update your controller like so:
class CustomersLoginController extends Controller
{
use ThrottlesLogins;
Another update
You tried to import the Trait which Laravel uses in their own Login. However this will not work here's why:
When you define a class, it can only have access to other classes within its namespaces. Your controller for instance is defined within the following namespace.
namespace App\Http\Controllers\Auth;
So to use other classes, you need to import them from their own namespaces so you can access them. e.g.:
use Illuminate\Foundation\Auth\ThrottlesLogins;
Now that you have imported the ThrottlesLogins, which is actually a trait, now inside the class you use it to expose all of the methods inside.

Calling a model function from a controller in Laravel 5.2

I have a model config which has the following at the top:
<?php
namespace App;
use DB;
use Illuminate\Database\Eloquent\Model;
class Config extends Model
{
protected $table = 'config';
public function getConfigVariables()
{
$config = DB::table('config')->where('is', '1')->first();
session()->put('name',$config['name']);
session()->put('infoemail',$config['infoemail']);
session()->put('copyrightowner',$config['copyrightowner']);
and I wish to call this in a controller to set up the session so in the route for the top level I set set up
Route::get('/',
[
'uses' => 'ConfigController#ConfigVariables',
'as' => 'home'
]);
The config controller method which does not work is:
public function ConfigVariables()
{
Config::getConfigVariables();
session()->put('thisyear',ReturnCurrentYear());
$footer = "&copy ".session()->get('thisyear').", ".session()->get('name');
session()->put('footer',$footer);
return view('welcome');
}
but this does not work and I am stuck!
Change
public function getConfigVariables()
to
public static function getConfigVariables()
You might want to read up how object oriented works, basically when you do Config::getConfigVariables(); you are trying to call a static method, without instantiating the class.
A good start would be here, the concept applies everywhere.

Passing a variable to a master template in laravel

In laravel i have defined a route like this
Route::get('/', array(){
'as' => 'index',
'uses' => 'HomeController#index'
});
The function index() in the HomeController contains
public function index(){
$index = new ExampleModel;
$data = $index->getExampleList();
return View::make('public.index');
}
Now the problem is i have a master layout called happypath inside layouts folder in my views which yields this public.index content and i need to pass this $data to layouts.happypath. How do i do this ?
You can use a view composer for example:
namespace App\Providers;
use App\ExampleModel;
use Illuminate\Support\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider
{
protected $exampleModel;
public function __construct(ExampleModel $exampleModel)
{
$this->exampleModel = $exampleModel;
}
public function boot()
{
view()->composer('layouts.happypath', function ($view) {
$view->with('publicIndex', $this->exampleModel->getExampleList());
});
}
public function register()
{
//
}
}
So, every time you use/render the layouts.happypath the $publicIndex variable will be attached within the layout. Also you need to add the ComposerServiceProvider class in your config/app.php file in the providers array. You may access/reference the data using $publicIndex variable in your layout. There are other ways like global shared $information using view()->share(...) method to share a peace of data all over the views but this may help you.
I could not figure out the ComposerServiceProvider View::composer thing. So i basically solved it like this in Laravel 4.2. Added this code to the BaseController.php
protected $menuList;
public function __construct() {
$response = API::pool([
['GET', API::url('level')],
]);
$index = new Index();
$index->setCourseList($response[0]->json()['Category']);
$result = $index->getCourseList();
View::share('result', $result); //This line shares the $result globally across all the views in laravel 4.2
}
This can be done with a Service Provider. You can either use an existing one or create a new one.
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\ExampleModel;
class ViewServiceProvider extends ServiceProvider
{
public function boot()
{
$index = new ExampleModel;
$data = $index->getExampleList();
view()->share('public.index', $data);
}
public function register()
{
}
}
Source: EasyLaravel.com

How put data in app.blade.php from controller in Laravel 5

I Need to put some dynamic data from controller to app.blade.php, but I can't find any controller. Where I sholud do this?
Thanks
To inject data into a layout view (a view that's #extended by others) you can use a view composer. How you do that is actually pretty well explained in the documentation
Create a service provider (inside app/Providers):
<?php namespace App\Providers;
use View;
use Illuminate\Support\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider {
public function boot()
{
//
}
public function register()
{
//
}
}
Now inside the boot() method you register your view composer:
View::composer('app', function($view){
$view->with('foo', 'bar');
});
After that, don't forget to register the service provider in config/app.php by adding it to the providers array:
'providers' => [
// other providers
'App\Providers\ComposerServiceProvider'
]
Thanks to lukasgeiter's answer. But it needs some modifications to get it working with all the views rendered by Laravel.
You need to put '*' character as a wildcard, so you may attach a composer to all views
View::composer('*', function($view){
//any code to set $val variable
$val = 'bar';
$view->with('foo', $val);
});
so complete class of app\Providers\ComposerServiceProvider.php will be like,
<?php
namespace App\Providers;
use View;
use Illuminate\Support\ServiceProvider;
class ComposerServiceProvider extends ServiceProvider {
public function boot()
{
View::composer('*', function($view){
//any code to set $val variable
$val = 'bar';
$view->with('foo', $val);
});
}
public function register()
{
//
}
}
Also register service provider in config\app.php file as,
'providers' => [
// Other Service Providers...
App\Providers\ComposerServiceProvider::class,
],
Now you can use $foo variable in your resources\views\layouts\app.blade.php file as
<div>
{{$foo}}
</div>
this will render to client as
<div>
bar
</div>

Resources