15

In using the laravel framework, how can I call a function defined in base_controller, in a view. For exacmple:

class Base_Controller extends Controller {

    public static function format_something()
    {
         return something;
    }
}

How can i call format_something() in a view file?

Usually the error I get looks something like this: Method [link_to_action] is not defined on the View class.

Probably a silly question, but thanks in advance!

Edit

Okay! First the correct place to do something like this is in the libraries folder. Second, problem is that your class cannot have underscores.

So in application/libraries I made file AppHelper.php with class

class AppHelper {

    public static function format_something()
    {
        return something;
    }
}

And can call it like:

$formated = AppHelper::format_something;

Thanks for the help and the good forum find Boofus McGoofus.

tereško
  • 58,060
  • 25
  • 98
  • 150
Jim
  • 517
  • 2
  • 5
  • 11

3 Answers3

21

For me is working:

Create directory "helpers" or whatever and file:

// app/helpers/AppHelper.php

class AppHelper {

    public static function format_something()
    {
        return something;
    }
}

Add path to composer.json

// composer.json

    "autoload": {
        "classmap": [
                    "app/helpers"   // <-------- add this line
        ]
    },

Run: (reload the autoload)

composer dump-autoload

Now you can call:

$formated = AppHelper::format_something();
Lajdák Marek
  • 2,969
  • 8
  • 29
  • 58
  • This method is also very useful, especially if you are using composer in your project. (FYI this thread was for L3). – Jim Jun 02 '13 at 21:22
  • 4
    Using this technique, I can call the method in the controller, but not in a template. What I ultimately want is to be able to do {{Notifier::alert('info', 'My info message')}} in the view template. How would I achieve that? – John Corry Jun 22 '14 at 15:37
  • Followed this to the letter `Class 'AppHelper' not found` – Edmund Sulzanok Jan 30 '15 at 08:36
10

This answer was written for Laravel 3. For Laravel 4 and after, Lajdák Marek's answer using Composer's autoloader is better.

Functions like format_something() don't belong in the controller. The controller should just be about collecting data from various sources and passing it to the view. It's job is mostly just routing.

I've created a folder called "helpers" in the application folder for all my little helpery functions. To make sure all my controllers, views, and models have access to them, I've included the following in my start.php file:

foreach(glob(path('app').'helpers/*.php') as $filename) {
    include $filename;
}

I suspect that there's a better way to do that, but so far it has worked for me.

J.T. Grimes
  • 4,222
  • 1
  • 28
  • 32
  • So I made a library file called App_Helpers.php with class App_Helpers and from what I can tell my autoloader in start.php is loading the libraries folder by default, yes my app still doesn't seem to know what App_Helpers::format_something() is? – Jim Nov 20 '12 at 20:30
  • 1
    @Jim - I think the answer is here: http://forums.laravel.com/viewtopic.php?pid=18328#p18328 - no underscore in library class names – J.T. Grimes Nov 20 '12 at 20:38
  • If you add files to the libraries folder doesn't it get autoloaded? – mattl Jan 25 '13 at 12:14
  • It does, but for my own reasons on that project, I wanted stand-alone functions rather than objects and (as I recall) the autoloader is happier with classes than with lists of functions. – J.T. Grimes Jan 25 '13 at 16:59
  • This doesnt work for me - it loads the function into the HTML (right at the top, before anything else) BUT it comments it out - which means its not working.. – bagnap Dec 05 '14 at 12:14
3

You can inspire yourself from Laravel framework itself.

I will take your example of a formatter and refer to url helper in Laravel Framework.

Start by creating your own helpers.php file:

<?php

if (! function_exists('format_that')) {
    /**
     * Generate something
     *
     * @param  string  $text
     * @return string
     */
    function format_that($text)
    {
        return app('formatter')->format_that($text);
    }
}

And add it to your composer.json file:

"autoload": {
      "files": [
          "app/helpers/helpers.php"
      ]
}

Run this command to recreate the autoload php file:

$ composer dumpautoload

Create your service provider app/Providers/FormatterServiceProvider.php:

<?php

namespace Illuminate\Routing;

use Illuminate\Support\ServiceProvider;
use App\Helpers\FormatGenerator;

class FormatterServiceProvider extends ServiceProvider
{
    /**
     * Register the service provider.
     *
     * @return void
     */
    public function register()
    {
        $this->app['formatter'] = $this->app->share(function ($app) {
            return new FormatGenerator($app['request']);
        });
    }
}

Register your service provider. Laravel framework invokes register method but you only need to add it to your app config file config/app.php:

 'providers' => [


      /*
       * Application Service Providers...
       */
      App\Providers\AppServiceProvider::class,
      // other providers...
      App\Providers\FormatterServiceProvider::class,

 ]

Finally, create your actual generator class app/Helpers/FormatGenerator.php

<?php

namespace App\Helpers;

use Illuminate\Http\Request;

class FormatGenerator
{

    protected $request;

    /**
     * Create a new URL Generator instance.
     *
     * @param  \Illuminate\Routing\RouteCollection  $routes
     * @param  \Illuminate\Http\Request  $request
     * @return void
     */
    public function __construct(Request $request)
    {
        $this->request = $request;
    }

    public function format_that($text){
        if ($request->path() == "home"){
            return mb_strtoupper($text);
        }
        else{
            return $text;
        }
    }

}

You can optionally create a Facade app/Facade/Formatter.php, to be able to do Formatter::format_that($text):

<?php

namespace App\Facades;

use Illuminate\Support\Facades\Facade;

/**
 * @see \App\Helpers\FormatGenerator
 */

class Formatter extends Facade
{
    protected static function getFacadeAccessor() { return 'formatter'; }
}

You could ask yourself:

  • Why the facade? You can reuse the component somewhere else by simply calling Formatter::format_that($text) instead of app('formatter')->format_that($text). Sugar syntax really.
  • Why the Service provider? Dependence injections. If you need to use Request or want to build a complex object, the Service provider will take care of that for you and make it available in your $app object.
Capripot
  • 1,354
  • 16
  • 26