I am trying to add an asset link to a nested properties value using Eloquents API resource function:
public function toArray($request)
{
return [
'id' => $this->id,
'title' => $this->title,
'image' => isset($this->image) ? asset('storage/'.$this->image) : null,
'properties' => $this->properties,
'created_at' => (string) $this->created_at,
'updated_at' => (string) $this->updated_at
];
}
The following works fine for the image value, but I am using a nested properties['pdf'] file that I need to add asset('storage/') parameter to so it outputs the full URL.
How am I able to pass isset($this->properties['pdf']) ? asset('storage/'.$this->properties['pdf']) : null into the properties value? I still need the pdf value to return inside the properties value.
Note: There are other values inside properties but they are dynamic based on the data returned.
Probably not the cleanest idea but this worked:
$properties = $this->properties;
if(isset($this->properties['pdf']) && $this->properties['pdf'] != null){
$properties['pdf'] = asset('storage/'.$this->properties['pdf']);
}
Then I applied $properties to the return.
Related
Something good with laravel is "$casts" attribute. Exemple with dates :
protected $casts = [
'date_rec' => 'datetime:Y-m-d',
'date_liv' => 'datetime:Y-m-d',
];
It works well if you return result of eloquent's query.
But if you don't want return full object with all relations it's the hell.
Examples :
protected $casts = [
'date_rec' => 'datetime:Y-m-d',
'date_liv' => 'datetime:Y-m-d',
];
public function asListItem()
{
return [
"try_1" => $this->date_rec, // return : "2021-10-19T22:00:00.000000Z"
"try_2" => $this->date_rec->format('Y-m-d'), // return : "2021-10-19" or error/crash if date is null
"try_3" => substr($this->date_rec ?? '', 0, 10), // work always but boring
"try_4" => json_encode($this->date_rec) // infinite loading and then error timeout
];
}
Is it possible to define how I want laravel parse date globally at serialization ?
Thx
You can use Carbon::setToStringFormat('your format'); in your provider to set a default string format
I'm learning Laravel and have created a public endpoint where I want to output only certain information of some comments if a user is not authenticated from a GET request.
I have managed to filter out the comments based on whether or not they are approved. I now want to filter out the data that is returned. I have attached a screenshot of what is currently returned.
Ideally, I only want to return the id, name and the body in the json. How can I go about this? I tried the pluck() method which did not give the desired results. Any pointers would be greatly appreciated
public function index(Request $request)
{
if (Auth::guard('api')->check()) {
return Comment::all();
} else {
$comments = Comment::where('approved', 1)->get();
return $comments->pluck('id','name','body');
}
}
To select the particular columns, you can pass columns name to get as
$comments = Comment::where('approved', 1) -> get(['id','name','body']);
You can use a transformer to map the incoming data to a sensible output based on the auth state. The following example comes from the Fractal lib:
<?php
use Acme\Model\Book;
use League\Fractal;
$books = Book::all();
$resource = new Fractal\Resource\Collection($books, function(Book $book) {
return [
'id' => (int) $book->id,
'title' => $book->title,
'year' => $book->yr,
'author' => [
'name' => $book->author_name,
'email' => $book->author_email,
],
'links' => [
[
'rel' => 'self',
'uri' => '/books/'.$book->id,
]
]
];
});
Ideally, you would create 2 classes that extend from Transformer and pass the correct one to the output.
If you want to pass the result as json respose
$comments = Comment::where('approved', 1)->pluck('id','name','body')->toArray();
return Response::json($comments);
If you want to pass the result as to blade
$comments = Comment::where('approved', 1)->pluck('id','name','body')->toArray();
return view('your_blade_name')->with('comments',$comments);
I have difficult to build and return a nested json. I want obtain the information from two differents table joined with an id.
This is my situation:
With this method on my controller:
public function eventOccList(EventOccurrence $eventOccurrence){
return new EventOccurrenceResourceCollection(EventOccurrence::all());
}
and with the mapping in the class EventOccurrenceResource
return [
'type' => 'event',
'id' => (string) $this->id,
'name' => $this->name,
'description' => $this->description,
'location_id' => $this->location_id
];
I obtain this JSON:
{"data":[{"type":"event","id":"1","name":"event_1","description":"event blabla","location_id":11}
If I want to obtain all the informations about the table "location" with the id "location_id" and show in the same json, what is the best way to retrieved this data?
Thanks !
I assume your Event Model have a location relationship :
public function location{
return $this->belongsTo(Event::class);
}
you can do this once you have your event in a Controller :
$event->load('location');
return $event->toJson();
You can then hide or append any attribute you want :)
I am using fractal for my small project, here is my code:
public function transform(Series $series) {
return [
'id' => $series->id,
'title' => $series->title,
'url' => $series->url,
'description' => $series->description,
'thumbnail_hd' => $series->thumbnail_hd,
'thumbnail_wide' => $series->thumbnail_wide,
'views' => $series->views
];
}
I would like to make views (which is an int) optional and not return the views unless requested - since this field is based on a relationship and will increase the processing time.
I would like to use it as relationships (so i can include particular fields whenever I need to):
// in transformer
public function includeUser(Series $series) {
return $this->item($series->user, new UserTransformer);
}
// in controller
return fractal()
->item($series)
->parseIncludes(['user'])
->transformWith(new SeriesTransformer)
->toArray();
But just for an integer instead of a whole array of data. Is it possible using Fractal?
What you can do is the following
public function transform(Series $series) {
$return = [
'id' => $series->id,
'title' => $series->title,
'url' => $series->url,
'description' => $series->description,
'thumbnail_hd' => $series->thumbnail_hd,
'thumbnail_wide' => $series->thumbnail_wide,
];
if ($series->views > 0) {
$return['views'] = (int) $series->views;
}
return $return;
}
I wouldn't suggest doing this though. I would usually just return views as 0.
If you're worried about your DB performance, your app is going to have to count the views anyway to know if they're greater than 0.
If you worried about client side performance, this is not going to matter with a single key value pair.
I've got error
Object of class Closure could not be converted to string
on this code
'class' => \dosamigos\grid\EditableColumn::className(),
'attribute' => 'remidi3',
'url' => function($data){return ['update?id=remidi3&dataid'.$data->id];},
'type' => 'text',
'editableOptions' => [
'mode' => 'inline',
]
even I've try to change
'url' => function($data){return ['update?id=remidi3&dataid'.$data->id];}
into
'url' => function($data){return 'update?id=remidi3&dataid'.$data->id;},
I need to display id in the URL of editable grid, somebody can help me?
According to source code and PHPDoc, you can't specify closure here.
PHPDoc says:
/**
* #var string the url to post
*/
public $url;
Usage in source code:
if ($this->url === null) {
throw new InvalidConfigException("'Url' property must be specified.");
}
...
$url = (array) $this->url;
$this->options['data-url'] = Url::to($url);
As you can see, it's converted to array and then processed by Url::to(), so the valid types are string and array.
I don't think you need to specify id in url, it should be taken automatically depending on row you working with.