I'm trying to structure my Laravel 4 site such that (1) major application groups' components (controllers/views/etc) are coupled together and (2) Laravel's supporting code outside of in my web server's document root. The default laravel home page loads fine, but I can't get a namespaced controller to route correctly. This is the relevant file structure:
/ [Project Root]
/laravel [full laravel install here]
composer.json
/app
/controllers
BaseController.php
/dev
/htdocs
index.php
/app
/PageTypes
/Home
/controllers
HomeController.php
/views
HomeView.blade.php
The default laravel landing page is loading fine. But when I tried setting up a controller with its own namespace, I keep getting the errors.
This is HomeController.php:
namespace PageTypes;
use Home\controllers;
class HomeController extends BaseController {
public function showWelcome()
{
return View::make('hello');
}
}
Here's routes.php:
<?php
Route::get('/', function()
{
return View::make('hello');
});
Route::get('/home', 'PageTypes\Home\controllers\HomeController#showWelcome' );
This setup yields the error: "Symfony \ Component \ Debug \ Exception \ FatalErrorException
Class 'PageTypes\BaseController' not found" Ok, laravel is finding HomeController.php at least.
Plenty of other SO responses told me to try changing BaseController to \BaseController. Making that one change and leaving everything else the same yielded the error "ReflectionException: Class PageTypes\Home\controllers\HomeController does not exist." What the?... >.<
I'm not understanding something at the intersection of namespaces, psr-0, and laravel's routing, any help would be REALLY appreciated.
Followup questions: (1) what steps could I have taken to have debugged this? NGINX's logs aren't really telling me anything other than what I see in the exception errors being thrown. (2) Has anyone come across a laravel seed on github that's laid out similarly? I'd love to have something to reference.
Here are my configuration settings:
// index.php
...
require __DIR__.'/../../laravel/bootstrap/autoload.php';
$app = require_once __DIR__.'/../../laravel/bootstrap/start.php';
...
// bootstrap/autoload.php
...
require __DIR__.'/../vendor/autoload.php';
...
// bootstrap/paths.php
...
'app' => __DIR__.'/../app',
'public' => __DIR__.'/../../dev/htdocs/',
'base' => __DIR__.'/..',
'storage' => __DIR__.'/../app/storage',
...
// compose.json
{
"name": "laravel/laravel",
"description": "The Laravel Framework.",
"keywords": ["framework", "laravel"],
"require": {
"laravel/framework": "4.0.*"
},
"autoload": {
"psr-0": {
"PageTypes": "../dev/htdocs/app"
},
"classmap": [
"app/commands",
"app/controllers",
"app/models",
"app/database/migrations",
"app/database/seeds",
"app/tests/TestCase.php"
]
},
"scripts": {
"post-install-cmd": [
"php artisan optimize"
],
"pre-update-cmd": [
"php artisan clear-compiled"
],
"post-update-cmd": [
"php artisan optimize"
],
"post-create-project-cmd": [
"php artisan key:generate"
]
},
"config": {
"preferred-install": "dist"
},
"minimum-stability": "dev"
}
class HomeController extends \BaseController {
Basically because you are in a namespace you need to resolve the BaseController in the global namespace (That's what the \ does).
You could also get away with having
use \BaseController;
class HomeController extends BaseController {
But since you are only going to be referring to BaseController once in the entire controller there's not much point.
The other potential problem is your namespacing which is what PageTypes\Home\controllers\HomeController is referring to. That's not actually the Pathname, thats the namespace name it's looking for (it just so happens that the autoloaders that follow PSR match the directory structure to the namespaces).
Try using
namespace PageTypes\Home;
instead of just PageTypes
Related
I am upgrading a legacy laravel application from Laravel 5 to 8 and ran into a brick wall. None of my service providers work, and I cannot figure out why.
Previous Structure
app
-->Services
------>Stripe
Within each service provider folder, I'd create three files like so:
Stripe.php
StripeFacade.php
StripeServiceProvider.php
within stripe.php
<?php
namespace app\Services\Stripe;
class Stripe
{
}
?>
within StripeFacade.php
<?php
namespace app\Services\Stripe;
use Illuminate\Support\Facades\Facade;
class StripeFacade extends Facade
{
protected static function getFacadeAccessor()
{
return 'Stripe';
}
}
within StripeServiceProvider.php
<?php
namespace app\Services\Stripe;
use Illuminate\Support\ServiceProvider;
class StripeServiceProvider extends ServiceProvider
{
public function register()
{
$this->app->singleton('Stripe', function($app) {
return new Stripe();
});
}
}
in my Config/app.php file, I'd register the service provider and facade like so:
'providers' => [
app\Services\Stripe\StripeServiceProvider::class,
],
'aliases' => [
'Stripe' => app\Services\Stripe\StripeFacade::class,
]
In my controller, I'd call the Stripe service as
use Stripe;
...
public function example(){
$auth = Stripe::auth();
}
Then I'd get this error in the Config/app.php file
Class "app\Services\Stripe\StripeServiceProvider" not found
I tried adding the Services directory to my psr-4 and didn't seem to get any luck, even after dumping configs and autoload.
"autoload": {
"psr-4": {
"App\\": "app/",
"Services\\": "app/Services",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
},
any help? :)
In your comment, you posted an error:
Class App\Services\Stripe\StripeServiceProvider located in ./app/Services /Stripe/StripeServiceProvider.php does not comply with psr-4 autoloading standard. Skipping.
I noticed an extra space in ./app/Services /Stripe.
Perhaps you have created the Services / directory with a space at the end.
Some improvements are to rename app\ to App\ and remove the "Services\\": line from your composer.json. Run composer dump-autoload after these changes.
Use the below code
namespace App\Services\Stripe;
use App\Services\Stripe\StripeServiceProvider::class
I am using PhpStorm v2021.2, have Laravel plugin (by Daniel Espendiller v0.15.4) installed and enabled, Laravel Query (by Ernestas Kvedaras v2.0.6) and I am also using barryvdh/laravel-ide-helper v2.10.0. I updated composer.json with this bit of code:
"scripts": {
"post-update-cmd": [
"Illuminate\\Foundation\\ComposerScripts::postUpdate",
"#php artisan ide-helper:generate",
"#php artisan ide-helper:meta"
],
"post-autoload-dump": [
"Illuminate\\Foundation\\ComposerScripts::postAutoloadDump",
"#php artisan ide-helper:generate",
"#php artisan ide-helper:meta",
"#php artisan package:discover --ansi"
],
so it regenerates all meta and helpers and it successfully creates files .phpstorm.meta.php and _ide_helper.php.
All my models do extend Illuminate\Database\Eloquent\Model. Not directly, I also wrote a BaseModel with some of default properties, so it looks like this:
BaseModel.php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class BaseModel extends Model
{
//
}
Client.php
namespace App\Modules\Clients\Entities;
use App\Models\BaseModel;
...
class Client extends BaseModel
{
//
}
But I am still seeing Method 'findOrFail' not found in \App\Modules\Clients\Entities\Client. What else can I do to make this notice go away?
In installation no describe process publishing this package.
But I would like to setup it.
Laravel 5.6
composer require mervick/emojionearea ^3.0.0
and I need to copy from folder /vendor to /public/vendor using
php artisan vendor:publish
I created file /vendor/mervick/emojioneareaServiceProvider.php
and added lines:
public function boot()
{
$this->publishes(
[
__DIR__ . '/dist' =>
public_path('vendor/mervick/emojionearea/dist'),
],
'emojionearea'
);
}
also, I added lines to /config/app.php
//ServiceProviders
Mervick\EmojioneArea\EmojioneAreaServiceProvider::class,
//Aliases
'EmojioneArea'=> Mervick\EmojioneArea\EmojioneAreaServiceProvider::class,
and run command :
php artisan vendor:publish
also, I used the command:
php artisan vendor:publish --provider="Mervick\EmojioneArea\EmojioneAreaServiceProvider"
Any help.Thanks.
Please follow below steps i have tried moved files to public/vendor folder by updating below steps. Its works fine.
Service provider file.
<?php
namespace mervick\emojionearea;
use Illuminate\Support\ServiceProvider;
class EmojioneAreaServiceProvider extends ServiceProvider
{
/**
* Bootstrap services.
*
* #return void
*/
public function boot()
{
$this->publishes([
__DIR__.'/../dist' => base_path('public/vendor/dist'),
]);
}
}
In your root composer.json file add your vendor for identify the service provider.
"autoload-dev": {
"psr-4": {
"Tests\\": "tests/",
"Mervick\\EmojioneArea\\": "vendor/mervick/emojionearea/src"
}
}
Like you said don't forgot to add the service provider in config/app.php
Mervick\EmojioneArea\EmojioneAreaServiceProvider::class,
If everything works fine for you. Please make it as correct answer.:-)
I moved my User Model from App\User to App\Models\Users, I followed the proper instruction, the same thing working properly on Windows OS, while facing error on Ubuntu 14.04
Whenever I try to Login(When submit information) it gives me error
FatalErrorException in
/var/www/html/sms/vendor/laravel/framework/src/Illuminate/Auth/EloquentUserProvider.php
line 126: Class '\App\User' not found
I also run composer dump-autoload command, but no luck.
Also tried this
https://stackoverflow.com/a/28516582/1216451
Here is my settings for Models directory
composer.json
"autoload": {
"classmap": [
"database",
"app/Models"
],
"psr-4": {
"App\\": "app/"
}
},
Model Directory Structure
App/Models/
Model User.php
namespace App\Models;
Auth.php tried both lines, given below.
'model' => App\Models\User::class,
'model' => App\Models\User,
AuthController.php
use App\Models\User;
EloquentUserProvider.php path is sms/vendor/laravel/framework/src/Illuminate/Auth/EloquentUserProvider.php line 126
public function createModel()
{
$class = '\\'.ltrim($this->model, '\\');
return new $class; //line# 126
}
Your configurations seems accurate, just reset them by using php artisan config:clear
Please check also all those files including relationship
the perfect way find out all, is to search folder excluding vendor.
config/services.php
config/auth.php
database\factories\Userfactory.php
public function user()
{
return $this->belongsTo(User::class);
}
Make sure that you have specified the correct namespace.
Like
App\Models\User
but this depend on youe file construction some time users but the Model User inside folder that named Models in older versions of laravel cus it's not there by default
Following this topic Use a custom function everywhere in the website I need a bit of help to finish what has been started.
So I created a folder in the app folder: Customs
Then I created a helpers.php file that has the following code:
<?php
use Illuminate\Support\Str;
if (! function_exists('str_slug')) {
/**
* Generate a URL friendly "slug" from a given string.
*
* #param string $title
* #param string $separator
* #return string
*/
function my_slug($title, $separator = '-')
{
$title = str_replace('\'','_',$title);
return Str::slug($title, $separator);
}
}
I read that I now have to update my composer.json, and especially the autoload section which is basically:
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/"
}
},
I don't understand what I should do now... psr-4 already says that the whole app folder is autoloaded, no?
I also tried to put the full path to the helpers.php but it did not work either.
What am I doing wrong?
Your autoload should have something like that:
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/"
},
"files": [
"app/helpers.php"
]
},
where files are your custom files. Also as is mentioned in Use a custom function everywhere in the website question I advice you to use traits for e.g. trait StringSluggify. It keeps OOP way.
Create a folder inside of app/ called Helpers.
Inside of app/Helpers create your custom class
namespace App\Helpers;
class FooHelper{
public static function bar(){
return 'bar';
}
}
Run composer dump-autoload to update autoload.
Here you are now able to use your helper functions like:
$bar = \App\Helper\FooHelper::bar();
If your plan is attach a facade, then edit facades array in config/app.php like so:
'Foo' => \App\Helpers\FooHelper::class
Now you can call your functions like:
public function controllerFunction(){
$bar = \Foo::bar();
}
use it in your view {{my_slug($collection->value)}} or in your controllers with the namespacing App\customs\my_slug($value) or by adding use \App\customs to the top of your controller and then my_slug($value)