Laravel Confide not triggering eloquent.saving - php

I'm using zizaco/confide in combination with cviebrock/eloquent-sluggable.
eloquent-sluggable uses Events::listen('eloquent.saving*') for generating the slug while/before saving.
// Cviebrock\EloquentSluggable\SluggableServiceProvider:55
public function registerEvents()
{
$app = $this->app;
$app['events']->listen('eloquent.saving*', function($model) use ($app)
{
$app['sluggable']->make($model);
});
}
Since I switched to Confide for authentication the slugs are not getting generated.
My user model is simply class User extends ConfideUser. Switching to class User extends Ardent or User extends Eloquent the event eloquent.saving is getting triggered fine.
I'm not shure if this is a bug or I'm missing something.
My Model:
<?php
use Illuminate\Database\Eloquent\Model;
use Zizaco\Confide\ConfideUser;
class User extends ConfideUser
{
public $autoPurgeRedundantAttributes = true;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* Soft delete
*
* #var boolean
*/
protected $softDelete = true;
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password');
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = array(
'nickname',
'password',
'email',
'deleted_at',
'disabled',
'firstname',
'lastname',
'birthday',
// needed by ardent
'email_confirmation',
'password_confirmation'
);
public static $rules = array(
'firstname' => 'required',
'email' => 'required|email|confirmed|unique:users',
'email_confirmation' => 'required',
'nickname' => 'required|min:2|unique:users',
'birthday' => 'date:d.m.Y|before:now',
'password' => 'required|min:5|confirmed',
'password_confirmation' => 'required'
);
public $imageSizes = array(
array(64, 64),
array(250, 250)
);
public static $sluggable = array(
'build_from' => 'nickname',
'save_to' => 'slug',
);
/**
* Roles
*
* #return object
*/
public function roles()
{
return $this->belongsToMany(
'Role',
'role_user'
)
->withTimestamps();;
}
}

Seems to me like this one is a bug: https://github.com/Zizaco/confide/issues/179
As a temporary workaround you can wrap the beforeSave() method in your Model without returning anything (!):
public function beforeSave($forced = false)
{
parent::beforeSave($forced);
}

Related

My storage fake doesn't store the image inside the test directory

I'm writing a test for my Item model, it has images to be uploaded and I expect it should be stored inside the testing directory to be cleared each time I ran the test. But it wasn't. Instead, it creates a new directory named item-images in both storage and testing/disks but it uses the actual storage/item-images directory instead of storage/disks/item-images.
Storage::fake('item-images') is already defined on top of the test case, I'm a bit confused by this, please help.
tests/Feature/ItemTest.php
public function test_user_can_store_new_item()
{
Storage::fake('item-images');
Sanctum::actingAs(User::factory()->create());
$images = [
UploadedFile::fake()->image('image1.png'),
UploadedFile::fake()->image('image2.png'),
UploadedFile::fake()->image('image3.png'),
];
$item = Item::factory()->make(['images' => $images]);
$this->postJson(route('items.store'), $item->toArray())
->dump()
->assertCreated()
->assertJsonFragment($item->toArray());
foreach ($images as $image) {
Storage::disk('item-images')->assertExists($image->hashName());
Storage::disk('item-images')->assertMissing('missing.png');
}
}
app/Models/Item.php
<?php
namespace App\Models;
use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\BelongsTo;
class Item extends Model
{
use HasFactory;
/**
* The attributes that are mass assignable.
*
* #var string[]
*/
protected $fillable = [
'category_id',
'name',
'description',
'history',
];
protected $with = ['category'];
/**
* Get the category that owns the Item
*
* #return \Illuminate\Database\Eloquent\Relations\BelongsTo
*/
public function category(): BelongsTo
{
return $this->belongsTo(Category::class);
}
}
app/Http/Controllers/ItemController.php
/**
* Store a newly created resource in storage.
*
* #param \App\Http\Requests\RequestItem $request
* #return \Illuminate\Http\Response
*/
public function store(RequestItem $request)
{
$data = $request->validated();
$item = Item::create(Arr::except($data, 'images'));
if ($request->has('images')) {
foreach ($request->file('images') as $image) {
$path = $image->store('item-images');
Image::create(['item_id' => $item->id, 'url' => $path]);
}
}
return response()->json($item, 201);
}
app/Http/Requests/RequestItem.php
<?php
namespace App\Http\Requests;
use Illuminate\Foundation\Http\FormRequest;
use Illuminate\Validation\Rule;
class RequestItem extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'category_id' => [
'required',
'integer',
],
'name' => [
'required',
'string',
'max:255',
Rule::unique('items', 'name'),
],
'description' => [
'required',
'string',
'max:255',
],
'history' => [
'string',
'max:2500',
],
'images' => [
'required',
'array',
'min:1',
'max:10',
],
];
}
}
I believe the confusing is you are creating a fake file, but actually properly saving it. $image->store('item-images'); doesn't specify the store you are saving it in, but the 'item-images' is the path and it will save it to the default storage. So either Storage::fake() the default storage option.
// assuming default storage is local
Storage::fake('local');
Or change your logic to specify the correct faked storage disk.
Storage::disk('item-images')->putFile('path/yourfile', $image);

