Use Models / Controllers from a sub directory in new project - php

So I've been asked to create a new project in Laravel (5.4). The project will need to load in a "platform" which is also built in Laravel 5.4 and contains already written controllers and models.
I am currently autoloading the platform in composer as so :
"psr-4": {
"App\\": "app/",
"Frontend\\": "app/Modules/Frontend/",
"Admin\\": "app/Modules/Admin/",
"Platform\\": "../platform/Modules/"
}
I have a routes file with the following in it :
Route::get('/', 'HomeController#index')->name('home');
Then inside of my HomeController, I'm trying to load the platforms' HomeController.
use Platform\Modules\Frontend\Controllers\HomeController as HC;
I am then presented with the error
Class 'Platform\Modules\Frontend\Controllers\HomeController' not found
Is this at all possible to do, wise to do? I'm open to any form of suggestions.

I have managed to mimic your situation in 2 PHP hello world projects.
The problem here is that your 2 projects are using the same namespace App and when you try to autoload the 2nd project into the namespace Platform, you get Class not found error. This is because your PSR-4 namespace for Platform doesn't correspond the namespace in your 2nd project.
App\Modules\Frontend\Controllers is never Platform\Modules\Frontend\Controllers. Those are totally 2 different namespaces.
Hopefully, there's a solution for this by providing an array of paths to the common namespace in both projects.
"psr-4": {
"App\\": ["app/", "../platform/Modules/"],
"Frontend\\": "app/Modules/Frontend/",
"Admin\\": "app/Modules/Admin/"
}
In your HomeController, load your controller like this:
use App\Modules\Frontend\Controllers as HC;
Always double check running the command below if you get Class not found error:
composer dump-autoload

Related

Laravel package migration class can not find sibling class

I'm creating a Laravel package.
This is my folder structure:
- host => (a laravel app to test the package)
- WebSite
- packages
- Company
- FirstPackage
- database
- migrations
- src
- Models
- Http
- Controllers
Inside migrations folder I have two migration classes:
2021-06-04-create-customers-table
2021-06-04-add-name-to-customers
Inside CreateCustomersTable class I have a constant called TABLE_NAME.
Inside AddNameToCustomers class I want to reuse that constant, and I simply use it like CreateCustomersTable::TABLE_NAME.
My IDE which is VS Code does not complain. But when I run php artisan migration, I get this error:
Class 'CreateCustomersTable' not found
at packages/Company/FirstPackage/database/migrations/2021-06-04-add-name-to-customers.php:line_number
Based on Laravel migrations: Class "not found", I made sure class names match file names, and I also tried to map classes in composer.json:
"autoload": {
"classmap": [
"database/migrations"
],
"psr-4": {
"Company\\FirstPackage\\": "src/"
}
},
But none of these values worked for me:
database/migrations
app/database/migrations
Company/FirstPackage/database/migrations
So I have two questions.
First: How can I fix this?
Second and more important: How should I debug class not found bugs?
Just use composer dumpautoload first, if it doesn't help follow below steps:)
First way: use a flag when executing migration commands.
This is inconvenient, but if you really need it, you can try:
php artisan migrate --path=/path/to/your/dir/with/migrations
Second way: you can add the paths that your migrations are in to your AppServiceProvider using $this->loadMigrationsFrom($paths);
How should I debug class not found bugs?
Check file name and class name;
Check the path where the class is located;
Run composer dumpautoload it can help you with warning messages like this
Class App\Namespace\To\Class\ClassName located in ./app/directory/to/class/ClassName.php does not comply with psr-4 autoloading standard. Skipping.;
And finally you can check vendor/composer/autoload_* files to find your mistakes.

Laravel package development - Target class [ControllerName] does not exist

