FatalThrowableError in Call to a member function get_one() on null - laravel

i have some laravel code like this
public function update_password(Request $request)
{
$data = array(
'password_current' => $request->input('password_current'),
'password_new' => $request->input('password_new'),
'password_new_confirmation' => $request->input('password_new_confirmation'),
);
$rules = [
'password_current' => 'required',
'password_new' => 'required|confirmed',
'password_new_confirmation' => 'required',
];
$validator = Validator::make($data, $rules);
if ($validator->fails()) {
return redirect()->action('Editor\ProfileController#edit_password')->withInput()->withErrors(['New password confirmation failed!']);
} else {
$user = $this->UserRepository->get_one(Auth::user()->id);
if(Hash::check($request->input('password_current'), $user->password))
{
$this->UserRepository->change_password(Auth::user()->id, $request->input('password_new'));
return redirect()->action('Editor\ProfileController#show');
} else {
return redirect()->action('Editor\ProfileController#edit_password')->withInput()->withErrors(['Current password mismatch!']);
}
}
}
but when i run the program, the program notification is FatalThrowableError, Call to a member function get_one() on null. i change with other script in google but no one is work.
$user = $this->UserRepository->get_one(Auth::user()->id);
anyone ever had this problem?
I try to change script like
use Auth;
$user_id = Auth::user()->id;
and still not work.

Related

Verify Token is Token Laravel Passport

I was recently updating from laravel's sanctum to passport; and there is this one test that bothers me a lot.
In sanctum there is this method under the PersonalAccessToken model that finds the token and returns the token if it exists.
I don't seem to find anything like that in the docs or online.
I'm validating the test by asserting that $user->tokens is not empty... yet I wish to validate that the token I'm returning from my login controller is indeed a token; not just the creation;
Thnx in advance...
Login Test
public function user_can_login()
{
//$this->withoutExceptionHandling();
$user = User::factory()->create();
$url = route('api.v1.auth.login', [
'email' => $user->email,
'password' => 'password'
]);
$res = $this->jsonApi()
->post($url)
->assertStatus(200);
$token = $res->json(['access_token']);
$this->assertNotEmpty($user->tokens);
}
Login method in authcontroller
public function login(Request $request)
{
$request->validate([
'email' => 'required|email',
'password' => 'required',
]);
$credentials = $request->only(['email', 'password']);
if (Auth::attempt($credentials)) {
$user = Auth::user();
$access_token = $user->createToken('laravel-api.local')->accessToken;
return response()->json(['access_token' => $access_token], 200);
} else {
return response()->json(['error' => 'Unauthorized'], 401);
}
}
pues:dont know why im writing the code, but just for ref of what i'm doing
https://laracasts.com/discuss/channels/testing/how-do-i-create-a-route-while-testing
solution is quite simple... you'll find it here... I had an issue when I tried that before hand and it seems to be with the use of the Route::name('name') method and the route('name') function threw a server error. but if you call the path directly it should work...
any who... authController and login method stay the same but the test changes to...
public function setUp(): void
{
parent::setUp();
Route::middleware('auth:api')
->get('/test-route', function (Request $request) {
return $request->user();
});
$clientRepository = new ClientRepository();
$client = $clientRepository->createPersonalAccessClient(
null,
'Personal Access Client Test',
'/'
);
DB::table('oauth_personal_access_clients')->insert([
'client_id' => $client->id,
'created_at' => date('Y-m-d'),
'updated_at' => date('Y-m-d'),
]);
}
/** #test */
public function user_can_login_with_correct_credentials()
{
//$this->withoutExceptionHandling();
$user = User::factory()->create();
$url = route('api.v1.auth.login', [
'email' => $user->email,
'password' => 'password',
'device_name' => $user->name . ' test Device'
]);
$res = $this->jsonApi()
->post($url)
->assertStatus(200);
$token = $res->json(['access_token']);
$this->jsonApi()
->withHeader('Authorization', 'Bearer ' . $token)
->get('/test-route')
->assertStatus(200);
}

Laravel passport create token doesnt work on plesk server

