Laravel aimeos how to add user to group? - php

Laravel 5.8
"aimeos/aimeos-laravel": "^2019.04"
I create new user by code:
$user = new User([
'id_customer' => $id_customer,
'id_customer_ref' => $id_customer_ref,
'firstname' => $firstname,
'lastname' => $lastname,
'email' => $email
]);
and save it:
$user->save()
This I do in a class extended from Illuminate\Console\Command.
How can I add this user to some group like editor ?

I would tag this as more of a database question, but basically you'd set up a relationship between the users. The most common method of grouping is simply adding an integer or string to the user table. So create a migration:
php artisan make:migration add_types_on_users
Then in the Blueprint callback do something like:
$table->string('type')->default('regular');
// or if you want an integer
$table->integer('type')->default(0);
Don't forget to add the reverse function logic:
$table->dropColumn('type');
Then run the migration:
php artisan migration
Now whenever you want to see if a user has permissions(typically done in policies) just check that field
if($user->type === 'editor'){
// do editor only stuff
}

Related

how to save extra not required field in laravel default auth registration form

I am trying to customize the laravel auth registration. And I have added father name field in table and form. But father name field is not required.
I added this field in registercontroller.php and in User model also.
And then, if submit the form with all fields then data inserts successfully, But if I submit the form without father name field (which is not required), then error comes: f_name filed can not be null.
If I remove f_name from fillable then f_name is not saving.
Method in RegisterController.php is:
protected function create(array $data)
{
return User::create([
'name' => $data['name'],
'email' => $data['email'],
'f_name' => $data['f_name'],
'password' => bcrypt($data['password']),
]);
}
User.php is:
protected $fillable = [
'name', 'email', 'f_name' , 'password',
];
This is because you did not make it nullable in the database.
The other thing is that you should not code like that. You should create a Request class (where you validate request) for users with php artisan make:request UserRequest in command line or terminal. See the following.
protected function create(UserRequest $userRequest)
{
$user = new User($userRequest->all());
$user->password => bcrypt($userRequest['password']);
$user->save();
// your rest of the code.
}
Case 1: You might have set field default value to not-NULL in DB. Check your migrations it shpuld be something like $table->string('f_name')->nullable(); or Check in DB/phpmuadmin and set to NULL by default.
Case 2: Check your validator function, can set it to sometimes.

Laravel Model Factories ID not set

I have a regular User model. The system works fine when I use it. But now I am trying to create unit tests in the PHPUnit that integrated with Laravel.
I have a factory that creates a user:
$factory->define(App\User::class, function (Faker\Generator $faker) {
return [
'id' => $faker->randomNumber(9),
'email' => $faker->safeEmail,
'first_name' => $faker->firstNameMale,
'last_name' => $faker->lastName,
'password' => bcrypt(str_random(10)),
'remember_token' => str_random(10),
];
});
I changed the User to have integer ID as the primary key but it not defined as auto-increment.
So the factory create random number for the ID.
Also I have created the simple test:
public function test_id_is_visible() {
$user = factory(App\User::class)->create();
$this->actingAs($user);
$this->visit('/userprofile');
$this->see($user->id);
}
That test always fails, but it seems to be OK when I navigate to the page manually.
I have noticed that in the test the $user->id is always 0. Even it can't be 0 in the factory. I checked and Laravel insert the user correctly to the database and it have correct ID, but in the code I always get 0.
What can I do to get the correct value of the ID?
EDIT
Now I see that if I changes $user = factory(App\User::class)->create(); to $user = factory(App\User::class)->make(); the user instance holds a correct ID. But why create clears the ID?
Update for Laravel 5.8+ Make sure to set
public $incrementing = false;
on your model.
The problem happened because the ID is not defined as auto-increment.
More information you can found in:
https://stackoverflow.com/a/31350800/1725836
Even the question is for Laravel 4 it is still relevant for Laravel 5.2.
You can write your tests like this:
$users = factory(User::class, 5)->make();
$users->each(function ($item, $key) {
$item->id = ++$key;
});
Now each user will have an id, without the need to persist the models to database (using create() instead of make()).
public function test_id_is_visible() {
$user = factory(App\User::class)->make();
$user->id = 7;
$this->actingAs($user);
$this->visit('/userprofile');
$this->see($user->id);
}

Laravel Creating userInfo database table when user registers