I'm following a tutorial on how to create laravel packages.
I'm using Laravel v8.42.1 (PHP v7.4.3) and jetstream package.
I'm stuck on creating a controller for my package, I always get following error when trying to connect to my url via the laraval app (<base-url/playground):
Target class [TestVendor\TestPackage\Http\Controllers\PlaygroundController] does not exist.
The TestVendor\TestPackage\src\routes.php is recognized by the main application:
use TestVendor\TestPackage\Http\Controllers\PlaygroundController;
use Illuminate\Support\Facades\Route;
Route::get('/playground', [PlaygroundController::class, 'index']);
And is loaded from my ServiceProvider class:
$this->loadViewsFrom(__DIR__.'/resources/views', 'playground');
loadRoutesFrom(__DIR__.'/routes.php');
My namespacing is also normally correctly written in the composer.json of my package:
"autoload": {
"psr-4": {
"TestVendor\\TestPackage\\": "src/"
}
},
And I have my PlaygroundController in src/Http/Controllers/PlaygroundController.php:
namespace TestVendor\TestPackage\Http\Controllers;
use Illuminate\Routing\Controller;
class PlaygroundController extends Controller
{
public function index()
{
return view('playground::hello');
}
}
The view is also in the right package.
I'm using https://github.com/Jeroen-G/laravel-packager to scaffold my packages.
Did multiple composer auto-load and composer updates.
It seems my controller is not recognized in the main application, I think somewhere my name spacing is not correct?
I already had a look at:
Target class controller does not exist - Laravel 8
Solution did not work
Target class does not exist. problem in laravel 8
Solution did not work
You have namespaced your controller as:
namespace TestVendor\TestPackage\Http\Controllers;
In the line above though you say:
And I have my PlaygroundController in src/Http/PlaygroundController.php:
Unless that is a typo, you need to add a Controllers directory underneath Http and put your PlaygroundController in there:
src/Http/Controllers/PlaygroundController.php
For psr-4 autoloading, your folder structure and namespaces should mimic each other.

ErrorException (E_ERROR) Class 'app\MyLib\MyClass' not found - Similar class working fine

I am creating a web application. I am relatively new to Laravel, and still learning. Anyway, here is my problem:
I am trying to include custom class into my project. I managed to include one class - Administrator, and tried to do the same with the other - Profesor, but despite the fact that first is working fine, the other does not.
I created files inside my app folder, subfolder Biblioteka, named Administrator and Profesor.
Inside each file I put:
namespace app\Biblioteka;
Inside composer.json I made following alterations:
"autoload": {
"psr-4": {
"App\\": "app/"
},
"classmap": [
"database/seeds",
"database/factories",
"app/Biblioteka/Administrator",
"app/Biblioteka/Profesor"
],
"files": ["app/Biblioteka/Administrator.php",
"app/Biblioteka/Profesor.php"]
},
After that I run:
php artisan route:clear
php artisan cashe:clear
composer dump-autoload
and got the following message:
[RuntimeException]
Could not scan for classes inside "app/Biblioteka/Administrator"
which does not appear to be a file nor a folder
dump-autoload [--no-scripts][-o|--optimize][-a|--classmap-
authoritative][--apcu][--no-dev]
I included:
use app\Biblioteka\Administrator;
use app\Biblioteka\Profesor;
in files using mentioned classes.
Application is working for class Administrator, but not for class Profesor.
Class Administrator was created first. After everything started working properly I made class Profesor the same way as I did with Administrator. It reports the error at the line where constructor for the class is called. I cannot figure out why the second class is not working properly.
Thanks to anyone who can help me figure this one out :)
There's no need to add to the classmap and files blocks if you're putting your custom classes in the app directory. Remove those lines, then just do use App/Biblioteka/Administrator; in your PHP files.
This bit:
"psr-4": {
"App\\": "app/"
},
means that anything in the app directory can be referenced via the App namespace. Thus, for app/Foo/Bar.php, the class is referenced as App\Foo\Bar.

Create new classes in laravel 5.2

