Laravel 5.3, Eloqent models and Namespace Issues - php

I am confused. I am following the laravel document to the T and something isn't being configured properly maybe?
The Short: I can't use my Eloquent models like the documentation shows.
The Long:
I followed these steps from the Laravel docs.
laravel new blog
added database details to .env
created a model: php artisan make:model SavedService
namespace App;
use Illuminate\Database\Eloquent\Model;
/**
* #property integer $service_id
* #property string $title
* #property string $price
* #property string $short_description
* #property string $long_description
* #property integer $display
*/
class SavedService extends Model
{
protected $table = 'saved_services';
public $timestamps = false;
/**
* #var array
*/
protected $fillable = ['title', 'price', 'short_description', 'long_description', 'display'];
}
created a controller: php artisan make:controller datatest
added index method to controller:
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Requests;
use App\SavedService;
class datatest extends Controller
{
public function index() {
$flights = App\SavedService::all();
foreach ($flights as $flight) {
echo $flight->name;
}
}
}
Now, use App\SavedService; is highlighted in PHPStorm: "SavedServices is never used."
Also, for $flights = App\SavedService::all();, App is highlighted in red: "Undefined namespace App." SavedService is highlighted and PHPStorm tells me "Undefined class SavedService."
If I let PHPStorm create the SavedService class, its namespace is App/Http/Controllers/App
??
Project structure is
app
-composer.json
-Http\
-SavedService.php
--Controllers\
---dataTest.php
My composer.json autoload:
"autoload": {
"classmap": [
"database"
],
"psr-4": {
"App\\": "app/"
}
},
EDIT:
Sorry, had to rush, train got into the station! I wanted to add to this a few things. First, I am using a vagrant machine to host the projects, not sure if that is important to know? Second, I wanted to use Propel-orm. I find eloquent not very eloquent at all. I couldn't get propel to work, something to do with namespaces. The propel generated models would be in app/Http/Models/Http/Models/ModelName. I am beginning to think this is all one problem.
I am not doing anything extra ordinary to the process. Just following the steps in the documentation.
Additionally, Eloquent doesn't seem to work the way the eloquent documentation hosted on the Laravel docs page. For example "get()" eloquentModel::get(). The laravel docs shows it as that, get(), and phpstorm throws a fit saying $key is expected. The eloquent documentation confirms, get($key). What am I missing there? Why the difference, and why isn't it mentioned in the documentation. Maybe this has something to do with my current issue? Maybe the answer the this will solve why I can't use propel?
END EDIT.
What am I missing? I'm so confused, why isn't this just working? Help please!!! Thanks

change
$flights = App\SavedService::all();
to
$flights = SavedService::all();

Related

Laravel / Mongdb - DB::collection() is not working

I am following this Laravel/Mongodb package: https://github.com/jenssegers/. Here if you go to this section https://github.com/jenssegers/laravel-mongodb#basic-usage-2 you can see that they are using DB::collection() method and passed the collection name to that.
Now, in my controller, I am trying to do this:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\DB;
use App\Models\Import;
use App\Models\Projects;
use Jenssegers\Mongodb\Collection;
use Jenssegers\Mongodb\Query\Builder;
class ImportController extends Controller
{
public function get_all_products() {
// Predefined key
$predefined_keys = [ 'image_link', 'title', 'price', 'brand', 'link' ];
// Get all the products
//$get_products = Import::paginate(10);
$get_products = DB::collection('products_1')->get();
return response()->json($get_products, 200);
}
}
but I don't get any result. Can you tell me what I am missing here?
My goal is to set the collectioin name directly in this controller not in Model.
Update:.
Here is my Import Mode:
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Jenssegers\Mongodb\Eloquent\Model;
class Import extends Model
{
protected $connection = 'mongodb';
protected $collection = 'products_46';
// protected $table = 'projects';
}
Something is wrong with how you have configured this project.
From the documentation that you linked:
When using MongoDB connections, Laravel will automatically provide you with the corresponding MongoDB objects.
Yet in the comments you report that DB::collection('products_1')->get(); results in:
message": "Method Illuminate\\Database\\MySqlConnection::collection does not exist."
This error message is referencing MySQL rather than MongoDB. It seems you are using MySQL for other portions of your application per this question.
In any case, I think the answer is to be sure to load the packages appropriately (and perhaps also to disambiguate between namespaces if DB is separately defined in Illuminate\Support\Facades and is in scope for this portion of the code).

