Laravel - Loading classes - php

There are questions on here and around Google asking about the same thing, but being a noob, I'm still not getting this. I'm using Laravel 4.
Trying to have a file for random classes. Doesn't load.
The class is in:
app/classes/Helpers.php
Helpers.php:
class Helpers {
public function randomLowerCase($amount)
{
strtolower($str_random($amount))
}
};
I've placed my classes in composer.json.
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/classes",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
]
autoload_classmap.php:
'Helpers' => $baseDir . '/app/classes/Helpers.php',
And also ran
composer dump-autoload
I'm running the function in a UserController.php file in controllers, but I keep getting Call to undefined function randomLowerCase()

The problem is that you're not instantiating an instance of the Helpers class before you call one of its methods. You'll want to do one of the following:
First, keeping your class as it is, you could create an instance in the controller and call your method on it:
// Controller
$helpers = new Helpers;
$helpers->randomLowerCase($str);
Or, you could make the method static and call it as a static method:
// Helpers.php
class Helpers
{
public static function randomLowerCase($amount)
{
strtolower($str_random($amount))
}
};
// Controller
Helpers::randomLowerCase($str);
The error you're getting is because you're running the randomLowercase method as if it were just a function; methods are functions attached to a class/object.

Related

How to unit test views with helper functions in laravel

I have these test cases visiting urls and checking for right behavior but I cant make it work because it errors on my helper functions within the view.
It works on the browser but not in tests.
/** #test */
public function setUp()
{
parent::setUp();
}
/** #test **/
public function openAdminDashboardUnauthorized()
{
$crawler = $this->client->request('GET', 'admin/organizations');
$this->assertTrue($this->client->getResponse()->isOk());
}
/** #test **/
public function tearDown()
{
parent::tearDown();
}
heres the error
EDIT
My helper classes are loaded in the global.php in the classLoader
by the way, this is on laravel 4.2
UPDATE
People say that you have to mock helper functions in order to unit test them. But in my case the helper functions are in the views and I tested dumping a static message from the setup function and indeed it was not loaded during the test run time.
So here's what I found working.
Loaded my helper class in the composer.json autoload sub tree
and run a quick "composer dump-autoload"
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
],
"files": [
"app/helper/Helper.php"
]
}
Now I know the difference between loading classes in global.php and autoloaded through composer. If anyone could explain more on the sequence in which laravel boots the application, I'll accept.
use Mockery, laravel4.2 has it by default. see https://laravel.com/docs/4.2/testing
You should have something like this at the top.
use Mockery as m;
class ClassToTest
{
public function test_some_method()
{
// Mock view helper
$viewHelperMock = m::mock(ViewHelper::class);
// Set expectations
$viewHelperMock->shouldReceive('show');
...
// This must be done only after setting the expectations
$this->app->instance(ViewHelper::class, $viewHelperMock);
...
// Your assertions goes here
}
}
We are binding our own viewHelperMock instance to Laravel's DI container. So whenever the request for ViewHelper class is made, it resolves to our mock instance. So, now you can set the expectations for all of the methods that are called in your view helper.
If you show us your view (html) code then it will be more easier to guide you. Don't get upset, it is tricky and confusing at the beginning. So, give it try multiple time also look at how Laravel's IOC container works.
Let us know if you have any problem following it.

How do you include a global class in laravel

I would like to include a class for every controller to use. Here is what I tried with no luck.
In the Controller.php file, I added this line of code:
use App\Lib\RequestType;
Then in my controller UserController.php, I called a test function.
dd(RequestType::test());
But a fatal error is thrown.
Class 'App\Http\Controllers\RequestType' not found
What is laravel looking for the class in the Controllers folder. Shouldn't UserController inherit the Controller class?
Thanks in advance
If you are trying to write a static class and call it by use, then one option is to make use of autoload feature of composer, which will enable the class to be used anywhere.
"autoload": {
"psr-4": {
"App\\": "app/"
},
"classmap": [
"app/Lib"
]
},
Then in any controller
use RequestType;
then
dd(RequestType::test());
Note: Function test should be like
public static function test()
There is no way to auto-magically have a class everywhere.
PHP use is not inherited by extending classes. Even Laravel's Facades have to specified.
You can store the class in the App\Http\Controllers\Controller->__contruct() to make it more easily manageable.
// App\Http\Controllers\Controller
public function __construct()
{
$this->requestType = new RequestType();
}
// App\Http\Controllers\FooController
public function __construct()
{
parent::__contruct();
}
public function index()
{
$requestType = $this->requestType;
}