Method store & posts not found [LARAVEL]

I've been stuck for a little while on a backend issue. PHPStorm tells me that the posts and store method doesn't exist, and I don't know which way to go to solve this problem...
File PostController.php:
public function store(){
$data = request()->validate([
'caption' => ['required', 'string'],
'image' => ['required', 'image']
]);
$imagePath = request('image')->store('uploads','public');
auth()->user()->posts()->create([
'caption' => $data['caption'],
'image' => $imagePath
]);
return redirect()->route('profiles.show', ['user' => auth()->user()]);
}
File User.php:
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'username', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function getRouteKeyName()
{
return 'username';
}
public function profile(){
return $this->hasOne('App\Profile');
}
}
Error encountered:
I hadn't created a relationship posts in my User.php.
So I added the relationship this way:
public function posts(){
return $this->hasMany('App\Post');
}
try this :
Post::create([
'caption' => $data['caption'],
'image' => $imagePath
]);

Can't assign Default User role to a new user

Error Message:
Call to undefined method App\User::roles()
I'm Tring to assign default role to new user But I failed to assigned it. All user information stored in database but Role can't stored in table. Where i mistaked in this code. Help me.My English not good, Sorry for miss-communication.
This is My Code of User.php, Role.php, RegisterController.php and HomeController.php Files. See and tell me "where i doing wrong?"
This is User.php File
namespace App;
use App\Role;
use Illuminate\Notifications\Notifiable;
use Illuminate\Contracts\Auth\MustVerifyEmail;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* #param string|array $roles
*/
public function authorizeRoles($roles)
{
if (is_array($roles)) {
return $this->hasAnyRole($roles) ||
abort(401, 'This action is unauthorized.');
}
return $this->hasRole($roles) ||
abort(401, 'This action is unauthorized.');
}
/**
* Check multiple roles
* #param array $roles
*/
public function hasAnyRole($roles)
{
return null !== $this->roles()->whereIn('name', $roles)->first();
}
/**
* Check one role
* #param string $role
*/
public function hasRole($role)
{
return null !== $this->roles()->where('name', $role)->first();
}
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
}
This is Role.php File
<?php
namespace App;
use App\User;
use Illuminate\Database\Eloquent\Model;
class Role extends Model
{
public function users()
{
return $this->belongsToMany(User::class);
}
}
This RegisterController.php File.
<?php
namespace App\Http\Controllers\Auth;
use App\Role;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Hash;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => ['required', 'string', 'max:255'],
'email' => ['required', 'string', 'email', 'max:255', 'unique:users'],
'password' => ['required', 'string', 'min:8', 'confirmed'],
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \App\User
*/
protected function create(array $data)
{
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
$user
->roles()
->attach(Role::where('name', 'student')->first());
return $user;
}
This is my role_user database Table
User Database Table
Role Database Table
Refactor your create method in RegisterController.php file like this:
protected function create(array $data)
{
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
$user
->roles()
->attach(Role::where('name', 'student')->first());
return $user;
}
your rest of the code will not run after return.
and add roles relation to User model like this:
public function roles()
{
return $this->belongsToMany(User::class);
}
You can update your create function with this
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
$role = new App\Role(['role' => 'student']);
$user->roles()->save($role);
return $user;
}
Source: https://laracasts.com/discuss/channels/laravel/attach-role-to-a-user-upon-registration?page=1
You don't currently have a roles() relation in your user model. Add the following
public function roles()
{
return $this->hasMany('App\Role');
}

Getting User::create() not found in Laravel 5.5

