I'm trying to send notification to database but having some trouble. In my notifications table, DATA row is null {"estate":null}. it should retrieve title and body though.
my controller is:
use Illuminate\Http\Request;
use App\Notifications\NewEstateNotification;
use App\Estate;
use App\User;
public function __construct()
{
$this->middleware('auth');
}
public function newEstate()
{
$estate = new Estate;
$estate->user_id = auth()->user()->id;
$estate->title = 'Laravel Notification';
$estate->body = 'This is the new Estate';
$estate->save;
$user = User::where('id', '!=', auth()->user()->id)->get();
if (\Notification::send($user, new NewEstateNotification(Estate::latest('id')->first())))
{
return back();
}
}
NewEstateNotification class:
use Queueable;
protected $estate;
/**
* Create a new notification instance.
*
* #return void
*/
public function __construct($estate)
{
$this->estate = $estate;
}
public function via($notifiable)
{
return ['database'];
}
public function toDatabase($notifiable)
{
return [
'estate' => $this->estate,
];
}
Any idea where am I doing wrong?
try to used like that
public function newEstate()
{
$estate = new Estate();
$estate->user_id = auth()->user()->id;
$estate->title = 'Laravel Notification';
$estate->body = 'This is the new Estate';
$estate->save();
$users = User::where('id', '!=', auth()->user()->id)->get();
//used like that
foreach($users as $user) {
$user->notify(new NewEstateNotification($estate));
}
return back();
}
in NewEstateNotification add toArray() method
public function toDatabase($notifiable)
{
return [
'estate' => $this->estate->toArray(),
];
}
it's also working fine if you want to used
\Notification::send($user, new NewEstateNotification($estate))
Related
I am a newbie in Laravel. So I am trying to update my form but it kept returning fail because I used the findOrFail method on the Controller.
But when I tried to dump the Id, the Id does exists.
Only when I call it using the method, it returns null.
Route for update
Route::post('/alumni/updateProfile','AlumniController#update');
Update method
public function update(Request $request, User $user, Profile $profile)
{
$user->roles()->sync($request->roles);
$profile = Profile::findOrFail(Auth::user()->id);
$profile->name = $request->name;
$profile->matric_no = $request->matric_no;
$profile->contact_no = $request->contact_no;
$profile->address = $request->address;
$profile->batch_year = $request->batch_year;
$profile->graduation_year = $request->graduation_year;
$profile->date_of_birth = $request->date_of_birth;
$profile->area_of_interest = $request->area_of_interest;
$profile->start_date = $request->start_date;
$profile->company_name = $request->company_name;
$profile->job_title = $request->job_title;
$profile->social_network = $request->social_network;
$profile->save();
return view('/home', compact('profile'));
}
Profile model
class Profile extends Model
{
// protected $guarded = [];
protected $fillable = ['alumni_id'];
protected $table = 'profiles';
public $timestamps = false;
public function users()
{
return $this->belongsTo('App\User');
}
}
User model
protected $hidden = [
'password', 'remember_token',
];
/**
* The attributes that should be cast to native types.
*
* #var array
*/
protected $casts = [
'email_verified_at' => 'datetime',
];
public function roles()
{
return $this->belongsToMany('App\Role');
}
public function profiles()
{
return $this->belongsTo('App\Profile');
}
public function hasAnyRoles($roles)
{
if($this->roles()->whereIn('name', $roles)->first()){
return true;
}
return false;
}
public function hasRole($role)
{
if($this->roles()->where('name', $role)->first()) {
return true;
}
return false;
}
Glad if any of you noticed anything, thank you.
You can write findOrFail() in try catch blog and get the exception in catch blog to understand the error.
OR
you can write below code instead of findOrFail().
$profile = Profile::where('id', '=', Auth::user()->id);
if( $profile->count() ){
# Assignment of values to database columns fields and then save.
$profile->save();
} else {
# Print No Record Found.
}
So i created a controller for authentication with 2 methods (token() / native)_). Im using fractal transformer to return response. The token method works fine for me, but the loginAndroid() returns
"Call to a member function createData() on null" error.
Any help? Thank you.
class AuthController extends RestController
{
protected $transformer = UserTransformers::Class;
public function __construct()
{
$this->middleware('auth:api', ['except' => ['login', 'loginAndroid']]);
}
public function login(Request $request)
{
$credentials = $request->only(['username', 'password']);
if (!$token = auth()->attempt($credentials)) {
return response()->json(['error' => 'Unauthorized'], 401);
}
return $this->respondWithToken($token);
}
public function loginAndroid(Request $request)
{
$credentials = $request->only(['username', 'password']);
if (Auth::attempt($credentials)) {
//$user = Auth::user()->with(['employees']);
$userdata = User::with(['employees', 'employees.role', 'employees.branch'])->find(Auth::id());
//$success['token'] = $user->createToken('MyApp')->accessToken;
//return response()->json($userdata, 200);
//return $userdata;
$response = $this->generateItem($userdata);
return $this->sendResponse($response, 201);
} else {
return response()->json('gagal', 401);
}
}
}
this is my restcontroller
abstract class RestController extends Controller
{
protected $manager;
protected $transformer;
public function __construct()
{
$this->manager = new Manager();
}
protected function generateItem($model, $transformer = null)
{
if (!is_null($transformer)) {
return new Item($model, new $transformer);
}
return new Item($model, new $this->transformer);
}
protected function generateCollection($model, $transformer = null)
{
if (!is_null($transformer)) {
return new Collection($model, new $transformer);
}
return new Collection($model, new $this->transformer);
}
protected function sendResponse(ResourceInterface $data, $status = 200)
{
return response()->json(
$this->manager->createData($data)->toArray(),
$status
);
}
protected function sendNotFoundResponse($status)
{
return response()->json($status, 404);
}
protected function sendIseResponse($status)
{
return response()->json($status, 500);
}
}
It looks like your sendResponse() method depends on $this->manager. However, $this->manager gets set in RestController::__construct() and you've overridden the __construct() method in your AuthController::__construct(). So, in order to have $this->manager available, you should call the parent constructor from your AuthController, like this:
class AuthController extends RestController
{
protected $transformer = UserTransformers::Class;
public function __construct()
{
parent::__construct(); // call the parent constructor where
// $this->manager gets initialized
$this->middleware('auth:api', ['except' => ['login', 'loginAndroid']]);
}
... etc
I'm getting the following error whenever i go on to a users page, its supposed to show if the authenticated user is already following the user that the profile is on.
Could this be a problem with the relationship setup, it hasMany
Stack trace
local.ERROR: Call to a member function addEagerConstraints() on
boolean {"userId":1,"email":"fakeemail#aol.com","exception":"[object]
(Symfony\Component\Debug\Exception\FatalThrowableError(code: 0):
Call to a member function addEagerConstraints() on boolean at
/Applications/MAMP/htdocs/elipost/vendor/laravel/framework/src/Illuminate/Database/Eloquent/Builder.php:522)"}
[]
UserController.php
public function getProfile($user)
{
$users = User::with([
'posts.likes' => function($query) {
$query->whereNull('deleted_at');
$query->where('user_id', auth()->user()->id);
},
'follow',
'follow.follower'
])->with(['followers' => function($query) {
$query->with('follow.followedByMe');
$query->where('user_id', auth()->user()->id);
}])->where('name','=', $user)->get();
$user = $users->map(function(User $myuser){
return ['followedByMe' => $myuser->followers->count() == 0];
});
if (!$user) {
return redirect('404');
}
return view ('profile')->with('user', $user);
}
MyFollow(model)
<?php
class MyFollow extends Model
{
use SoftDeletes, CanFollow, CanBeFollowed;
protected $fillable = [
'user_id',
'followable_id'
];
public $timestamps = false;
protected $table = 'followables';
public function follower()
{
return $this->belongsTo('App\User', 'followable_id');
}
public function followedByMe()
{
return $this->follower->getKey() === auth()->id();
}
}
MyFollow
use Overtrue\LaravelFollow\Traits\CanFollow;
use Overtrue\LaravelFollow\Traits\CanBeFollowed;
class MyFollow extends Model
{
use SoftDeletes, CanFollow, CanBeFollowed;
protected $fillable = [
'user_id',
'followable_id'
];
public $timestamps = false;
protected $table = 'followables';
public function follower()
{
return $this->belongsTo('App\User', 'followable_id');
}
public function followedByMe()
{
return $this->follower->getKey() === auth()->id();
}
}
Post
class Post extends Authenticatable
{
protected $fillable = [
'title',
'body',
'user_id',
'created_at',
];
public function user()
{
return $this->belongsTo(User::class);
}
public function comments()
{
return $this->hasMany('App\Comment');
}
public function likes()
{
return $this->hasMany('App\Like');
}
public function likedByMe()
{
foreach($this->likes as $like) {
if ($like->user_id == auth()->id()){
return true;
}
}
return false;
}
}
Likes
<?php
namespace App;
use App\Post;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\SoftDeletes;
class Like extends Model
{
use SoftDeletes;
protected $fillable = [
'user_id',
'post_id'
];
}
User(model)
class User extends Authenticatable
{
use Notifiable,CanFollow, CanBeFollowed;
/**
* 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',
];
public function posts()
{
return $this->hasMany(Post::class);
}
public function images()
{
return $this->hasMany(GalleryImage::class, 'user_id');
}
public function likes()
{
return $this->hasMany('App\Like');
}
public function follow()
{
return $this->hasMany('App\MyFollow');
}
public function comments()
{
return $this->hasMany('App\Comment');
}
}
As Jonas Staudenmeir stated, followedByMe isn't a relationship, it's a regular function and what it does is returning a boolean. I'm confused at why you've got a follow on your user model and trying to get information from the follow's follower? Just simplify, I see too much unneeded eager loading here.
Searching by indexed elements (id) > searching by name, any day of the week
Edit:
UserController
public function getProfile(Request $request, $id)
{
//$request->user() will get you the authenticated user
$user = User::with(['posts.likes','followers','follows','followers.follows'])
->findOrFail($request->user()->id);
//This returns the authenticated user's information posts, likes, followers, follows and who follows the followers
//If you wish to get someone else's information, you just switch
//the $request->user()->id to the $id if you're working with id's, if you're
//working with names, you need to replace findOrFail($id) with ->where('name',$name')->get() and this will give you
//a collection, not a single user as the findOrFail. You will need to add a ->first() to get the first user it finds in the collection it results of
//If you're planning on getting an attribute (is_following = true) to know if
//the authenticated user is following, you can use an accessor in the User model and write this after you've fetched the instance of the User
//$user->append('is_following');
return view ('profile')->with('user', $user);
}
User Model
//Accessor
//People who this user follows
public function getIsFollowingAttribute()
{
return MyFollow::where('followable_id',$this->attributes['id'])->where('user_id',Auth()->user()->id)->count() > 0 ? true : false;
}
//Relationships
//People who this user follows
public function follow()
{
return $this->hasMany('App\MyFollow','user_id','id');
}
//People who follows this user
public function followers()
{
return $this->hasMany('App\MyFollow','followable_id','id');
}
//Posts of this user
public function posts()
{
return $this->hasMany('App\Post','user_id','id');
}
//Likes of this user, not sure about this one tho, we're not using this for now but it could come in handy for you in the future
public function likes()
{
return $this->hasManyThrough('App\Likes','App\Post','user_id','user_id','id');
}
Post Model
//Who like this post
public function likes()
{
return $this->hasMany('App\Post','user_id','id');
}
MyFollow Model
//Relationships
//People who follow this user
public function followers()
{
return $this->hasMany('App\MyFollow','followable_id','user_id');
}
//Relationships
//People who this user follows
public function follow()
{
return $this->hasMany('App\MyFollow','user_id','followable_id');
}
With the help of #abr i found a simple fix, simple solution.
MyFollow.php(model)
public function followers()
{
return $this->hasMany('App\MyFollow','followable_id','user_id');
}
//Relationships
//People who this user follows
public function follow()
{
return $this->hasMany('App\MyFollow','user_id','followable_id');
}
User.php(model)
public function getIsFollowingAttribute()
{
return MyFollow::where('followable_id',$this->attributes['id'])->where('user_id',Auth()->user()->id)->count() > 0 ? true : false;
}
public function follow()
{
return $this->hasMany('App\MyFollow');
}
UserController.php
public function getProfile($user)
{
$users = User::with(['posts.likes' => function($query) {
$query->whereNull('deleted_at');
$query->where('user_id', auth()->user()->id);
}, 'followers','follow.followers'])
->with(['followers' => function($query) {
}])->where('name','=', $user)->get();
$user = $users->map(function(User $myuser){
$myuser['followedByMe'] = $myuser->getIsFollowingAttribute();
return $myuser;
});
if(!$user){
return redirect('404');
}
return view ('profile')->with('user', $user);
}
it works now. :)
I was able to login and get user token using JWT in laravel.However, while tring to get authenticated user (getAuthUser) by passing that token, I get following error:
"SQLSTATE[42S22]: Column not found: 1054 Unknown column '' in 'where
clause' (SQL: select * from user where `` = 12 limit 1)"
AuthenticationController:
<?php
namespace Modules\Authentication\Http\Controllers;
use Illuminate\Http\Request;
use App\Http\Controllers\Controller;
use Illuminate\Support\Facades\Auth;
use App\Http\Requests;
use JWTAuth;
use JWTAuthException;
use Modules\Settings\Entities\Users;
use Modules\Authentication\Http\Requests\Authentication;
class AuthenticationController extends Controller
{
public function __construct()
{
// $this->user = new Users;
$this->guard = \Auth::guard('api');
}
public function login(Authentication $request){
$credentials = $request->only('username', 'password');
try {
// verify the credentials and create a token for the user
$token = JWTAuth::attempt($credentials);
if (! $token = JWTAuth::attempt($credentials)) {
return response()->json(['error' => 'invalid_credentials'], 401);
}
} catch (JWTException $e) {
// something went wrong
return response()->json(['error' => 'could_not_create_token'], 500);
}
// if no errors are encountered we can return a JWT
return response()->json(compact('token'));
}
public function getAuthUser(Request $request){
$user = JWTAuth::user($request->token);
// dd($user);
return response()->json(['result' => $user]);
}
}
Users Model:
namespace Modules\Settings\Entities;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Contracts\Auth\Authenticatable;
use Tymon\JWTAuth\Contracts\JWTSubject;
class Users extends Model implements JWTSubject,Authenticatable{
Protected $table="user";
// protected $primaryKey = 'id';
protected $fillable = ['id','username','password','user_status_type_id','client_id','created_userid'];
protected $hidden = [
'password', 'remember_token',
];
public function user_status(){
return $this->belongsTo('Modules\Settings\Entities\UserStatusType','user_status_type_id');
}
public function user_client(){
return $this->belongsTo('Modules\Settings\Entities\Client','client_id');
}
public function role()
{
return $this->belongsToMany('Modules\Settings\Entities\Role','user_role','user_id','role_type_id');
}
public function getAuthPassword() {
return $this->password;
}
public function getJWTIdentifier() {
return $this->getKey();
}
public function getJWTCustomClaims()
{
return [];
}
public function getAuthIdentifierName(){}
public function getAuthIdentifier(){}
// public function getAuthPassword(){}
public function getRememberToken(){}
public function setRememberToken($value){}
public function getRememberTokenName(){}
}
Route:
Route::group(['middleware' => 'web', 'prefix' => 'api/v1/authentication', 'namespace' => 'Modules\Authentication\Http\Controllers'], function(){
Route::post('auth/login', 'AuthenticationController#login');
// Route::group(['middleware' => 'jwt.auth'], function () {
Route::get('user', 'AuthenticationController#getAuthUser');
// });
});
I am testing it in postman by
GET: ..../api/v1/authentication/user?token={Token}
EDIT:
Now my method for getAuthUser in the controller looks like this:
public function getAuthUser(Request $request){
// $token = JWTAuth::getToken();
// dd($token);
$input = $request->all();
JWTAuth::setToken($input['token']);
// dd($input['token']);
$user = JWTAuth::toUser($input['token']);
// dd($user);
return response()->json(['result' => $user]);
}
and In JWTAuth.php
public function authenticate()
{
// dd($this->getPayload()->get('sub'));
$id = $this->getPayload()->get('sub');
// dd($id);
// dd($this->auth->byId($id));
if (! $this->auth->byId($id)) {
return false;
}
return $this->user();
}
here by doing dd($id), value of id comes but if I try to do dd($this->auth->byId($id)) I get the same error as before.
Try this to retrieve the user instead:
public function getAuthUser()
{
try {
if (! $user = JWTAuth::parseToken()->authenticate()) {
return response()->json(['user_not_found'], 404);
}
} catch (Tymon\JWTAuth\Exceptions\TokenExpiredException $e) {
return response()->json(['token_expired'], $e->getStatusCode());
} catch (Tymon\JWTAuth\Exceptions\TokenInvalidException $e) {
return response()->json(['token_invalid'], $e->getStatusCode());
} catch (Tymon\JWTAuth\Exceptions\JWTException $e) {
return response()->json(['token_absent'], $e->getStatusCode());
}
// the token is valid and we have found the user via the sub claim
return response()->json(['result' => $user]);
}
Taken from docs, Retreiving the Authenticated user from a token
EDIT:
May not make a difference but just looking at your Model again and I would say that it needs to be
class Users extends Authenticatable implements JWTSubject
rather than
class Users extends Model implements JWTSubject,Authenticatable
I'm trying Laravel 5.4 (i usually work with 5.1) and im actually copypasting most of the code, so i dont understand what is the trouble, maybe is because there is a better way to do it but yeah, its been 1 hour and i cant get past this;
Hope you can help me with this..
In case this isn't enough i'll be posting my views and routes. Thank to everyone.
This is my Model:
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class User extends Model
{
protected $fillable = ['user_id', 'user_name', 'user_birthday'];
public static $rules = [
'user_name' => 'required|max:255',
'user_birthday' => 'required'
];
public $timestamps = false;
}
Controller:
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\User;
class UsersController extends Controller
{
public function index()
{
$users = User::with('user_id')->orderBy('user_id', 'ASC')->paginate(10);
return view('admin.users.index')->with("user", $users);
}
public function create()
{
return view('admin.users.create');
}
public function store(Request $request)
{
$users = new User($request->all());
$users->save();
return redirect()->route('admin.users.index');
}
public function show($id)
{
$users = User::find($id);
}
public function edit($id)
{
$users = User::find($id);
return view('admin.users.edit')->with('user', $user);
}
public function update(Request $request, $id)
{
$users = User::find($id);
$users->user_name = $request->user_name;
$users->user_birthday = $request->user_birthday;
$users->save();
return redirect()->route('admin.users.index');
}
public function destroy($id)
{
$users = User::find($id);
$users->delete();
return redirect()->route('admin.users.index');
}
}
Your error is from the following line of code. When you use with on a model is to load children relationships or sub-models. That is why the application is looking for the relationship user_id in the User Model thinking that it's a sub-model of the User model but it's not, so it return an error.
wrong
$users = User::with('user_id')->orderBy('user_id', 'ASC')->paginate(10);
correct
$users = User::orderBy('user_id', 'ASC')->paginate(10);