"Trying to get property of non-object" Laravel - laravel

i have some problem...
here is my code..
i can't get what i swrong with my code.....
here is the error
here is my user class
this is the full DashboardController
/**
* '/home' calls this route
*
* #param none
* #return view dashboard
*/
public function index()
{
$this->permission();
$data = [
'pagetitle' => 'Dashboard',
'permission' => Session()->get('permission'),
'name' => Auth::user()->name,
];
return view('dashboard',$data);
}
/**
* Checks if session has permission in it if not they adds to it
*
* #param null
* #return null
*/
private function permission()
{
if (!Session()->has('permission')) {
$permission = User::find(Auth::user()->id)->details;
$permission_arr = [
'department' => $permission->permission_department,
'asset' => $permission->permission_asset,
'users' => $permission->permission_users,
];
Session()->put('permission', $permission_arr);
}
}
}
i have no idea how solve it..
any help would be great..

You get this kind of problem for you are getting only access of details column From your User table . Remove the details from $permission = User::find(Auth::user()->id);
private function permission(){
if (!Session()->has('permission')){
$permission = User::find(Auth::user()->id);
$permission_arr = [
'department' => $permission->permission_department,
'asset' => $permission->permission_asset,
'users' => $permission->permission_users,
];
Session()->put('permission', $permission_arr);
}
}
Note I have only remove the details object from your permission variable

Related

Laravel api resources and LengthAwarePaginator issue

