How does escaping work on DB insert in laravel? - laravel

I have a basic resource, and I'd like to know if I must escape form data or laravel does it for me behind the scenes?
public function store(ProductRequest $request, Product $product)
{
$fields = [
'owner_id' => 1,
'title' => $request -> title,
];
$product -> create($fields);
return view('product');
}
if I pass
';drop table products;
as the title, it is being stored as is, yet I still have the table, how?
in App\Http\Kernel.php I've the default middlewares
laravel -v: 2.0.1

Laravel uses parameter binding in order to protect you against SQL injection out of the box if you use Eloquent.
If you need to use the query builder than you should use this approach to bind parameters passed to the query for SQL injection protection.

Related

Laravel lighthouse paginate without model

Is there a way to use the #paginate directive from lighthouse-php without querying data from a model? Let say, i using a third party library to query data using an api or so.
Fortunately, such a feature has been added very recently: https://github.com/nuwave/lighthouse/pull/2232. This PR added support for returning data in a Paginator from option resolver in #paginator directive.
You can provide your own function that resolves the field by directly returning data in a \Illuminate\Contracts\Pagination\Paginator instance.
This is mutually exclusive with builder and model. Not compatible with scopes and builder arguments such as #eq.
type Query {
posts: [Post!]! #paginate(resolver: "App\\GraphQL\\Queries\\Posts")
}
A custom resolver function may look like the following:
namespace App\GraphQL\Queries;
use Illuminate\Pagination\LengthAwarePaginator;
final class Posts
{
/**
* #param null $root Always null, since this field has no parent.
* #param array{} $args The field arguments passed by the client.
* #param \Nuwave\Lighthouse\Support\Contracts\GraphQLContext $context Shared between all fields.
* #param \GraphQL\Type\Definition\ResolveInfo $resolveInfo Metadata for advanced query resolution.
*/
public function __invoke($root, array $args, GraphQLContext $context, ResolveInfo $resolveInfo): LengthAwarePaginator
{
//...apply your logic
return new LengthAwarePaginator([
[
'id' => 1,
'title' => 'Flying teacup found in solar orbit',
],
[
'id' => 2,
'title' => 'What actually is the difference between cookies and biscuits?',
],
], 2, 15);
}
}
(The docs are currently not getting updated correctly, which is why you probably did not find out about this. I am working on restoring the deployment.)

Populating $attributes with values from the previous model?

I've got a Laravel project (actually a Laravel Nova project) that involves entering a lot of data. To save some time I'd like to pre-fill some of the fields in my form, based on the logged in user's last entry.
I can pre-fill fields via the $attributes variable on my model, called Product, like so:
protected $attributes = [
'category' => 'ABC'
];
And I can do this for more dynamic data in the constructor like so:
function __construct() {
$this->attributes['category'] = Str::random();
parent::__construct();
}
But I'm not quite sure how I'd go about this when I want to retrieve what the user entered last time. For example, I'd like to do this:
function __construct() {
$user = auth()->user()->id;
$last = Product::where('created_by', $user)->latest()->first();
$this->attributes['category'] = $last['category'] ?? null;
}
However that ends up in an infinite loop. Same if I call $this->where('created_by' ...
Is there a way I can set $attributes of a new Product based on the last Product created by the user?
Nova fields have resolveUsing method, so in your case if you want to populate Text field:
Text::make('Category')->resolveUsing(function () {
return optional(auth()->user()->products()->latest()->first())->category;
})
I found the solution in the Nova Defaultable package.
Once you add the necessary traits, you can just add ->defaultLast() to a resource field and it'll default to the last set value. This also works for relationships which is perfect for my use case.

Empty field in view while it has been retrieved with dd Function

I have joined two tables in Clint table controller and Appointment table as below image and dd function showing the data already.
Here is my controller:
and here is result of dd():
but in the view page it's an empty field:
and here is available I am using in the view:
I have seen your controller image and in join statement mistake.
When you join your appointment table to the clients table then you should use foreign keys.
public function show(Client $client) {
abort_if(Gate::denies('client_show'), Response::HTTP_FORBIDDEN, '403 Forbidden');
$client = DB::table('clients') ->join('appoinments', 'clients.id', '=', 'appoinments.clint_id') ->select('clients.*', 'appoinments.start_time', 'appoinments.finish_time') ->get();
return view('admin.clients.show', compact('client'));
}
I assume in the appointment table you have clint_id.
The variable $client that you are passing to your view is from your Route Model Binding. $clients is the result of your query with the join to appointments which provides the fields start_time and finish_time. You are showing us the output of a dd on $clients which includes those fields, but passing $client to your view which most likely does not have such fields.
You could adjust what you are passing to your view to fix this:
return view('admin.clients.show', [
'client' => $clients,
]);
I am not sure what your purpose is with this method though as the route parameter doesn't end up being used. You probably want to be using that route parameter to filter your query. Though this could be a good place to try using relationships instead of directly joining with query builder.
Also, please do not put up pictures of code. Please edit your question and include the code into the question if you can. Thanks.
Laravel 6.x - Docs - Routing - Route Model Binding

Laravel Coding Practice / Most Optimised Method to Store

Laravel documentation says one should store as follows:
public function store(Request $request)
{
// Validate the request...
$flight = new Flight;
$flight->name = $request->name;
$flight->save();
}
However, why not just as follows:
public function store(Request $request)
{
Flight::create($request->all());
}
The above example is quite easy, since it only has one field. But I imagine its rather tedious to do something with many fields and have to assign each one as opposed to just passing the whole $request as in the second example?
First option gives you better control as to what goes into new model. If you store everything from the request then user might inject fields that you don't want to be stored for a new model in your store method.
For example, your flight has column is_top_priority that is declared as fillable in your Flight model, but when creating new flight you want to set only name for you flight (and leave is_top_priority as null or maybe it has default value of 0 in your table). If you write Flight::create($request->all()); then user can inject <input name="is_top_priority" value="1"> and get advantage of your code.
That is why it is not recommended to use fill($request->all()). Use $request->only(...) or assign each needed field manually as provided in your first example.
For example your model have some fields like name, email, password,status and etc.
Request validate name, email and password and if you do this:
Flight::create($request->all());
Client can send with other fields status, but you change status manually. I do this:
Flight::create([
'name' => $request->get('name'),
'email' => $request->get('email'),
'password' => $request->get('password'),
'status' =>config('params.flight.status.not_active'),
]);

User::all show relationship items

I Laravel 5.5 I am returning users information like this...
$users = User::all();
return Response::json(array(
'error' => false,
'response' => $users,
));
I have a belongs to many categories relationship setup and would like to also show all of the categories each user belongs to.
Anyone have an example I can see?
Use the with() method to load categories for each user:
$users = User::with('categories')->get();
If you don't need to load all the columns from the categories table, use select() inside the with() closure. Also, since you're using Laravel 5.5 you could use Resource classes for formatting JSON.

Resources