Zizaco Entrust 'hasRole' not working within Laravel controller - laravel

User model:
<?php
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
use Zizaco\Entrust\HasRole;
class User extends Eloquent implements UserInterface, RemindableInterface {
use HasRole;
Role Model:
<?php
use Zizaco\Entrust\EntrustRole;
class Role extends EntrustRole
{
}
Permission Model:
<?php
use Zizaco\Entrust\EntrustPermission;
class Permission extends EntrustPermission
{
}
User controller:
public function postSignin(){
if (Auth::attempt(array('email'=>Input::get('email'),
'password'=>Input::get('password')))) {
$id = Auth::user()->id;
$user = User::where('id','=',$id);
$firstname = Auth::user()->firstname;
if ($user->hasRole("User_Not_Approved")) {
return Redirect::intended('/users/dashboard');
}
Error message:
BadMethodCallException
Call to undefined method Illuminate\Database\Query\Builder::hasRole()
The error message is presented when the IF statement is running, whilst the user is logging in. I have followed Entrust's instructions, but I am at a loss as to why it isn't picking up the method.
Any help would be hugely appreciated!

Try changing: $user = User::where('id','=',$id); to $user = User::find($id);
User::where would need ->get to return what you want, and even then it would return a collection; you would want something like User::where(etc)->first(); to ensure you got a single instance of User. In reality though, since you are retrieving by id, that is what ->find($id) is designed for, and what you should do.

Related

method addMediaFromUrl() from spatie not working

I want use spatie to get Google+ avatar, but when I try get it there is an error.
$user = Socialite::driver('google')->user();
$usertest=User::whereEmail($user->getemail())->first();
if(! $usertest){
$usertest=User::create([
'name'=>$user->name,
'email'=>$user->email,
'password'=>bcrypt($user->id)
]);}
$usertest->addMediaFromUrl($user->avatar)->toMediaCollection('avatar');
auth()->loginUsingId($usertest->id);
return redirect('/');
error:
Type error: Argument 1 passed to Spatie\MediaLibrary\FileAdder\FileAdder::processMediaItem() must be an instance of Spatie\MediaLibrary\HasMedia\HasMedia, instance of App\User given,
It looks like you have not added HasMedia interface and HasMediaTrait to User class:
class User extends Authenticatable implements HasMedia {
use HasMediaTrait;
// ...
}

PhpUnit - mocking laravel model with relations

I'm trying to mock (it's example only) $user->posts()->get().
example service:
use App\Models\User;
class SomeClass{
public function getActivePost(User $user): Collection
{
return $user->posts()->get();
}
}
and my Model:
and Model:
namespace App\Models;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use \App\Models\Post;
class User extends Model
{
public function posts() : HasMany
{
return $this->hasMany(Post::class);
}
}
this doesn't work:
$this->user = Mockery::mock(User::class);
$this->user
->shouldReceive('wallets->get')
->andReturn('test output');
error:
TypeError: Return value of Mockery_2_App_Models_User::posts() must be an instance of Illuminate\Database\Eloquent\Relations\HasMany, instance of Mockery_4__demeter_posts returned
without return type hint (on post() method) everything is ok. Must I modify andReturn()? idk how
This error can be solved by using the alias prefix with a valid class name. Like the following:
$m = m::mock('alias:App\Models\User');
More information can be found at the official documentation http://docs.mockery.io/en/latest/reference/creating_test_doubles.html#aliasing
Alternatively you can use like this.
use App\Models\User;
class SomeClass{
public function getActivePost(User $user): Collection
{
$user->load('posts');
return $user->posts;
}
}
First you need to mock post, then add it to Collection (don't forget to use it in the top). Then when you call posts attribute its takes mocked $posts. In this case it will not throw error about return type.
use Illuminate\Database\Eloquent\Collection;
$post = $this->mock(Post::class)->makePartial();
$posts = new Collection([$post]);
$this->user = Mockery::mock(User::class);
$this->user
->shouldReceive('getAttribute')
->with('posts');
->andReturn($posts);
Also i wouldn't use mocks here. There is absolutely no need for it. So the unit test i write would be:
Create a user.
Create some posts authored by the user.
Perform assertions on user & posts.
So the code will then be something like this in my test:
$user = factory(User::class)->create();
$posts = factory(Post::class, 5)->create(['user_id' => $user->id]);
$this->assertNotEmpty($user->id);
$this->assertNotEmpty($posts);
$this->assertEquals(5, $posts->fresh()->count());
$this->assertEquals($user->id, $post->fresh()->first()->user_id);
if you want to test the relationship you can:
/** #test */
function user_has_many_posts()
{
$user = factory(User::class)->create();
$post= factory(Post::class)->create(['user_id' => $user->id]);
//Check if database has the post..
$this->assertDatabaseHas('posts', [
'id' => $post->id,
'user_id' => $user->id,
]);
//Check if relationship returns collection..
$this->assertInstanceOf('\Illuminate\Database\Eloquent\Collection', $user->posts);
}

Laravel model: instance or relationship?

I'm not a professional programmer, so I don't know that I'm describing this very well.
Eloquent relationships are established in the model, using syntax and functions such as ... - >belongsTo.. etc.
Behind these models, are tables in my database.
In my (laravel) application, I have a logged in user who needs certain information about other users. At the end of the day, they're all just users, persisting in the user's table.
So when I use a relationship to another object, (e.g. car) all is good. When I try use a relationship to another user I get errors like Cannot redeclare class App\Models\User.
I think I'm misunderstanding something here.
I get the feeling maybe I should be 'instantiating' another version of my User (as 'manager') ... But do I really need to? It's more of a lookup than anything else. I'm not sure I would even know how to do that.
Some pointers please?
It sounds like you created two distinct "User" models:
// /app/User.php:
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
// ...
public function user() {
return $this->hasOne('App\Models\User');
}
}
// /app/models/User.php:
<?php namespace App\Models;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
// ...
public function user() {
return $this->belongsTo('App\User');
}
}
Instead you want to have a single class which belongs to itself:
// /app/User.php:
<?php namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
// ...
public function parent() {
return $this->belongsTo('App\User');
}
public function children() {
return $this->hasMany('App\User');
}
}
Then in your database make sure that the users table has a user_id property (edit database/migrations/2014_10_12_000000_create_users_table.php):
$table->integer('user_id')->unsigned()->nullable();
$table->foreign('user_id')->references('id')->on('users');
Now you can attach users to one another:
<?php
$manager = new User();
$employeeOne = new User();
$employeeTwo = new User();
$manager->children()->saveMany([
$employeeOne,
$employeeTwo
]);
dd( $employeeTwo->parent->name ); // Manager's name