I use passport in my laravel project to authenticate users by api. API work correctly on my local host. But after i deploy it on Plesk server token doesnt create. Always show Server Error.
public function login(Request $request) {
$validator = Validator::make($request->all(),[
'email' => 'required',
'password' => 'required',
]);
if($validator->fails()) {
return response()->json(["validation errors" => $validator->errors()]);
}
$email = $request->email;
$password = $request->password;
error_log($password);
$user = DB::table("users")->where([["email", "=", $email]])->first();
if(is_null($user)) {
return response()->json(["success" => false, "message" => "User doesn't exist"]);
}
if(Auth::attempt(['email' => request('email'), 'password' => request('password')])) {
$user = Auth::user();
$token = $user->createToken('token')->accessToken;
$success['success'] = true;
$success['user'] = $user;
$success['message'] = "Success! you are logged in successfully";
$success['token'] = $token;
return response()->json(['success' => $success ], 200);
} else {
return response()->json(['error' => 'Unauthorised'], 401);
}
}
$token = $user->createToken('token')->accessToken;
This line throw error
Problem was in my AuthServiceProvider
class AuthServiceProvider extends ServiceProvider
{
protected $policies = [
'Medicare\Model' => 'Medicare\Policies\ModelPolicy',
];
public function boot()
{
$this->registerPolicies();
Passport::routes();
//
}
}
After i commented 'Medicare\Model' => 'Medicare\Policies\ModelPolicy' everything works fine.

How can i avoid image required in edit form if image exist in laravel?

I am adding and editing a user with same function (Store), when ever i add a user it asks me image is required but whenever i edit a user which have image it also ask me image is required and i want if a image is already present it wont ask me , please see my above code i had recently changed my code according to Gurpal singh
In my controller
public function rules()
{
$child_details = Children::findOrFail($inputs['id']);
$rules = [
'child_name' => 'required',
'gender' => 'required',
'dob' => 'required',
'current_class' => 'required',
'b_group' => 'required',
'm_tongue' => 'required',
'image' => 'image',
];
if ($child_details->notHavingImageInDb()){
$rules['image'] = 'required|image';
}
return $rules;
}
public function Postchild(Request $request)
{
$data = \Input::except(array('_token')) ;
$validator = \Validator::make($data,$rules);
$inputs = $request->all();
if ($validator->fails())
{
return redirect()->back()->withInput()->withErrors($validator->messages());
}
if(!empty($inputs['id'])){
$child_details = Children::findOrFail($inputs['id']);
}else{
$child_details = new Children;
}
$child_details->parent_id = Auth::User()->id;
$child_details->child_name = $inputs['child_name'];
$child_image = $request->file('image');
if($child_image){
$tmpFilePath = 'uploads/childrens/';
$extension = $child_image->getClientOriginalExtension();
$hardPath = str_slug($inputs['child_name'], '-').'-'.md5(time());
$img = Image::make($child_image);
//$img->resize(180)->save($tmpFilePath.$hardPath.'-b.jpg');
$img->fit(250, 250)->save($tmpFilePath.$hardPath.'.'.$extension);
$child_details->image = $hardPath.'.'.$extension;
}
$child_details->save();
if(!empty($inputs['id'])){
return \Redirect()->route('child_list')->with('success', 'Child has been updated');
}else{
return \Redirect()->route('child_list')->with('success', 'Child has been added');
}
}
You can use Conditionally Adding Rules Not having image in database
Add this in model
public function notHavingImageInDb()
{
return (empty($this->image))?true:false;
}
This is the validation rule request
public function rules()
{
$user = User::find(Auth::id());
$rules = [
'name' =>'required|max:100',
'image' =>'image',
];
if ($user->notHavingImageInDb()){
$rules['image'] = 'required|image';
}
return $rules;
}
Don't forgot to import auth and user model
ie
use App\User;
use Auth;
for more detail click here
You can normally do like below :
$rule = array(
'name' => 'required',
);
if (!empty($inputs['id'])) {
$user = User::findOrFail($inputs['id']);
} else {
$rule["image"] = "required";
$user = new User;
}
It is better to separate them or simply create another function. But you can put an if statement that if the image is in the request or not.
Like this:
if(! isset($data['image'])){ //if the image is not in the request
//Your code
}
else{ //if the image is in the request
//Your code
}
If you want a code for storing, renaming, moving an image feel free to request.
You can use validation's after hook.
public function Postchild(Request $request)
{
//Define your rules
$rules = [
'child_name' => 'required',
'gender' => 'required',
'dob' => 'required',
'current_class' => 'required',
'b_group' => 'required',
'm_tongue' => 'required',
];
//Validate your data
$data = $request->except('_token');
$validator = \Validator::make($data,$rules);
$validator->after(function ($validator) {
//Check the mode of request (Create or Update)
if(!empty($data['id'])){
$child_details = Children::findOrFail($data['id']);
if($child_details->image == null){
$validator->errors()->add('image', 'Image field is required');
}
}
});
if ($validator->fails()) {
return redirect()->back()
->withErrors($validator)
->withInput();
}
}
Just this few lines can solve your problems... You have to check there image have or not.
Rules in a private or protected function
private function validateRequest($request)
{
//This is for Update without required image, this will check that In DB image have or not
$child_image = Children::find($request->id);
$rules = [];
if ($child_image) :
if ($child_image->image == null):
$rules['image'] = 'required|image|max:1999';
endif;
//This is for regular validation
else :
$rules = [
'image' => 'required|image|max:1999',
];
endif;
return $rules;
}

