I'm trying to write my own validation class in Laravel 4. To do this, I created a new directory called app/validators. I then added this directory to the composer.json classmap and ran composer update, like so:
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/validators", <- added here
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
]
My validation class looks like this:
class LinkValidation extends Illuminate\Validation\Validator {
{
public function validateHost($field, $value, $params)
{
return $value == 'test';
}
}
and in my controller, I'm trying to extend the validator like so:
Validator::extend('awesome', 'LinkValidation#supportedHost');
However, I'm getting this error when loading a page:
{
"error":{
"type":"ReflectionException",
"message":"Class LinkValidation does not exist",
"file":"C:\\xampp\\htdocs\\laravel\\vendor\\laravel\\framework\\src\\Illuminate\\Container\\Container.php",
"line":301
}
}
Any ideas why Laravel won't load the class? I thought it'd do it automatically if added to composer's classmap.
Not sure why it isn't working, but I think you should try adding it in app/start/global.php.
/*
|--------------------------------------------------------------------------
| Register The Laravel Class Loader
|--------------------------------------------------------------------------
|
| In addition to using Composer, you may use the Laravel class loader to
| load your controllers and models. This is useful for keeping all of
| your classes in the "global" namespace without Composer updating.
|
*/
ClassLoader::addDirectories(array(
app_path().'/commands',
app_path().'/controllers',
app_path().'/models',
app_path().'/database/seeds',
app_path().'/validators',
));
Always do composer dumpautoload after create new class object.
Related
I had a problem importing libraries into the Laravel project. I want to use the image_QRCode-0.1.3 library coded in php used in Project Laravel.
https://pear.php.net/package/Image_QRCode/download
but when I use the require command in class QRCodeController
<?php
namespace App\Http\Controllers\Api;
use App\Http\Controllers\Controller;
require_once "../../../Library/Image_QRCode-0.1.3/Image_QRCode-0.1.3/Image/QRCode.php";
class QRCodeController extends Controller {
public function genQRCode()
{
$QR = new \Image_QRCode();
$option = array(
'module_size' => 4,
'image_type' => 'png',
'output_type' => 'display',
'error_correct' => 'H',
);
$qrcode = $QR->makeCode(htmlspecialchars("https://blog.shnr.net/?p=526", ENT_QUOTES), $option);
}
}
The program did not run and reported an error.
Please help me, thanks you so much !
To use external classes or any other PHP library into your Laravel project, you have to do the following steps:
1. Create a folder somewhere in your Laravel app that will contain the PHP files you're going to use:
For example you have a custom class, create a folder in the directory app/libraries. Inside app/libraries, paste the PHP files you'll be using (the library files you've downloaded).
2. In your composer.json file, add the folder/directory into your autoload classmap:
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/libraries", <------------------ YOUR CUSTOM DIRECTORY
"app/database/migrations",
"app/database/seeds",
]
}
3. Once you're done, just run composer dump-autoload and you should be able to call your class as follows:
Assuming your class name is SomeClass.php and it's inside the app/libraries directory and you're properly namespaced the class you've just copied over, you can now use SomeClass.php anywhere you need it.
$class = new \some_class_namespace\SomeClass();
You can also give it an alias in your config/app.php file:
/*
|--------------------------------------------------------------------------
| Class Aliases
|--------------------------------------------------------------------------
|
| This array of class aliases will be registered when this application
| is started. However, feel free to register as many as you wish as
| the aliases are "lazy" loaded so they don't hinder performance.
|
*/
'aliases' => [
....
'SomeAlias' => 'app\libraries\SomeClass',
....
],
After then you can instantiate the class from anywhere in your application just like any other classes:
$class = new SomeAlias();
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.
I have made the below composer view for my app. I've placed it in separate file at app/composers.php.
<?php
// namespace App\Modules\Manager\Composer;
// use Illuminate\Support\Facades\View as View ;
/*
|--------------------------------------------------------------------------
| Composers
|--------------------------------------------------------------------------
|
|
*/
View::composer('tshop.includes.header', function($view)
{
$categories = Categories::getWithChilds();
$view->withCategories( $categories);
});
My composer.php file is
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
],
"files": [
"app/composers.php"
]
},
Unfortunately I get this error
Fatal error: Class 'View' not found in C:\xampp\htdocs\eshop\app\composers.php on line 15
Update
I also tried this. I wrote inside app/start/global.php
require app_path().'/composers.php';
and
use Illuminate\Support\Facades\View as View ;
at app/composers.php, getting this error
Fatal error: Call to a member function composer() on a non-object in
C:\xampp\htdocs\eshop\vendor\laravel\framework\src\Illuminate\Support\Facades\Facade.php
on line 211
I don't think your app/composers.php should be autoloaded within composer. Composer's responsibility is to resolve packages and install them for you, which has nothing to do with your application logic, let alone your application's views.
At the point of running composer, it would not have any knowledge of your Laravel app. That means your Laravel facades like View, Input, DB, Auth, etc. are not loaded yet. Thus your code throws Call to a member function composer() on a non-object.
Approach 1:
Laravel does not strictly specify where you put your laravel view composers, so requiring it by adding:
require app_path() . '/composers.php';
at the bottom of app/start/global.php like edi9999 said would be fine.
Don't forget to remove in this case:
"files": [
"app/composers.php"
]
Approach 2: there is a way to autoload your view composers in composer.json!
From example in Laravel docs on view composers, you can do something like...
app/viewcomposers/HeaderViewComposer.php:
class HeaderViewComposer
{
public function compose($view)
{
$categories = Categories::getWithChilds();
$view->withCategories( $categories);
}
}
composer.json:
"classmap": [
...
"app/viewcomposers"
]
app/composers.php:
View::composer('tshop.includes.header', 'HeaderViewComposer');
bottom of app/start/global.php:
require app_path() . '/composers.php';
Unfortunately you still need to add the line above to app/start/global.php so Laravel knows what view composers are defined.
Approach 3: Do autoload class in composer.json + register a custom ServiceProvider
Learning from Using View Composers in Laravel 4 by Philip Brown, we could also add our own custom service provider and not having to edit our app/start/global.php file.
app/viewcomposers/HeaderViewComposer.php:
<?php namespace App\Modules\Manager\Composer;
class HeaderViewComposer
{
public function compose($view)
{
$categories = Categories::getWithChilds();
$view->withCategories( $categories);
}
}
composer.json:
"classmap": [
...
"app/viewcomposers"
]
app/viewcomposers/ViewComposerServiceProvider.php:
<?php namespace App\Modules\Manager\Composer;
use Illuminate\Support\ServiceProvider;
class ViewComposerServiceProvider extends ServiceProvider {
public function register()
{
$this->app->view->composer('tshop.includes.header', 'App\Modules\Manager\Composer\HeaderViewComposer');
}
}
app/config/app.php:
'providers' => array(
...
'App\Modules\Manager\Composer\ViewComposerServiceProvider',
),
As #TheShiftExchange found out, one problem is that you used the "files" options.
As you can see in composer's code, the autoload section corresponds to this:
class ComposerAutoloaderInitf8489489s7f894ds98f47d
{
....
....
public static function getLoader()
{
....
....
$includeFiles = require __DIR__ . '/autoload_files.php';
foreach ($includeFiles as $file) {
composerRequiref4s65f4556sd4f564fsdfd($file);
}
return $loader;
}
}
function composerRequire5894s89f4sd98498489f7b37d($file)
{
require $file;
}
So the files array you specify is required during composer's autoload process, way before the View Facade is loaded.
The providers to the facades are loaded in vendor/laravel/framework/illuminate/foundation/start.php
/*
|--------------------------------------------------------------------------
| Register The Core Service Providers
|--------------------------------------------------------------------------
|
| The Illuminate core service providers register all of the core pieces
| of the Illuminate framework including session, caching, encryption
| and more. It's simply a convenient wrapper for the registration.
|
*/
$providers = $config['providers'];
$app->getProviderRepository()->load($app, $providers);
Actually, the problem with classmaps is an other one: It is that they is no class in your file, so the file will never be loaded so it doesn't do anything.
To make it work, you should add into app/start/global.php at the end of the file:
Instead of
require app_path() . '/filters.php';
Write
require app_path() . '/composers.php';
require app_path() . '/filters.php';
That's the best way I can think of to include files at each load of your application that are not classes.
Okay so I have an project folder inside my Laravel app. named TLGD (the name if my site). Inside i created a form validation helper which is being used to take away unnecessary code form the controller.
here is the folder structure:
TGLD\Validation\Forms
and inside here I have my form helper classes
now in the controller just to test it out I was calling the classes by the use methd from php like so:
use TGLD\Validation\Forms\Login;
login being the class for the login validation
now thus works great so I tried to autoload the TGLD folder so I don't need to add the use line in every controller. Here is my composer.json file
"autoload": {
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
],
"psr-4": {
"TGLD\\": "app/TGLD"
}
},
but when I autoload it it gives me the error that my login class doesn't exist which means the autoloader is not working. Is there a syntax error or am I missing something? I ran
composer dump-autoload -o
well any advice is helpful thank you in advance
What you want to do cannot be done.
You have to use the complete namespace somewhere to identify the class you want to use. You have several options to do this
Using the fully qualified name of the class with namespace like this: new \TGLD\Validation\Forms\Login().
Using a use clause that imports the named class into the current namespace for this file with use TGLD\Validation\Forms\Login; ... new Login();
Using a part of the namespace in the use, and use the rest in the class name: use TGLD\Validation\Forms; ... new Forms\Login();
After you have chosen the class name in one way or the other, PHP knows which class it needs, and then triggers the autoloading if the class is still unknown to PHP.
So you cannot affect the naming of classes with autoloading.
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.