Why I get BadMethodCallException?

In my seeder class, I am calling a method that is defined in a User model:
Like this:
$user = User::where('email', 'user1#teams.com')->get();
$user->test();
My User model:
class User extends Authenticatable
{
public function test()
{
return "!!";
}
}
But, when run the seed, I get this error:
[BadMethodCallException]
Method test does not exist.
the $user contains a collection of users since you are using get(). You can use first() instead.
So the new code should be:
$user = User::where('email', 'user1#teams.com')->first();

Laravel 4 arg1 must be an instance of UserInterface when using Auth::login

I have a basic laravel 4 app that allows someone to register and then login. I am trying to make it so that when a user completes their registration successfully they are logged in automatically. I get an error exception 'Argument 1 passed to Illuminate\Auth\Guard::login() must be an instance of Illuminate\Auth\UserInterface, instance of User given'. I understand that this means that the first argument being passed to the login method is not correct but I don't understand why it is not correct when the laravel documentation says to use
$user = User::find(1);
Auth::login($user);
Here is my controller
<?php
Class UsersController extends BaseController {
public $restful = 'true';
protected $layout = 'layouts.default';
public function post_create()
{
$validation = User::validate(Input::all());
if ($validation->passes()) {
User::create(array(
'username'=>Input::get('username'),
'password'=>Hash::make(Input::get('password'))
));
$user = User::where('username', '=', Input::get('username'))->first();
Auth::login($user);
return Redirect::Route('home')->with('message', 'Thanks for registering! You are now logged in!');
}
else {
return Redirect::Route('register')->withErrors($validation)->withInput();
}
}
}
?>
There's a few scenarios I can think of:
You're not using the User model which comes with a fresh Laravel install (sounds unlikely, but that one implements UserInterface, it's possible yours does not if you've edited it or created a new one).
User::create() isn't successfully being called (isn't created a user successfully)
$user = User::where()->... isn't resulting in a result
Try:
$user = User::create(array(
'username'=>Input::get('username'),
'password'=>Hash::make(Input::get('password'))
));
Auth::login($user);
If you still get errors, it's likely that $user isn't a User object because the user wasn't created successfully.
make sure your User.php begins like..
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {

Resources