When I try to register a user, I am getting an error:
Call to undefined method App\Models\User::create()
here is my User model:
<?php
namespace App\Models;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'first_name', 'last_name', 'email', 'password',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
protected $table = 'users';
}
I have used the User model that is shipped with Laravel 5.5, but just moved it to the Models folder. I updated the config/auth file to point to App\Models\User. I have ran php artisan optimize and composer dump-autoload several times, to no avail.
Here is my Register Controller:
<?php
namespace App\Http\Controllers\Auth;
use App\Models\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
class RegisterController extends Controller {
public $titles = [];
public $title = 'Registration';
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
$this->middleware('guest');
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'first_name' => 'required|string|max:255',
'last_name' => 'required|string|max:255',
'email' => 'required|string|email|max:255|unique:users',
'password' => 'required|string|min:6|confirmed',
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return \App\User
*/
protected function create(array $data)
{
return User::create([
'first_name' => $data['first_name'],
'last_name' => $data['last_name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
}
public function showRegistrationForm() {
return view('auth.register')
->with('env', $this->env)
->with('titles', $this->titles)
->with('title', $this->title);
}
}
When extending Laravel User model from the Auth package, you should extend the User class from that package. The abstract class from package extends the Model and then you will have access to all model methods.
From Illuminate\Foundation\Auth\User:
class User extends Model implements
AuthenticatableContract,
AuthorizableContract,
CanResetPasswordContract
{
use Authenticatable, Authorizable, CanResetPassword;
}

Laravel registration: Insert two rows into separated tables

I have a problem with inserting rows in Laravel.
Theory: I use simple Laravel authentication and have two tables.
users: id, name, password.
user_details: id, userID, email
After the registration it would be useful to insert rows into both tables, and the userID = id (in users table).
RegisterController.php
<?php
namespace App\Http\Controllers\Auth;
use App\User;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Validator;
use Illuminate\Foundation\Auth\RegistersUsers;
class RegisterController extends Controller
{
/*
|--------------------------------------------------------------------------
| Register Controller
|--------------------------------------------------------------------------
|
| This controller handles the registration of new users as well as their
| validation and creation. By default this controller uses a trait to
| provide this functionality without requiring any additional code.
|
*/
use RegistersUsers;
/**
* Where to redirect users after registration.
*
* #var string
*/
protected $redirectTo = '/home';
/**
* Create a new controller instance.
*
* #return void
*/
public function __construct()
{
//$this->middleware('guest');
}
/**
* Get a validator for an incoming registration request.
*
* #param array $data
* #return \Illuminate\Contracts\Validation\Validator
*/
protected function validator(array $data)
{
return Validator::make($data, [
'name' => 'required|max:255',
'email' => 'required|email|max:255|unique:users',
'password' => 'required|min:6|confirmed',
]);
}
/**
* Create a new user instance after a valid registration.
*
* #param array $data
* #return User
*/
protected function create(array $data)
{
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
'e_r' => $data['e_r'],
]);
$details = UserDetails::create([
'firstname' => 'joco',
'lastname' => 'nagy',
'email' =>$data['email'],
'position' => 'cleaner',
'salary' => '250000',
'amount_holiday' => '40'
]);
return $user;
}
}
(I have just tried to insert fake datas. There are default values in migration files.)
Models:
User.php
<?php
namespace App;
use Illuminate\Notifications\Notifiable;
use Illuminate\Foundation\Auth\User as Authenticatable;
class User extends Authenticatable
{
use Notifiable;
/**
* The attributes that are mass assignable.
*
* #var array
*/
protected $fillable = [
'name', 'email', 'password', 'e_r',
];
/**
* The attributes that should be hidden for arrays.
*
* #var array
*/
protected $hidden = [
'password', 'remember_token',
];
public function user_detail(){
return $this->hasOne("App\UserDetails");
}
}
Error:
FatalThrowableError in RegisterController.php line 74: Class
'App\Http\Controllers\Auth\UserDetails' not found
I do not understand why should be my model in Auth directory.
Have you include your model UserDetails?
Include it on top:
use App\User;
use App\UserDetails;
or
Change UserDetails to App\UserDetails.
$details = App\UserDetails::create([
'firstname' => 'joco',
'lastname' => 'nagy',
'email' =>$data['email'],
'position' => 'cleaner',
'salary' => '250000',
'amount_holiday' => '40'
]);
You should use use statement eg. use Your\Name\Space\UserDetails;
Without this declaration PHP is looking for UserDetails class in your current namespace, in your case App\Http\Controllers\Auth. That's why you get
'App\Http\Controllers\Auth\UserDetails' not found

Categories