Autoload Helper folder Laravel 5 - php

I would like to call statics methods in a helpers folders.
I have tried many tutos but it's always for just one file.
My config
/app/Helpers/Languages.php -> my static class
composer.json
"autoload": {
"classmap": [
"database",
"app/Helpers/" <- I understand, L5 add in own autoload
app.php
'aliases' => [ ...., 'Languages' => 'App\Helpers\Languages',
What I tried :
Add autoload classmap, HelpersServiceProviders class, namespace (work just in blade template, not in a Controller)
Add autoload psr-4 with and without classmap, namespace
For all the method, I need to put the use 'app/Helpers/Languages' but I would like call just Languages::myFunction() without 'use' . Is it possible ?
I already the 'app/' folder in psr-4 so it will be load folder and my file, isn't it ?
If it's can help when in load a page without I've :
FatalErrorException Class 'App\Http\Controllers\Languages' not found
When I updated composer.json, I did't forgot composer dump-autoload

I don't think the problem you have is because the class is not being autoloaded, but rather because you try to use it the wrong way. Even with the alias you added, when using the class from within a namespace (like App\Http\Controllers) you have to either add an import statement:
use App\Helpers\Languages;
// or with the alias
use Languages;
Or specify the FQN when using it:
\App\Helpers\Languages::myFunction();
// or with the alias
\Languages::myFunction();
You can't really avoid this. What you could do, so you don't have to worry about namespaces: use helper functions without a class. Just like Laravel's helper functions. (route(), 'trans()', etc)

Related

Yii 2: Using a class from inside a require_once

I'm using a 3rd party extension like so:
(This is inside my controller)
require_once Yii::$app->basePath.'/vendor/campaignmonitor/createsend-php/csrest_subscribers.php';
$wrap = new CS_REST_Subscribers($list_id, $auth);
However, this is returning an error that CS_REST_subscribers class is not found.
How do I use this class correctly when the class is inside the file. Unfortunately this extension is older and is not namespaced.
You need to install it using composer with the following command
composer require "campaignmonitor/createsend-php" "6.0.0"
It uses the simplest way, i.e autoloads each class separately. we define the array of paths to the classes that we want to autoload in the composer.json file and if you see the vendor/campaignmonitor/createsend-php/composer.json file inside the package directory
"autoload": {
"classmap": [
"csrest_administrators.php",
"csrest_campaigns.php",
"csrest_clients.php",
"csrest_general.php",
"csrest_events.php",
"csrest_lists.php",
"csrest_people.php",
"csrest_segments.php",
"csrest_subscribers.php",
"csrest_templates.php",
"csrest_transactional_classicemail.php",
"csrest_transactional_smartemail.php",
"csrest_transactional_timeline.php"
]
}
so you won't need the include or require statement, you can directly call any class you want for instance adding the following lines inside your action or view
$authorize_url = CS_REST_General::authorize_url(
'1122',//'Client ID for your application',
'http://example.com/redirect-page',//Redirect URI for your application,
'ViewReports'//The permission level your application requires,
);
print_r($authorize_url);
prints the following
https://api.createsend.com/oauth?client_id=1122&redirect_uri=http%3A%2F%2Fexample.com%2Fredirect-page&scope=ViewReports
For knowledge base if you want to use a Third-party code that is not using autoloader or psr4 you can go through the Yii tutorial

What is autoload in composer.json and how can we use this in laravel?

I am just start working with Laravel, want to create a custom class and want to call this class in every controller. For this, I create a Customer class in app/Library/ folder.
When I tried to autoload this library via composer, json it's giving an error:
Could not scan for classes inside "App/Library/Customer" which does not appear to be a file nor a folder.
How can we use autoload class in controllers?
Customer.php
<?php
namespace App\Library;
use App\Model\User;
class Customer
{
public function login($user_name,$password){
$data = User::where('email', $user_name)
->where('password', $password)
->first();
return $data->id';
}
}
Autoload section of Composer.json
{
"autoload": {
"classmap": [
"database",
"app/Library/Customer"
],
"psr-4": {
"App\\": "app/"
},
"files" : [
"app/Helper/helper.php"
]
}
}
I think you're not understanding what the composer autoload is there for. You use this to include libraries and their dependencies, not really for classes you've created in your app.
What you're better off doing is when you create the controller add in the class you want to use eg:
<?php
use App\Library\Customer;
You will need to put this in every controller.
You should remove it from the classmap group and just add the proper namespace and class. You can see all the psr-4 standards here: http://www.php-fig.org/psr/psr-4/
Lets say you have a folder structure like this:
app
-> Library
-> Customer.php // namespace App\Library; class Customer{}
-> Model
-> User.php // namespace App\Model; class User{}
And all the files should autoload as long as you use the proper namespace and class names.
By the way you should use the Auth facade instead: https://laravel.com/docs/5.4/authentication
There is no need to classmap as already psr-4 autoloading is in place. You've to understand how it works. then you can simply import your classes using use keyword, like this
<?php
use App\Library\Customer;
For more information read PSR-4: Autoloader and take this Tutorial

composer autoload classmap with psr-4

I am trying to change an autoloading system that I've written before.
I'm using composer and at the moment I'm autoloading just one library with class map.
"autoload": {
"classmap": ["libs/"]
}
I want to add a psr-4 loader for the rest of the files and to be able to call the files under libs without namespaces and without "use" them' kind of like aliases in laravel. This is what I'm trying to do:
"autoload": {
"classmap": ["libs/"],
"psr-4": {
"App\\": ""
}
}
So eventually if in "libs" I have the Session class I'm calling it as:
Session::get('anything')
but now after trying to add the psr-4 and calling it from within a namespaced class
namespace App\models;
Class User{
function get(){
return Session::get('anything');
}
}
It won't work anymore because it looks for session within the user's namespace.
I know there are many frameworks which implements it out of the box with aliases.., it's just that this project is kinda old and I'm trying to organize it a bit and get rid of all the requires anywhere - at the moment each model has to be required.
I want to add a psr-4 loader for the rest of the files and to be able to call the files under libs without namespaces and without "use" them' kind of like aliases in laravel.
You can't use the classes without either adding use or adding the fully qualified namespace path starting with the backslash \. This has nothing to do with the way you load these classes, but is a basic requirement of PHP itself - so there is no way around it no matter how you'd like to design your autoloading.
As was commented, adding a backslash works, but this is the required minimum:
namespace App\models;
Class User{
function get(){
return \Session::get('anything');
}
}
I've ended up writing another class that aliasing any classses that i want so i will be able to call them out of the box.
you can see it here:
https://github.com/shahafan/SAmvc-App/blob/master/Config/Aliases.php
basically i'm just using the php class_alias function so i can load all the classes that i want before using them.
i think laravel does it the same way.

"Class not found" What did I miss?

I want to add Accessors and Mutators to a model. In Laravel 4 it worked all fine, but with Laravel 5 I have some trouble.
I have a "lib" folder in my App directory which contains the "db_transformers.php" file. This file holds classes like "dbDate" with a set and get function to transform dates stored in the database to a user-friendly format.
The "db_transformers.php" file is namespaced:
<?php namespace App\lib;
I also rerfer to the folder in my model:
use App\lib;
But my methodes still throw errors:
public function getDateTimeAttribute($value)
{
return dbDate::get($value);
}
This will return a "Class 'App\dbDate' not found" error.
What could be my problem?
You're confusing autoloading (PHP including/requiring a class definition file) with namespaces (a system that allows hierarchical naming of PHP classes/functions to help prevent code conflicts).
It's an easy thing to do. Covering the changes to autoloading in Laravel 5 is beyond the scope of a Stack Overflow question, but if you're interested I've written a multiple article series on how autoloading works with composer/Laravel 4/Laravel 5.
To your specific question, you say you've defined a class named dbDate in a file named db_transformers.php, and db_transformers.php has a namespace of App\lib.
#File: lib/db_transformers.php
namespace App\lib;
//other code
class dbDate
{
//other code
}
//other code
This mean your class's full name is App\lib\dbDate. The entire thing is the class's name. That's probably the biggest thing to get used to with namespaces in PHP.
This means if you wanted to use the class in other code, you'd need to refer to the full class name, including a leading backslash.
return \App\lib\DbDate::get($value);
You could also import the class using the use keyword
use App\lib\DbDate;
//other code
public function getDateTimeAttribute($value)
{
//since we imported the class with `use`, we don't need to type the full name
return DbDate::get($value);
}
The use keywords imports a specific class into the current namespace. When you said
use App\lib;
you were telling PHP
You know that global classApp\lib? I'm going to refer to it below as lib
Since you don't have a class named lib, this is meaningless, and it's why your use didn't help.
So that's namespaces. The other problem you need to solve is autoloading. Autoloading is what lets you skip the require or include statement/function when you want a class definition files in your project.
Laravel 4 used a bunch of different autoloaders, including something called a classmap autoloader. The classmap autoloader automatically parses all the files in your project looking for classes, and creates a giant map of which class is where (that's over simplifying it a bit, see the article series I linked earlier for the full details).
In Laravel 4, the classmap autoloader probably read the file in lib for you. Laravel 5 reduced the number of autoloaders, which included getting rid of the classmap autoloader for most folders.
The simplest thing you can do in Laravel 5 is to configure your project to use the classmap autoloader again. Open up composer.json and find this section
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/"
}
},
And add lib to the classmap autoloader section
"autoload": {
"classmap": [
"database",
"lib"
],
"psr-4": {
"App\\": "app/"
}
},
This tells composer to include the lib folders when it creates its autoloader files. You'll need to run the dumpautoload command
composer dump-autoload
after doing that, and you should be able to use the classes defined in lib/db_transformers.php as you wish.
You need to use the complete class name: use App\lib\dbDate;
You might also look into using view decorators for this purpose, as doing it in your model is really not appropriate.
Several packages exist to help with this, e.g. https://github.com/ShawnMcCool/laravel-auto-presenter

Write a user defined class in laravel?

I have class in libraries/myclass.php and a function named myFunction. Also I try to call that function in my controller with the following code
$myclasobj=new libraries\Myclass();
$returnvalue=$myclasobj->myFunction($para);
results that class not found. I dont want it as a helper class and auto load this class. I just want to use as a simple class.I am using laravel 4.How can I obtain this?
Update
Thanks all of you for your great help.
As per #carousel,#Ohgodwhy I make it by namespacing (Actually before I don't know about it).
I make a directory under libraries named mylib and move my class (myclass.php) to it and after that I add namespace mylib; to the top of myclass.php.
And after that I add use mylib\Myclass; to my controller.
Finally I add these lines to composer.json
,
"psr-0": {
"mylib": "app/libraries"
},
After these things my class is working.Thanks to all for helping me
Every new class, in order to be used in Laravel, has to be linked to Application. It can be done in more then one way:
Through class map
With namespacing
By its path
In that sense there is no simple classes. All classes can become a part of Laravel Application flow, if they are referenced correctly with composer.
UPDATE TO MY ANSWER:
Here is a link to best resource that explaines facades.
Assuming that the file hasn't been loaded yet, the proper way to add your libraries/ directory to the classloader would be to modify your composer.json to add the directory to the autoloader.
autoload: {
classmap: [
"...",
"libraries/"
]
}
After that, you'll need to rebuild the autoloader, so in the home directory, go ahead and run this in your terminal:
$ php artisan dump-autoload -o
Also ensure that your class is actually contained inside a namespace, because using
new libraries\myClass();
Does not load "myClass" from the "libraries" folder. It would be helpful if you could add it to the original question.
Try doing this, it should solve your problem:
ClassLoader::addDirectories(array(
app_path().'/commands',
app_path().'/controllers',
app_path().'/models',
app_path().'/database/seeds',
app_path().'/classes', //we added this
));

Categories