I am creating an activation code after user registered , and I want to fetch that code after creating , all the codes are created in database but I can not fetch that code in event,this is my code:
public function __construct(User $user)
{
$this->user = $user;
$this->activationCode = ActivationCode::createCode($user)->code;
dd( ActivationCode::createCode($user)->code);
}
My error is :
Undefined property: Illuminate\Database\Eloquent\Builder::$code
How can I fetch code?
Use value() method:
ActivationCode::createCode($user)->latest()->value('code')
Or get the object first:
ActivationCode::createCode($user)->first()->latest()->code;
Related
I have a laravel app using Policies to assign roles and permissions, i cant seem to access the show page and im not sure what im doing wrong?
If i set return true it still shows a 403 error as well, so im unsure where im going wrong here. The index page is accessable but the show page is not?
UserPolicy
public function viewAny(User $user)
{
if ($user->isSuperAdmin() || $user->hasPermissionTo(44, 'web')) {
return true;
}
return false;
}
public function view(User $user, User $model)
{
if ($user->isSuperAdmin() || $user->hasPermissionTo(44, 'web')) {
return true;
}
return false;
}
UserController
public function __construct()
{
$this->authorizeResource(User::class, 'user');
}
public function index()
{
$page_title = 'Users';
$page_description = 'User Profiles';
$users = User::all();
return view('pages.users.users.index', compact('page_title', 'page_description', 'users'));
}
public function create()
{
//
}
public function store(Request $request)
{
//
}
public function show($id)
{
$user = User::findOrFail($id);
$user_roles = $user->getRoleNames()->toArray();
return view('pages.users.users.show', compact('user', 'user_roles'));
}
Base on Authorize Resource and Resource Controller documentation.
You should run php artisan make:policy UserPolicy --model=User. This allows the policy to navigate within the model.
When you use the authorizeResource() function you should implement your condition in the middleware like:
// For Index
Route::get('/users', [UserController::class, 'index'])->middleware('can:viewAny,user');
// For View
Route::get('/users/{user}', [UserController::class, 'view'])->middleware('can:view,user');
or you can also use one policy for both view and index on your controller.
I had an issue with authorizeResource function.
I stuck on failed auth policy error:
This action is unauthorized.
The problem was that I named controller resource/request param with different name than its model class name.
F. ex. my model class name is Acknowledge , but I named param as timelineAcknowledge
Laravel writes in its documentation that
The authorizeResource method accepts the model's class name as its first argument, and the name of the route / request parameter that will contain the model's ID as its second argument
So the second argument had to be request parameter name.
// Here request param name is timelineAcknowledge
public function show(Acknowledge $timelineAcknowledge)
{
return $timelineAcknowledge->toArray();
}
// So I used this naming here also
public function __construct()
{
$this->authorizeResource(Acknowledge::class, 'timelineAcknowledge');
}
Solution was to name request param to the same name as its model class name.
Fixed code example
// I changed param name to the same as its model name
public function show(Acknowledge $acknowledge)
{
return $acknowledge->toArray();
}
// Changed here also
public function __construct()
{
$this->authorizeResource(Acknowledge::class, 'acknowledge');
}
I looked over Laravel policy auth code and I saw that the code actually expects the name to be as the model class name, but I couldn't find it anywhere mentioned in Laravel docs.
Of course in most of the cases request param name is the same as model class name, but I had a different case.
Hope it might help for someone.
So I'm learning doing tests for my application and one of the tests it doesn't want to pass, and here it is the logic: Basically, when a user request the home page, I expect that the database list count would be 0, and this passed, then I expect also that the session has an error key of NoBook and here it fails. this is the code that i have tried:
class BookDisplayManagmentTest extends TestCase
{
use RefreshDatabase;
/** #test */
public function Show_error_message_when_there_is_no_book_to_display_in_index_page()
{
//Request the home page
$response = $this->get(route('home'));
// I expect the count on the database book equal 0
$this->assertCount(0, book::all());
//Then I also expect that the session will flash an error with key NoBook
$response->assertSessionHasErrors('NoBook');
}
}
But the problem I'm getting this error:
Session is missing expected key [errors]. Failed asserting that false is true.
And the code that add the session error:
<?php
namespace App\Http\Controllers;
use App\Books;
use Illuminate\Http\Request;
class IndexController extends Controller
{
/** #show index function */
public function index()
{
$book = Books::paginate(7);
if(!$book->count())
{
session()->now('NoBook','There is no books at the moment');
}
return view('index', compact('book'));
}
}
You are using session() which is adding a key to the session which is not an error key.
Therefore, since you are not passing an error from your Controller - then your test is "successfully" failing.
If you want to pass on an error to the session, you have to use MessageBag such as using the following code:
/** #show index function */
public function index()
{
$book = Books::paginate(7);
$errors = [];
if(!$book->count())
{
$errors['NoBook'] = 'There is no books at the moment';
}
return view('index', compact('book'))->withErrors($errors);
}
What I am trying to do is apply a policy on a control method that lists a bunch of records instead of just one record like most of the examples I have seen.
Instead of checking against the ThoughtRecords I want to check the signed in user hashedId to the user that's being queried hashedId in the controller index() method.
Apparently in the Laravel docs the model class needs to be passed on actions that don't require a model. So I'm confused how to make this work.
AuthServiceProvider.php
protected $policies = [
'App\ThoughtRecord' => 'App\Policies\ThoughtRecordPolicy',
];
public function boot()
{
$this->registerPolicies();
}
ThoughtRecordPolicy.php
public function view(User $signedInUser, User $client)
{
//return true;
dd('Policy working');
//return $signedInUser->id === $client->id;
}
ThoughtRecordController.php
public function index($userHashedId)
{
$client = User::where('hashed_id', $userHashedId)->first();
$this->authorize('view', ThoughtRecord::class, $client);
$records = ThoughtRecord::where('user_id', $client->id)->latest()->paginate(1);
return ThoughtRecordResource::collection($records);
}
Error
Too few arguments to function App\Policies\ThoughtRecordPolicy::view()
I have also tried:
$this->authorize('view', $client);
This action is unauthorized.
As said:
Apparently in the Laravel docs the model class needs to be passed on actions that don't require a model. So I'm confused how to make this work.
You need pass both the ThoughtRecord::class and the $client into an array:
$this->authorize('view', [ThoughtRecord::class, $client]);
I am building a project with Laravel and Vue using Axios and Passport.
My authentication is working and generating token and saving in my local storage to check for login.
I am also getting the data using
Route::middleware('auth:api')->get('/user', function (Request $request) {
return $request->user();
});
However, my user also has some relationship which I have described in my model like
public function types()
{
return $this->belongsTo(types::class, 'type_id');
}
and my user resource looks like this
public function toArray($request)
{
$array = parent::toArray($request);
$array['group'] = $this->groups;
$array['type'] = $this->types->typeName;
return $array;
}
So when user login I am trying to get user data using auth:api however I want a relationship to come with it.
I tried
Route::middleware('auth:api')->get('/user', function (Request $request) {
return UserResource::collection($request->user());
});
and get error
> Call to undefined method App\User::mapInto()
I also tried
```php
return new UserResource::collection($request->user());
error: syntax error, unexpected 'collection' (T_STRING), expecting variable (T_VARIABLE) or '$'
return UserResource::collection($request->user()-get());
error: Trying to get property 'typeName' of non-object
So what am I doing wrong? thanks for your time and if need more details please let me know
You can achieve similar, if not better results using Eager loading. source
Sample:
Route::get('me', function(Request $request) {
$request->user()->load('types');
});
this is used to authenticate my users from accesing the views in this controller I keep getting this error when trying to access session data
---PHP Fatal error: Call to a member function userdata() on null in G:\PleskVhosts\apptcenter.com\control.apptcenter.com\application\controllers\tech.php on line 13 ----
I have tried loading the session library here and reinitializing my session(session_start()) but I keeps saying its is null or that im calling library() on null.
class tech extends CI_Controller {
function __construct()
{
$email = $this->session->userdata("activeEmail");
$query = $db->query("SELECT * FROM tech WHERE Contains('email', $email)");
if(empty($query))
{
redirect("Welcome/index");
}
}