Lumen: update records via json body

I have a Laravel Lumen API. I'm seeing an issue with the update functionality.
In my controller, the code for updating an item is:
public function update(Request $request, $id)
{
$this->validate($request, [
'name' => 'required',
'description' => 'required',
'completed' => 'required',
]);
$todo = Todo::find($id);
$todo->name = $request->name;
$todo->description = $request->description;
$todo->completed = $request->completed;
$todo->save();
return response()->json(['status' => 'success']);
}
I can update the todo item using:
http://lumen-todo.app/api/51?name=test&description=test&completed=1
however was hoping I could send the parameters in a json body, like this
PUT http://lumen-todo.app/api
{
"id": 1
"name": "Test",
"description": "Test",
"completed": 1,
}
For adding items, it works via a json body, so don't understand why it does not work for updates. For info, the 'add item' controller code is here:
public function store(Request $request)
{
$this->validate($request, [
'name' => 'required',
'description' => 'required',
'completed' => 'required'
]);
$todo = new Todo();
$todo->name = $request->name;
$todo->description = $request->description;
$todo->completed = $request->completed;
$todo->save();
return response()->json(['status' => 'success']);
}
If you want to get the json data from request payload, validate and store it, use
public function store(Request $request)
{
$data = $request->json()->all();
$this->validate($data, [
'name' => 'required',
'description' => 'required',
'completed' => 'required'
]);
$resource = $this->model->find($id);
$resource->fill($request);
$resource->save();
return response()->json(['status' => 'success']);
}
Instead of doing this:
$todo = new Todo();
$todo->name = $request->name;
$todo->description = $request->description;
$todo->completed = $request->completed;
$todo->save();
Do, this:
use App\Todo;
protected $model;
public function __construct(Todo $model) {
$this->model = $model;
}
$resource = $this->model->find($id);
$resource->fill($request);
$resource->save();
Also, you can do json_decode() function to change your json params to array and use that to validate and save data.

Laravel Testing User::store() with phpunit

I'm learning both Laravel and UnitTesting at the moment, so this may be a stupid question.
I'm getting stuck on how to best test the controller function below:
UserController:
public function store()
{
$input = Input::all();
$user = new User($input);
if( ! $user->save()){
return Redirect::back()->withInput()->withErrors($user->getErrors());
}
return Redirect::to('/user');
}
here's the test as I have it so far:
/**
* #dataProvider providerTestUserStoreAddsUsersCorrectly
*/
public function testUserStoreAddsUsersCorrectly($first_name, $last_name, $email, $password)
{
$response = $this->call('POST', 'user', array('first_name'=>$first_name, 'last_name'=>$last_name, 'email'=>$email, 'password'=>$password));
}
public function providerTestUserStoreAddsUsersCorrectly(){
return array(
array("FirstName", "LastName", "Email#add.com", "pass1234")
);
}
This is actually working and adding the user to the db correctly, but I'm not sure how to test the output / what assertions to use as the response should be to add the user to the db and to redirect to the /user page.
How do I finish this test?
If you need to check success status then you can simply send status code from your controller
and check status in test
public function store()
{
$input = Input::all();
$user = new User($input);
if( !$user->save() ){
return array("status"=>'failed');
}
return array("status"=>'success');
}
public function testUserStoreAddsUsersCorrectly($first_name, $last_name, $email, $password)
{
$requested_arr = [
'first_name' => $first_name,
'last_name' => $last_name,
'email' => $email,
'password' => $password
];
$response = $this->call('POST', 'user', $requested_arr);
$data = json_decode($response ->getContent(), true);
if ($data['status']) {
$this->assertTrue(true);
} else {
$this->assertTrue(false);
}
}

Resources