I'm making an API using Eloquent: API Resources.
This is my article Resource:
class Article extends JsonResource
{
/**
* Transform the resource into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'id' => $this->id,
'slug' => $this->slug,
'name' => $this->name,
'comments' => $this->when($this->showComments(), function () {
$comments = config('eblogger.models.comment')::where([
'commentable_type' => get_class($this),
'commentable_id' => $this->id,
'parent_id' => 0,
])->orderBy('created_at', 'desc')->get();
$paginator = makePaginationCollection($comments, route('blog.comments'));
return CommentResource::collection($paginator);
}),
];
}
}
It's an article with comments.
I want to get pagination with my comments, so i call a custom helper
function makePaginationCollection($collection, $path)
{
$request = request();
$page = request('page', 1);
$perPage = config('settings.items_by_pages');
$paginate = new \Illuminate\Pagination\LengthAwarePaginator(
$collection->forPage($page, $perPage),
$collection->count(),
$perPage,
$page,
['path' => $path]
);
return $paginate;
}
Update : this my resource collection
class CommentCollection extends ResourceCollection
{
/**
* Transform the resource collection into an array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function toArray($request)
{
return [
'data' => $this->collection,
];
}
}
but when i inspect the response in the devtools, i see
I tried with CommentCollection class without success.
Do you have an idea?
Thanks
My solution
finally, thanks to #Rwd, i found this solution but I think it is possible to do better:
This is my article Resource:
public function toArray($request)
{
return [
// ...
'comments' => $this->when($this->showComments(), function() {
return new CommentCollection(
$this->comments()
->orderBy('created_at', 'desc')
->paginate(config('settings.items_by_pages'))
->withPath(route('blog.comments'))
);
})
];
}
And this is my resource collection :
public function toArray($request)
{
return [
'data' => $this->collection,
'links' => $this->resource,
'meta' => $this->resource
];
}

How to test a fake file upload to a route that validate the file in Laravel?

I'm trying to write a test unit for the route 'store' in my controller, pass a fake file to be tested too through the validator of my method, but all i got is that the data is not a file :
Illuminate\Foundation\Testing\TestResponse {
+baseResponse: Illuminate\Http\JsonResponse {
#data: "{
"message":"The given data was invalid.",
"errors":{"invoice":["The invoice must be a file."]}
}"
Code :
Test :
$data = factory('App\Domain\X\X')->raw(['creator_id' => $user->id]);
$data['invoice'] = UploadedFile::fake()->create('invoice.xlsx');
$response = $this->json('POST', route('x.store', $data));
Controller :
public function store(XXXRequest $request)
{
...
Request :
class XXXRequest extends FormRequest
{
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'name' => 'required',
'invoice' => 'nullable|file',
];
}
try this:
Test:
$data = factory('App\Domain\X\X')->raw(['creator_id' => $user->id]);
$data['invoice'] = UploadedFile::fake()->create('invoice.xlsx');
$response = $this->json('POST', route('x.store', $data), [
'name' => 'abc',
'invoice' => $data['invoice']
]);
Just create an UploadedFile from a local file and add it to your request:
use Illuminate\Http\UploadedFile;
$filename = public_path('tests/invoice.pdf');
$file = new UploadedFile($filename, 'invoice.pdf', 'application/pdf', filesize($filename), null, true);
$this->post('/', [
'invoice' => $file,
]);
You can read about testing file uploads here or visit official documentation
/**
* Example
*
* #test
*/
public function test_correct_file_uploading(): void
{
// Set fake storage ('local', 's3', etc)
Storage::fake('local');
$response = $this->json('POST', '/path_to_your/controller/method', [
'file' => UploadedFile::fake()->create('invoice.xlsx', 1024)
]);
// Assert response successful
$response->assertSuccessful();
// Assert the file was stored
Storage::disk('local')->assertExists('invoice.xlsx');
}

Controller method not found laravel

Hello i have been using implicit controllers for a hile now but today i am having an issue i just cannot understand, i have the following in my Route.php:
/**
* Purchase
*/
Route::controllers([
'purchase' => 'PurchaseController'
]);
and in my controller i have created this method:
public function postNsano(NsanoRequest $request)
{
$data = [
'code' => $request->code,
'msg' => $request->msg,
'reference' => $request->referencecode
];
if ($request->code == "00")
{
Session::put('nsano_callback_post_data', $data);
return [
'code' => '00',
'msg' => 'success'
];
}
else
{
return [
'code' => '01',
'msg' => 'rollback'
];
}
}
Now for some reason when i try and post to this URL:
sample.com/purchase/nsano
I get this error: "Controller Method Not Found"
Which is odd for me because i can see the method right there.
I took out the $request and just used Input::get() instead and now it works can someone please explain this to me?
This is my request:
class NsanoRequest extends Request {
/**
* Determine if the user is authorized to make this request.
*
* #return bool
*/
public function authorize()
{
return true;
}
/**
* Get the validation rules that apply to the request.
*
* #return array
*/
public function rules()
{
return [
'code' => 'required',
'msg' => 'required',
'reference' => 'required'
];
}
}
Implicit controller routing needs the HTTP verb in the method name:
public function postNsano(NsanoRequest $request)
{
//
}
Your request validates do not correct so it jumps to an url to prompt error but not found.
If you add some parameters like this and than OK.

Authentication failed results in WSOD

I'm using Larave 4.2, and everything works just fine. If I enter the correct credentials I will be taken to the correct URL (the one with auth filter). But the problem I'm currently experiencing is when one of the fields entered is incorrect and the user submits it will show a white screen.
I'm expecting of course that the user will be redirected back to login page with Input and display the error.
I've checked the filters, and quite sure it is still what came with Laravel and didn't change anything.
My routes
<?php
Route::get('login', function()
{
// just a shortcut to redirec to /login into /cms/login : prevents redirect LOOP
return Redirect::route('cms.login');
});
Route::group(array('prefix' => 'cms'), function()
{
Route::get('/', function()
{
if (Auth::guest())
{
return Redirect::route('cms.login');
}
else
{
return Redirect::route('cms.home');
}
});
Route::get('login', array(
'as' => 'cms.login',
'uses' => 'CMSController#login'
));
Route::post('login', array(
'as' => 'cms.postLogin',
'uses' => 'CMSController#userLogin'
));
Route::get('logout', array(
'as' => 'cms.logout',
'uses' => 'CMSController#userLogout'
));
Route::group(array('before' => 'auth'), function()
{
Route::get('home', array(
'as' => 'cms.home',
'uses' => 'CMSController#home'
));
Route::get('my-account', array(
'as' => 'cms.myaccount',
'uses' => 'AccountsController#myAccount'
));
Route::get('my-account/edit', array(
'as' => 'cms.edit-myaccount',
'uses' => 'AccountsController#editMyAccount'
));
Route::resource('accounts', 'AccountsController');
Route::resource('products', 'ProductsController');
Route::resource('news', 'NewsController');
Route::resource('settings', 'SettingsController');
Route::resource('homepage-sliders', 'HomepageSlidersController');
Route::resource('testimonials', 'TestimonialsController');
Route::resource('effects', 'EffectsController');
});
});
User model
<?php
use Illuminate\Auth\UserTrait;
use Illuminate\Auth\UserInterface;
use Illuminate\Auth\Reminders\RemindableTrait;
use Illuminate\Auth\Reminders\RemindableInterface;
class User extends Eloquent implements UserInterface, RemindableInterface {
use UserTrait, RemindableTrait;
/**
* The database table used by the model.
*
* #var string
*/
protected $table = 'users';
/**
* Fillable array
*
*/
protected $fillable = array('email', 'password', 'username', 'position', 'mobile');
/**
* The attributes excluded from the model's JSON form.
*
* #var array
*/
protected $hidden = array('password', 'remember_token');
/**
* Sets the Validation Rules when Logging In
*
* #var array
*/
public static $loginRules = array(
'email' => 'required|email',
'password' => 'required|alpha_dash|min:6'
);
/**
* Sets the Validation Rules creating a User
*
* #var array
*/
public static $rules = array(
'email' => 'required|email|unique:users',
'username' => 'required|min:2|unique:users',
'position' => 'required|',
'mobile-number' => 'required|numeric|digits:11',
'password' => 'required|alpha_dash|min:6|confirmed',
'password_confirmation' => 'required|alpha_dash|min:6'
);
/**
* Sets the Validation Rules updating a User
*
* #var array
*/
public static $updateRules = array(
'username' => 'required|min:2',
'password' => 'required|alpha_dash|min:6|confirmed',
'password_confirmation' => 'required|alpha_dash|min:6'
);
/**
* Defines many-to-many relationship with Module
*
*/
public function permissions()
{
return $this->belongsToMany('Module', 'permissions')->withPivot('add','edit', 'view','delete');
}
/**
* Get the unique identifier for the user.
*
* #return mixed
*/
public function getAuthIdentifier()
{
return $this->getKey();
}
/**
* Get the password for the user.
*
* #return string
*/
public function getAuthPassword()
{
return $this->password;
}
/**
* Get the e-mail address where password reminders are sent.
*
* #return string
*/
public function getReminderEmail()
{
return $this->email;
}
/**
* Gets the Remember Token
*
* #return string $this->remember_token
*/
public function getRememberToken()
{
return $this->remember_token;
}
/**
* Set the Remember Token
*
* #param string $value
*/
public function setRememberToken($value)
{
$this->remember_token = $value;
}
/**
* Get the Remember Token name
*
* #return string 'remember_token'
*/
public function getRememberTokenName()
{
return 'remember_token';
}
/**
* Get the password and Hash it before saving to the database.
*
* #param string $value
*/
public function setPasswordAttribute($value)
{
$this->attributes['password'] = Hash::make($value);
}
/**
* Checks if Guest User input invalid credentials
*
* #param array $credentials
* #return object $validation
*/
public static function loginIsInvalid($credentials)
{
$validation = Validator::make($credentials, self::$loginRules);
if ($validation->fails())
{
return $validation;
}
}
My CMSController
<?php
class CMSController extends BaseController {
/**
* Display the login page.
* GET /cms
*
* #return Response
*/
public function login()
{
return View::make('cms.login');
}
/**
* Accepts the post request for login
* of user in CMS
*
*/
public function userLogin()
{
$user_credentials['email'] = Input::get('email');
$user_credentials['password'] = Input::get('password');
//sets the remember_me variable
if (Input::has('remember'))
{
$remember_me = true;
}
else
{
$remember_me = false;
}
if ($errors = User::loginIsInvalid($user_credentials))
{
return Redirect::route('cms.login')->withInput()->withErrors($errors);
}
if (Auth::attempt(array(
'email' => $user_credentials['email'],
'password' => $user_credentials['password']), $remember_me))
{
return Redirect::route('cms.home');
}
}
/**
* Accepts the post request for logout
* of user in CMS
*
*/
public function userLogout()
{
Session::clear();
Auth::logout();
return Redirect::route('cms.login');
}
/**
* Directs user to home page
*
*/
public function home()
{
return View::make('cms.home');
}
}
Currently in your code there is nothing after Auth::attempt() - so if the Auth fails - it has no where to go.
Just add a return after the Auth::attempt() to make it work
if (Auth::attempt(array(
'email' => $user_credentials['email'],
'password' => $user_credentials['password']), $remember_me))
{
return Redirect::route('cms.home');
}
return Redirect::route('cms.login')->withInput()->withErrors($errors);

Laravel JsonResource: array_merge_recursive(): Argument #2 is not an array

I have a JsonResource of Post that should return a single post. But after joining some other data I get this error: array_merge_recursive(): Argument #2 is not an array.
This does not work:
/**
* Display the specified resource.
*
* #param int $id
* #return \Illuminate\Http\Response
*/
public function show($slug)
{
// $post = Post::findOrFail($id);
$post = Post::where('slug', $slug)->first();
// return single post as resource
return new PostResource($post);
}
When I directly return $posts, I get a json back, almost fine. But it doesnt contain the joined data comment.
Here is the class Post extends JsonResource.
public function toArray($request)
{
// return parent::toArray($request);
$img = '.'.pathinfo('storage/'.$this->image, PATHINFO_EXTENSION);
$imgName = str_replace($img,'', $this->image);
$img = $imgName.'-cropped'.$img;
return [
'id' => $this->id,
'title' => $this->title,
'body' => $this->body,
'excerpt' => $this->excerpt,
'image' => asset('/storage/' . $this->image),
'image_small' => asset('storage/' . $img),
'author_id' => $this->author_id,
'category_id' => $this->category_id,
'seo_title' => $this->seo_title,
'slug' => $this->slug,
'meta_description' => $this->meta_description,
'meta_keywords' => $this->meta_keywords,
'status' => $this->status,
'featured' => $this->featured,
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
'user' => User::find($this->author_id),
'commentCount' => $this->comment->where(['status' => 1, 'id_post' => $this->id])->count(),
];
}
// **Big mistake below here**:
public function with($request)
{
// return [
// 'version' => '1.0.0',
// ];
}
Model:
class Post extends Model
{
public $primary_key = 'id';
public $foreign_key = 'id_post';
public function user()
{
return $this->belongsTo('App\User', 'id_author', 'id');
}
public function comment()
{
return $this->belongsTo('App\Comment', 'id', 'id_post');
}
}
Why do I get a warning about array_merge_recursive()?
I wan't reproduce issue with your code, but - are you sure you included everything? Looking at https://laravel.com/docs/5.6/eloquent-resources#writing-resources it's possible to define additional data data will be returned too like this:
/**
* Get additional data that should be returned with the resource array.
*
* #param \Illuminate\Http\Request $request
* #return array
*/
public function with($request)
{
return [
'meta' => [
'key' => 'value',
],
];
}
So I was able to reproduce the issue when I added to this Post resource class the following method:
public function with($request)
{
return 'test';
}
as you see it's returning just string and not array and then I was getting same error as you did.
But when I didn't have this method implemented at all or when I return just an array, everything is fine.
So to sum up - make sure you don't have with method defined that returns something else than array.

Resources