I am doing an extension build on the User model on larval 5.
What I want to accomplish is once the user registers and is validated I want ANOTHER database table created named userInfo which has a belongsto Relationship with the User model and the User model has a hasOne relationship with userInfo.
Two things.
How to I successfully implement this logic. I was reading
http://laravel.com/docs/master/eloquent-relationships#inserting-related-models
and
http://laravel.com/docs/5.1/events#registering-events-and-listeners
But Im not to sure
And second.
Where best do I implement this logic.
Thanks in advance
PS. I do not what to combine the two database because the user model is when they register and data that lives in userInfo is "optional" for the user to fill out After authentication.
If I am understanding the question correctly, you want to create an additional related model to the user when they register. That should be pretty straightforward - something like:
$user->userInfo()->save(UserInfo::create([
//whatever information you need to save to the userInfo table - if any
]));
as for where to put it, you have options there. You could put it the 'store' method on your registration controller. Or extract it out to a service class 'RegisterUser', and create the user and userInfo there.
something like:
//controller method
public function store(Request $request, RegisterUser $registerUser)
{
$user = $registerUser->handle($request);
return view(....)
}
//RegisterUser class
public function __construct(UserInfo $userInfo)
{
$this->userInfo = $userInfo;
}
public function handle($request)
{
// create your user
$user = .....
$user->userInfo()->save($this->userInfo->create([
.....
]));
// whatever else you need to do - send email, etc
return $user;
}
Edit: If you are using Laravel 5 and the default registration scaffolding, then you can add code to the app\Services\Registar class. This class is called by the postRegister method in the trait. Change the create method:
// app\Services\Registar
public function create(array $data)
{
$user = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => bcrypt($data['password']),
]);
$user->userInfo()->save($this->userInfo->create([
.....
]));
// whatever else you need to do - send email, etc
return $user;
}
If you are using Laravel 5.1 then the Registar class doesn't exist anymore, the create method has been moved to the AuthController (the method is the same, just in a different location) so override it there.
Your answer pointed me in the right direction but I made some simple tweek to your edited question.
$user->userInfo()->firstOrCreate([
'aboutMe' => 'Please Fill out so users can know about you',
'bodyType' => '--',
]);
return $user;

Laravel unique validation issue

I try to make a unique validation the settings of my website but this doesn't work :
In my controller :
$rules = array(
'username' => 'required|unique:User,username,10',
'email' => 'required|email|unique:User,email,10',
'language' => 'required|in:fr,en',
);
My model:
class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
protected $primaryKey = 'id_user';
protected $table = 'user';
}
The problem is:
My Validator Validator::make(Input::all(), $rules, $messages); fails, it says that this username and email already exist.
Disagree with the answer to your own question:
"Laravel is not done to search in a custom column".
This is not true.
To be precise: There is nothing bad in using a Plugin...
See the important part of a migration file (app/database/migrations):
// creates a DB-table named 'users'
Schema::create('users', function (Blueprint $t) {
$t->increments('id');
$t->timestamps();
// ... Here a unique field
$t->string('user_email_one', 255)->unique();
// ...
});
And the relevant validation rules in the UserController:
$rules = array(
'user_email_one' => 'required|email|unique:users',
// ...
);
And Laravel is doing its job.
With unique: you have to call the DB-table name, not the model name.
BTW: the plugin you've chosen does this...
The Laravel docs about validation:
unique:table,column,except,idColumn
The field under validation must be unique on a given database table.
If the column option is not specified, the field name will be used.
Just as an interesting info about naming a mySQL table 'User', 'user' or 'users', which could have caused your error. Visit this question:
Is there a naming convention for MySQL? asked by StackOverflowNewbie, answered by Tom Mac (highest vote & accepted answer)
Laravel is not done to search in a custom column.
So I have installed this plugin https://github.com/felixkiss/uniquewith-validator who did the job very well:
$rules = array(
'username' => 'required|alpha_dash|unique_with:user,username,10 = id_user',
'email' => 'required|email|unique_with:user,email,10 = id_user',
'language' => 'required|in:fr,en',
);

MassAssignmentException in Laravel