Laravel 8, Model factory class not found

so when using the new model factories class introduced in laravel 8.x, ive this weird issue saying that laravel cannot find the factory that corresponds to the model. i get this error
PHP Error: Class 'Database/Factories/BusinessUserFactory' not found in .....
tho ive followed the laravel docs, ive no idea whats going on
Here is the BusinessUser class
<?php
namespace App;
use Database\Factories\BusinessUserFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class BusinessUser extends Model
{
use HasFactory;
}
and the factory
<?php
namespace Database\Factories;
use App\BusinessUser;
use Illuminate\Database\Eloquent\Factories\Factory;
use Illuminate\Support\Str;
class BusinessUserFactory extends Factory
{
/**
* The name of the factory's corresponding model.
*
* #var string
*/
protected $model = BusinessUser::class;
/**
* Define the model's default state.
*
* #return array
*/
public function definition()
{
return [
'name' => "dsfsf"
];
}
}
any ideas or leads is greatly appreciated.
If you upgraded to 8 from a previous version you are probably missing the autoload directive for the Database\Factories namespace in composer.json:
"autoload": {
"psr-4": {
"App\\": "app/",
"Database\\Factories\\": "database/factories/",
"Database\\Seeders\\": "database/seeders/"
}
},
You can also remove the classmap part, since it is no longer needed.
Run composer dump after making these changes.
Laravel 8.x Docs - Upgrade Guide - Database - Seeder and Factory Namespace
Apparently you have to respect the folder structure as well. For example, if you have the User Model in the following path: app\Models\Users\User, then the respective factory should be located in database\factories\Users\UserFactory.
I'm in the process of migrating from laravel 7 to 8.
After banging my head against the wall for a while and looking at the source code, I saw that you can optionally override what factory class gets called for a model using the newFactory method on the model.
I also then noticed that it IS in the documentation (https://laravel.com/docs/8.x/database-testing#creating-models) - I just didn't understand what it meant the first time I read it. Now I do.
I solved this by the following:
<?php
namespace My\Fancy\Models;
use Database\Factories\SomeFancyFactory;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
class SomeClass extends Model
{
use HasFactory;
/** #return SomeFancyFactory */
protected static function newFactory()
{
return SomeFancyFactory::new();
}
}
After this change, my tests passed as expected.
You need to ensure that the namespace is the same: as shown below: otherwise this will screw you up big time. The name of the factory is the name of the model + Factory
e.g. app\models\User- will match to database/factories/UserFactory
finally ensure you run: composer dumpautoload
In my own case, it happened in a Laravel 8 project ie it wasn't a project I upgraded from Laravel 7. And I noticed this after doing composer update recently.
1: When creating the model, create the factory alongside
php artisan make:model BusinessUser -f // -f creates the factory
2: For your older models comment out use HasFactory; or just create the factory
php artisan make:factory BusinessUserFactory -m
Let's say your model Example is under the App\Example\Models namespace. If you want ALL of your factories under database\factories, then you could define the namespace for your all of factories in your AppServiceProvider:
// ...
use Illuminate\Database\Eloquent\Factories\Factory;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* #return void
*/
public function boot()
{
Factory::guessFactoryNamesUsing(function (string $modelName) {
return 'Database\\Factories\\'.class_basename($modelName).'Factory';
});
}
}
And then in your factory, located in database/factories/ExampleFactory.php:
namespace Database\Factories;
use Illuminate\Database\Eloquent\Factories\Factory;
class ExampleFactory extends Factory
{
// ...
}
...as per this twitter comment (I can't take credit for this solution but sharing the fix!):
https://twitter.com/ejunker/status/1306007589940068352/photo/1
I was having this same issue, but for a different reason. If you're using factories in the setUp function of a test, make sure:
You're extending Tests\TestCase (instead of PHPUnit\Framework\TestCase)
The first line of your setUp function should be parent::setUp(); (I was missing this)
Add this to AppServiceProvider::boot() to prevent namespace of model guessing.
Factory::guessFactoryNamesUsing(function (string $modelName) {
return 'Database\\Factories\\' . Arr::last(explode('\\', $modelName)) . 'Factory';
});
It seems like a laravel core issue ! it was caused by the modelName() method located in Illuminate\Database\Eloquent\Factories\Factory.php
Issue was fixed 10 days ago by laravel maintainers in this commit
Fix commit and this release 8.82.0
You can fix the issue by upgrading your laravel version to 8.82.0
Hope this saves you some time. cheers !
May be everything is perfect just run composer dump-autoload. It happened to me.
my problem was related with composer.lock file that was installing laravel v7, solved it with this command
composer update
Use this package if you are upgrading from laravel 7 to 8
composer require laravel/legacy-factories
Today I have got below issue after upgrading my project from Laravel 7 to Laravel 8 and updating it online on server.
Trait 'Illuminate\Database\Eloquent\Factories\HasFactory' not found
Even I have updated composer.json with autoload directive given in answer by #lagbox but it did not resolved the issue for me.
Finally I have updated complete vendors folder online that have resolved my issue.

Laravel webwizo shortcodes package Shortcodes class not found

I recently started using laravel so i'm a beginner, and right now i'm working on a small project which requires me use shortcodes(like the ones in wordpress).
So i searched for a little bit and found this package:
https://packagist.org/packages/webwizo/laravel-shortcodes
I ran the installation and usage the way it's written but i get the error : Class 'App\Providers\Shortcode' not found in the provider I have to make using the laravel make:provider command as specified in the package instructions, below is my exact usage and install code.
added this to the providers array :
/*
* shortcodes providers
*/
Webwizo\Shortcodes\ShortcodesServiceProvider::class,
App\Providers\ShortcodesServiceProvider::class,
Added this to aliases:
'Shortcode' => Webwizo\Shortcodes\Facades\Shortcode::class,
this is the content of my ShortcodesServiceProvider in app/providers:
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Shortcodes\JobsForm;
class ShortcodesServiceProvider extends ServiceProvider
{
/**
Bootstrap the application services.
*
#return void
*/
public function boot()
{
//
}
/**
Register the application services.
*
#return void
*/
public function register()
{
Shortcode::register('jobs', JobsForm::class);
}
}
I use laravel 5.4 so that might be an issue.
The thing is the class obviously exists, it gives the Shortcodes class not found error because I think it searches for it in the app/providers/ShortcodesServiceProvider file, and obviously it's not there it's in the vendor file.
Is there something I'm missing i've checked and double checked, I can't seem to get this thing to work.
It shoould work considering it has an alias defined right ?
I used it in the view like this:
return view('quarx-frontend::pages.' . $page->template)->with('page', $page)->withShortcodes();
Thanks for taking the time to read this any help would be much appreciated.
If you need any more info I'll be glad to supply it.
p.s. sorry for bad english ,not a native speaker :P
It searches for Shortcode in the App\Providers; namespace and not in the root namespace where the Facade is defined.
You can fix this in App\Providers\ShortcodesServiceProvider.php by either doing:
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use App\Shortcodes\JobsForm;
use Shortcode;
class ShortcodesServiceProvider extends ServiceProvider
{
Or use \Shortcode
/**
* Register the application services.
*
* #return void
*/
public function register()
{
\Shortcode::register('jobs', JobsForm::class);
}
I would recommend the first option.

Troubleshooting referencing a model in a laravel controller

I've been trying unsuccessfully to resolve an error in a laravel 5.2 app (carfreak).
FatalErrorException in PropertyController.php line 85:
Class 'App\Models\CarModel' not found
I have moved the default user model to a folder app/models and made the necessary changes so that it's all working fine.
Now I have a new controller CarController, and a new model, CarModel that are just not working. It seems to be such a simple problem with namespaces, but I am unable to resolve it.
is the model in the models folder? Yes. carfreak\app\Models\CarModel.php
is the controller namespace correct? Yes... namespace carfreak\Http\Controllers;
does the controller reference the model? Yes...use App\Models\CarModel;
is the model namespace correct? Yes... namespace carfreak\Models;
I am able to create different versions of the error by playing with the CarController but no permutation I can think of has worked.
EDIT: Controller and Model added...
EDIT: More details added:
The irony of this is that I can php artisan make:model sanityCheck and it will create a model in the \app root (i.e. not in app\models)... and that model can be called just fine. If I put my CarController back in the root, and change it's namespace appropriately, it still doesn't work. It's almost like I have some stupid spelling error in the class name or something, but I've copied and pasted class names into my filename, class declaration, "use" declarations, etc. and it. still. doesnt. work. Aargh!
//this is carModel
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class CarModel extends Model
{
//
/**
* The attributes that are mass assignable.
* #var array
*/
protected $fillable = [
'colourOfCar',
];
}
//this is carController
<?php
namespace carfreak\Http\Controllers;
use Illuminate\Http\Request;
//use \carfreak\app\Models\CarModel;
use App\Models\CarModel;
class CarController extends Controller
{
/**
* Display a listing of the resource.
*
* #return \Illuminate\Http\Response
*/
public function __construct()
{
$this->middleware('auth');
}
public function store(Request $request)
{
// validate the data
$this->validate($request, array(
'CarColour' => 'required|max:50'
));
// store in the database
$newCar = new CarModel;
dd($request);
}
}
This looks wrong use \carfreak\app\Models\CarModel; should be use App\Models\CarModel in this is carController
Casing is important on linux. The namespace generally is used in a PSR Aloader to find the file. And Linux filesystem is case sensitive. So the CareModel.php file should be located in App/Models/CarModel.php
But I never used Laravel...
Well, here it is. I solved it by asking myself this question: If I'm having so much trouble namespacing, referencing and organising my models, then maybe I can get artisan to do it for me.
The post that got me thinking differently was Mansoor Akhtar's advice here: How do I instruct artisan to save model to specific directory?
Get artisan to make the model in the right place first time.
php artisan make:model Models/CarModel
In the Controller, reference the model correctly
use name-of-app\Models\CarModel;
There may or may not be cache flushing involved in my problem. I was eventially restarting my XAMPP after every change to ensure no caching was involved. I also tried
php artisan cache:clear

Eloquent ORM Code Hinting in PhpStorm

So I'm just starting off with Laravel (using v5) and Eloquent. I'm working on getting some basic APIs up and running and noticing that a lot of working methods don't show up in PhpStorm's code hinting
So I have this model:
namespace Project\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable as AuthenticatableContract;
use Illuminate\Contracts\Auth\CanResetPassword as CanResetPasswordContract;
class User extends Model
implements AuthenticatableContract, CanResetPasswordContract {
}
And in one of my controllers I try to do
User::query()->orderBy('id', 'desc');
User::query() creates a Eloquent Builder object and orderBy() behave properly and without error. However, PhpStorm does not show orderBy() (or take(), skip(), and I'm sure others) when I type User::query()-> and gives warnings when I actually do use it.
I am using Laravel IDE Helper which has helped immensely with bringing code hints to the Facades, but not to the models/builders it would seem.
Does anyone have a solution to this?
For future Googlers, and perhaps OP as well if you are still sticking to Laravel.
The laravel-ide-helper package solves this issue for you quite elegantly, with what I believe is a relatively new feature; generated model PHPDocs.
You can generate a separate file for all PHPDocs with this command:
php artisan ide-helper:models
The generated metadata will look something like this for each class:
namespace App {
/**
* App\Post
*
* #property integer $id
* #property integer $author_id
* #property string $title
* #property string $text
* #property \Carbon\Carbon $created_at
* #property \Carbon\Carbon $updated_at
* #property-read \User $author
* #property-read \Illuminate\Database\Eloquent\Collection|\Comment[] $comments
*/
class Post {}
}
This caused issues for me in PHPStorm however, where the software was complaining about multiple class definitions. Luckily an option is readily available for writing directly to the model files:
php artisan ide-helper:models -W
There are a few more options and settings available if you need to tweak the behavior, but this is the gist of it.
Add in model PHPDoc#mixin
/**
* Class News
* #property int $id
* #property string $created_at
* #property string $updated_at
* #mixin \Eloquent
* #package App
*/
class News extends Model
{
}
In PHPStorm works
You can try Laravel plug-in for PhpStorm and you need to specifically activate it in your project settings.
If you're using BarryVHD's Laravel IDE Helper package, run:
php artisan ide-helper:eloquent
This will write /** #mixin \Eloquent */ into the vendor\laravel\framework\src\Illuminate\Database\Eloquent\Model.php file.
A little late but I recently had the same problem so I thought I would put a note down:
This is because Database\Eloquent\Model.php has a query() function which returns \Illuminate\Database\Eloquent\Builder and the Eloquent\Builder has a line:
use Illuminate\Database\Query\Builder as QueryBuilder;
Then it uses 'magic' __call methods to call to functions in Query\Builder. (look for __call method in Eloquent\Builder)
See:
http://php.net/manual/en/language.oop5.overloading.php#object.call
__call() is triggered when invoking inaccessible methods in an object context.
So, indeed the method you are calling is inaccessible :) There is not much that the IDE can do.
There are workarounds like using #method tags but it is unmaintainable. An alternative is to use #mixin (but this is not standards based).
See: https://github.com/laravel/framework/issues/7558
I think this all be resolved when they get rid of all the magic calls in the Laravel code and use PHP 'traits' instead. See last message here. :)
Just import Eloquent Builder in your Model class and add mixin:
use Illuminate\Database\Eloquent\Builder;
/** #mixin Builder */
To cover all the models at once — add the mixin to the src/Illuminate/Database/Eloquent/Model.php)
I wanted to have some kind of explicit "casting" when interacting with the query builder. Example...
$user = User::query()->findOrFail($id);
$user->myUserSpecialMethod(); // <-- IDE syntax error
Since all my models are extending my custom base Model which in turn extends Eloquent, I've ended up creating this method in my custom base model:
/**
* Explicit type-hinting
*
* #return static
*/
static public function hint(BaseModel $model)
{
return $model;
}
This way, it solves the IDE invalid error and helps me:
$user = User::hint(User::query()->findOrFail($id));
$user->myUserSpecialMethod(); // <-- all OK !
Please note that this is not OOP type casting. It is only a hint to help the IDE. In my example, the returned Model was already a User. If I woud use this method on a derived class like SuperUser, only the IDE will be fooled...
An nice alternative also is to put meta information directly over the assignment statement:
/** #var User $user */
$user = User::query()->findOrFail($id);
$user->myUserSpecialMethod(); // <-- all OK !
Or next to it...
$user = User::query()->findOrFail($id); /** #var User $user */
$user->myUserSpecialMethod(); // <-- all OK !
Verified on Laravel 8, just added #mixin Builder to Illuminate\Database\Eloquent\Model.php annotation solved it.
// Illuminate\Database\Eloquent\Model.php
/**
* #mixin Builder
*/
abstract class Model

Categories