psr-4 autoloading not working in Laravel 4

I'm trying to create a directory to store custom classes, so I create the directory app/ArgumentClub/Transformers, and the class UserTransformer.php in that folder.
I then autoload with:
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
],
"psr-4": {
"ArgumentClub\\": "app/ArgumentClub"
}
},
And run composer dump-autoload. And namespace like this:
<?php namespace ArgumentClub\Transformers;
class UserTransformer {
I'm calling this class within another class like this:
<?php
use Sorskod\Larasponse\Larasponse;
use ArgumentClub\Transformers;
class UsersController extends \BaseController {
...
$transformed = $this->fractal->collection($users, new UserTransformer());
But I get the error:
Class 'UserTransformer' not found
What am I doing wrong here?
You're not using the use correctly.
use ArgumentClub\Transformers; imports that Namespace, but doesn't import the class you want to use.
To fix it you can either extend the use statement (which you should) to be like so:
use ArgumentClub\Transformers\UserTransformer
Or you can add the Transformers namespace to where you instantiate your UserTransformer class
$transformed = $this->fractal->collection($users, new Transformers\UserTransformer());
When you want to instantiate a namespaced class without putting the full namespace, you need to put the full class path in the use statement.

Laravel namespaces class not found

I am newbie to Laravel namespaces.
I am trying to do something like this:
namespace App\Controllers; // when I remove this line, everything works fine... I need to include this
class HomeController extends BaseController {
protected $layout = "layouts.main";
public function __construct() {
// some stuff here
}
/**
* Home page.
* #return View
*/
public function getHome() {
// Show the page
$this->layout->content = View::make('home');
}
}
But I am having this weird error,
Class HomeController does not exist
Here is some of my composer.json stuff,
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/libraries",
"app/models",
"app/database/migrations",
"app/database/seeds",
]
},
I have also executed,
composer dump-autoload
While I am routing something like this,
# Default
Route::get('/', array('as' => 'home', 'uses' => 'HomeController#getHome'));
Here's one common case where this error can occur:
Imagine you're defining a route using that class:
Route::get('/home', 'HomeController#getIndex');
The Laravel core is going to pass that string ('HomeController#getIndex') to some method(s) deep in the bowels of the routing class, parse it, instantiate HomeController, and call getIndex. Does that code include a use App\Controllers directive? Not likely, since this is something you've created. Basically, wherever that HomeController class is used (and I have no idea where it is), the PHP interpreter is not going to know where that class comes from.
The solution is to use the fully-qualified class name. That means including the full namespace in the string, like so:
Route::get('/home', '\App\Controller\HomeController#getIndex');
Now when Laravel tries to instantiate the class, it has everything it needs to find it.
I don't know for sure if this is the problem - you need to show us the code where the error occurs - but this is one possibility.
Are you typing use App\Controllers\HomeController in the file where you're trying to use it? This essentially includes it.
You don't use namespaces for Controllers in app/controllers.
HomeController extends BaseController which extends Controller in the framework.
You might want to use namespaces if you are including custom libraries into the framework. /app/libraries for example.
As long as your routes.php has some url to get to a home controller method, it should work.
Route::get('/home', 'HomeController#index');
HomeController.php:
class HomeController extends BaseController {
private $myVar;
public function __construct() {
// some stuff here
}
public function index(){
return View::make('home');
}
}

3rd Party class in laravel

Here is what I've done so far.. based on this link Laravel cannot load 3rd party library
I followed all of it but still Im having this error
{"error":{"type":"Symfony\\Component\\Debug\\Exception\\FatalErrorException","message":"Class 'FileProcess' not found","file":"C:\\xampp\\htdocs\\fileshare\\trunk\\app\\controllers\\UserFilesController.php","line":437}}
my composer.json
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/library",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
]
},
then my controller
<?php
use \FileProcess;
class UserFilesController extends \BaseController {
public function someMethod(){
$fp = new FileProcess;
}
}
then my 3rd party class which is located in app/library/FileProcess.php folder
<?php namespace FileProcess;
class FileProcess
{
// some methods
}
i do not know what is wrong or if there is lacking
The reason Laravel can't find the class is because you have namespaced it and when you call it using use you are calling it from the Global namespace. Either of the following will fix it for you.
1) Remove namespace FileProcess; from the class file
2) In your controller call it using it's namespace use FileProcess\FileProcess;

Categories