Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Add new methods to a resource controller in Laravel

Tags:

laravel

People also ask

How do I add a method to resource controller?

To add another method to the resource you can define a new one below the route resource definition on the "routes/web. php" file. For an example, you can see the command below where it's creating a new controller called "ArticleController" and having the "-r" flag which stands for "resource".

How do you make a resource controller in Laravel?

Creating the Controller This is the easy part. From the command line in the root directory of your Laravel project, type: php artisan make:controller sharkController --resource This will create our resource controller with all the methods we need.

How do I add a controller in Laravel?

Open the command prompt or terminal based on the operating system you are using and type the following command to create controller using the Artisan CLI (Command Line Interface). Replace the <controller-name> with the name of your controller. This will create a plain constructor as we are passing the argument — plain.


Just add a route to that method separately, before you register the resource:

Route::get('foo/bar', 'FooController@bar');
Route::resource('foo', 'FooController');

I just did that, to add a GET "delete" method.

After creating your files, you just need to add

'AntonioRibeiro\Routing\ExtendedRouterServiceProvider',

to 'providers' in your app/config.php

Edit the Route alias in this same file:

'Route'           => 'Illuminate\Support\Facades\Route',

changing it to

'Route'           => 'AntonioRibeiro\Facades\ExtendedRouteFacade',

And make sure those files are being autoloaded, they must be in some directory that you have in your composer.json ("autoload" section).

Then you just need to:

Route::resource('users', 'UsersController');

And this (look at the last line) is the result if you run php artisan routes:

routes list Those are my source files:

ExtendedRouteFacade.pas

<?php namespace AntonioRibeiro\Facades;

use Illuminate\Support\Facades\Facade as IlluminateFacade;

class ExtendedRouteFacade extends IlluminateFacade {

    /**
     * Determine if the current route matches a given name.
     *
     * @param  string  $name
     * @return bool
     */
    public static function is($name)
    {
        return static::$app['router']->currentRouteNamed($name);
    }

    /**
     * Determine if the current route uses a given controller action.
     *
     * @param  string  $action
     * @return bool
     */
    public static function uses($action)
    {
        return static::$app['router']->currentRouteUses($action);
    }

    /**
     * Get the registered name of the component.
     *
     * @return string
     */
    protected static function getFacadeAccessor() { return 'router'; }

}

ExtendedRouter.pas

<?php namespace AntonioRibeiro\Routing;

class ExtendedRouter extends \Illuminate\Routing\Router {

    protected $resourceDefaults = array('index', 'create', 'store', 'show', 'edit', 'update', 'destroy', 'delete');

    /**
     * Add the show method for a resourceful route.
     *
     * @param  string  $name
     * @param  string  $base
     * @param  string  $controller
     * @return void
     */
    protected function addResourceDelete($name, $base, $controller)
    {
        $uri = $this->getResourceUri($name).'/{'.$base.'}/destroy';

        return $this->get($uri, $this->getResourceAction($name, $controller, 'delete'));
    }

}

ExtendedRouteServiceProvider.pas

<?php namespace AntonioRibeiro\Routing;

use Illuminate\Support\ServiceProvider;

class ExtendedRouterServiceProvider extends ServiceProvider {

    /**
     * Indicates if loading of the provider is deferred.
     *
     * @var bool
     */
    protected $defer = true;

    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->app['router'] = $this->app->share(function() { return new ExtendedRouter($this->app); });
    }

    /**
     * Get the services provided by the provider.
     *
     * @return array
     */
    public function provides()
    {
        return array('router');
    }

}

Yeah, It's possible..

In my case I add method : data to handle request for /data.json in HTTP POST method.

This what I did.

First we extends Illuminate\Routing\ResourceRegistrar to add new method data

<?php

namespace App\MyCustom\Routing;

use Illuminate\Routing\ResourceRegistrar as OriginalRegistrar;

class ResourceRegistrar extends OriginalRegistrar
{
    // add data to the array
    /**
     * The default actions for a resourceful controller.
     *
     * @var array
     */
    protected $resourceDefaults = ['index', 'create', 'store', 'show', 'edit', 'update', 'destroy', 'data'];


    /**
     * Add the data method for a resourceful route.
     *
     * @param  string  $name
     * @param  string  $base
     * @param  string  $controller
     * @param  array   $options
     * @return \Illuminate\Routing\Route
     */
    protected function addResourceData($name, $base, $controller, $options)
    {
        $uri = $this->getResourceUri($name).'/data.json';

        $action = $this->getResourceAction($name, $controller, 'data', $options);

        return $this->router->post($uri, $action);
    }
}

After that, make your new ServiceProvider or use AppServiceProvider instead.

In method boot, add this code :

    public function boot()
    {
        $registrar = new \App\MyCustom\Routing\ResourceRegistrar($this->app['router']);

        $this->app->bind('Illuminate\Routing\ResourceRegistrar', function () use ($registrar) {
            return $registrar;
        });
    }

then :

add to your route :

Route::resource('test', 'TestController');

Check by php artisan route:list And you will find new method 'data'


Route::resource('foo', 'FooController');
Route::controller('foo', 'FooController');

Give this a try .Put you extra methods like getData() etc etc .. This worked for me to keep route.php clean


Using Laravel >5 Find the web.php file in routes folder add your methods

You can use route::resource to route all these methods index, show, store, update, destroy in your controller in one line

Route::get('foo/bar', 'NameController@bar');
Route::resource('foo', 'NameController');

Just add a new method and a route to that method.

In your controller:

public function foo($bar=“default”)
{
      //do stuff
}

And in your web routes

Route::get(“foo/{$bar}”, “MyController@foo”);

Just be sure the method in the controller is public.


I solve by

Create a custom router file that extends the BaseRouter

// src/app/Custom/Router.php


<?php

namespace App\Custom;

use Illuminate\Routing\Router as BaseRouter;
use Illuminate\Support\Str;

class Router extends BaseRouter
{
    public function customResource($name, $controller, array $options = [])
    {
        $model = Str::singular($name); // this is optional, i need it for Route Model Binding

        $this
            ->get( // set the http methods
                $name .'/{' . $model . '}/audit',
                $controller . '@audit'
            )->name($name . '.audit');

        return $this->resource($name, $controller, $options);
    }
}

Then register at src/bootstrap/app.php

$app->singleton('router', function ($app) {
    return new \App\Custom\Router($app['events'], $app);
});

And use it on /routes/web.php

Route::customResource(
    'entries',
    'EntryController'
);