I'm working with Laravel framework.
I have a question regarding classes creation.
To explain my question, i will give you an example:
class articleController extends Controller{
public function bla(){
$a = new MyNewClass($colorfulVariable);
$b = $a->createSomething(new MySecondNewClass());
}
}
Now, the classes MyNewClass and MySecondNewClass do not exist, I want to create them, use them in every controller I want, just like I use the Redirect or Request classes that Laravel offers.
How can i create this classes? Make a new functions to use them in my laravel project?
you can just create those classes in your app folder (or in subfolder for example we create a Libraries folder with all the utilities). Just include a use App\YourClass; before using those classes and laravel will include the classes for you
Laravel 5.* is autoloaded using PSR-4, within the app/ directory. You can see this in the composer.json file.
"autoload": {
"classmap": [
"database/seeds",
"database/factories"
],
"psr-4": {
"App\\": "app/"
}
},
Basically, you could create another directory within app, and then namespace your files in there as appropriate:
app/folder1/folder2/SomeClass.php.
Then, within your SomeClass.php, make sure you namespace it:
<?php namespace App\folder1\folder2;
class Someclass {}
Now, you can access this class using the namespace within your classes:
use App\folder1\folder2\SomeClass;
You can create your classes as usual, but don't forget to include them into composer.json autoload section:
"autoload": {
"classmap": [
"App\MyClassesNamespace"
....
And then run composer dumpauto command to rebuild autoloader file. If you'll not do this, you'll not be able to use your classes in your application.
You don't have to do anything other than below things:
Create a class in App\ folder.
Whenever you use the class, you will have to import the class using "use App\XYZ;" on top of the importing class.
thats it. Mostly people follow convention and then create "Service" folder on App\ folder. It is good to create alien class into service folder which are other than laravel framework classes.

Including my class in a Laravel 5 Project

I made a class in php with some helper methods that parse HTML files.
I'd like to use this class in my Laravel project, but I'm new to Laravel and it's not clear how to add a simple class to a Laravel 5 project.
Is this possible? Or do I need to go to all the trouble of creating a composer package for my class, hosting it somewhere, and then require it in my composer.json file. That seems like a lot of work for including a simple PHP class, and I'm hoping there's an easier way.
As it stands right now there's not a great/easy way to do this in Laravel 5 (possibly by design). The two approaches you can take are
Create a new class in the App namespace
By default Laravel 5.0 looks for App\ prefixed classes in the app/ folder, so something like this should work
#File: app/Helpers/Myclass.php
<?php
namespace App\Helpers;
class Myclass
{
}
and then create your class with
$object = new App\Helpers\Myclass;
This approach, however, relies on you creating classes in the App\ namespace, and there's some ambiguity around if the App\ namespace is owned by Laravel, or is owned by the developer of the application.
Create your own Namespace and Register as PSR-4 autoloader
A better, but more complicated, approach would be to create classes in your own namespace, and then tell Laravel about this namespace by registering a new PSR autoloader.
First, you'd create the class definition
#File: application-lib/Myclass.php
<?php
namespace Pulsestorm;
class Myclass
{
}
Notice we've created a new folder off the root folder to hold our classes named application-lib. You could name this folder anything you like, because in the next step, you're going to add a section to your composer.json file's autoloader section
#File: composer.json
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/",
"Pulsestorm\\": "application-lib/"
}
},
The section we've added is this
"Pulsestorm\\": "application-lib/"
The key to the object (Pulsestorm\) is your namespace. The value (application-lib) is the folder where composer should look for class definition files with the specified namespace.
Once you've added this to composer.json, you'll need to tell Composer to regenerate it's autoload cache files with the dumpautoload command
$ composer dumpautoload
Generating autoload files
After doing the above, you should be able to instantiate your class with
$object = new Pulsestorm\Myclass;
The "real" right way to do this would be to create a generic composer package for your helper class, and then require that composer package into your laravel project. That may, however, be more work than you care to take on for a simple library helper.
If your class is generic enough to use it in other projects, the best way is to release it as a package.
Here's how you create packages with Laravel 5: http://laravel.com/docs/5.0/packages

Categories