I am a Laravel newbie. I want to seed my database. When I run the seed command I get an exception
[Illuminate\Database\Eloquent\MassAssignmentException]
username
db:seed [--class[="..."]] [--database[="..."]]
What am I doing wrong. The command I use is:
php artisan db:seed --class="UsersTableSeeder"
My seed class is as follows:
class UsersTableSeeder extends Seeder {
public function run()
{
User::truncate();
User::create([
'username' => 'PaulSheer',
'email' => 'psheer#rute.co.za',
'password' => '45678'
]);
User::create([
'username' => 'Stevo',
'email' => 'steve#rute.co.za',
'password' => '45678'
]);
}
}
Read this section of Laravel doc : http://laravel.com/docs/eloquent#mass-assignment
Laravel provides by default a protection against mass assignment security issues. That's why you have to manually define which fields could be "mass assigned" :
class User extends Model
{
protected $fillable = ['username', 'email', 'password'];
}
Warning : be careful when you allow the mass assignment of critical fields like password or role. It could lead to a security issue because users could be able to update this fields values when you don't want to.
I am using Laravel 4.2.
the error you are seeing
[Illuminate\Database\Eloquent\MassAssignmentException]
username
indeed is because the database is protected from filling en masse, which is what you are doing when you are executing a seeder. However, in my opinion, it's not necessary (and might be insecure) to declare which fields should be fillable in your model if you only need to execute a seeder.
In your seeding folder you have the DatabaseSeeder class:
class DatabaseSeeder extends Seeder {
/**
* Run the database seeds.
*
* #return void
*/
public function run()
{
Eloquent::unguard();
//$this->call('UserTableSeeder');
}
}
This class acts as a facade, listing all the seeders that need to be executed. If you call the UsersTableSeeder seeder manually through artisan, like you did with the php artisan db:seed --class="UsersTableSeeder" command, you bypass this DatabaseSeeder class.
In this DatabaseSeeder class the command Eloquent::unguard(); allows temporary mass assignment on all tables, which is exactly what you need when you are seeding a database. This unguard method is only executed when you run the php aristan db:seed command, hence it being temporary as opposed to making the fields fillable in your model (as stated in the accepted and other answers).
All you need to do is add the $this->call('UsersTableSeeder'); to the run method in the DatabaseSeeder class and run php aristan db:seed in your CLI which by default will execute DatabaseSeeder.
Also note that you are using a plural classname Users, while Laraval uses the the singular form User. If you decide to change your class to the conventional singular form, you can simply uncomment the //$this->call('UserTableSeeder'); which has already been assigned but commented out by default in the DatabaseSeeder class.
To make all fields fillable, just declare on your class:
protected $guarded = array();
This will enable you to call fill method without declare each field.
Just add Eloquent::unguard(); in the top of the run method when you do a seed, no need to create an $fillable array in all the models you have to seed.
Normally this is already specified in the DatabaseSeeder class. However because you're calling the UsersTableSeeder directly:
php artisan db:seed --class="UsersTableSeeder"
Eloquent::unguard(); isn't being called and gives the error.
I used this and have no problem:
protected $guarded=[];
I was getting the MassAssignmentException when I have extends my model like this.
class Upload extends Eloquent {
}
I was trying to insert array like this
Upload::create($array);//$array was data to insert.
Issue has been resolve when I created Upload Model as
class Upload extends Eloquent {
protected $guarded = array(); // Important
}
Reference https://github.com/aidkit/aidkit/issues/2#issuecomment-21055670
User proper model in your controller file.
<?php
namespace App\Http\Controllers\Auth;
use App\Http\Controllers\Controller;
use App\User;
if you have table and fields on database you can simply use this command :
php artisan db:seed --class=UsersTableSeeder --database=YOURDATABSE
This is not a good way when you want to seeding database.
Use faker instead of hard coding, and before all this maybe it's better to truncate tables.
Consider this example :
// Truncate table.
DB::table('users')->truncate();
// Create an instance of faker.
$faker = Faker::create();
// define an array for fake data.
$users = [];
// Make an array of 500 users with faker.
foreach (range(1, 500) as $index)
{
$users[] = [
'group_id' => rand(1, 3),
'name' => $faker->name,
'company' => $faker->company,
'email' => $faker->email,
'phone' => $faker->phoneNumber,
'address' => "{$faker->streetName} {$faker->postCode} {$faker->city}",
'about' => $faker->sentence($nbWords = 20, $variableNbWords = true),
'created_at' => new DateTime,
'updated_at' => new DateTime,
];
}
// Insert into database.
DB::table('users')->insert($users);
Use the fillable to tell laravel which fields can be filled using an array.
By default, Laravel does not allow database fields to be updated via an array
Protected $fillable=array('Fields you want to fill using array');
The opposite of fillable is guardable.
If you use the OOP method of inserting, you don't need to worry about mass-action/fillable properties:
$user = new User;
$user->username = 'Stevo';
$user->email = 'steve#rute.co.za';
$user->password = '45678';
$user->save();

Categories