I've just inherited a project in Laravel and it's using Dingo API.
The API is returning strings like Federaci\u00f3ninstead of FederaciĆ³n.
All strings are correctly UTF-8 encoded in the database, so the problem is in the server.
The controller is returning $this->response->paginator($articles, new ArticlesCollectionTransformer); and inside ArticlesCollectionTransformer I placed a var_dump for the strings I have issues with and they are correctly encoded there.
Where else should I look? What am I missing?
Controller:
public function index(Request $request)
{
$limit = (0 === (int)$request->limit || $request->limit > self::PER_PAGE) ? self::PER_PAGE : $request->limit;
$articles = Article::with('author', 'category')
->approved()
->orderBy('published_at', 'desc')
->orderBy('featured', 'desc')
->paginate($limit);
return $this->
response->
paginator($articles, new ArticlesCollectionTransformer)->
// also tried:
// withHeader('Content-type', 'application/json; charset=utf-8');
}
Transformer
class ArticlesCollectionTransformer extends TransformerAbstract
{
public function transform (Article $article)
{
// var_dump($article->title) ==> is correctly encoded
return [
'id' => (int) $article->id,
'category' => $article->category->name,
'author' => $article->author->name ?? ArticleAuthor::DEFAULT_AUTHOR_FOR_NEW_ARTICLES,
'display_order' => (int) $article->display_order,
'title' => $article->title,
'featured' => (bool) $article->featured,
'viewed_times' => (int) $article->viewed_times,
'last_update' => $article->updated_at->timestamp,
];
}
}
More info:
Laravel: 5.2.*
dingo/api: 1.0.x#dev
Related
Hi I'm saving information from blade. The form goes to store function. After saving data I have to send push info using GCM. But this function can not return to view. How can solve this?
public function store(Request $request)
{
$request->validate([
'title_uz' => 'required',
'desc_uz' => 'required',
'url_uz' => 'required',
'company_id' => 'required',
]);
News::create($request->all());
$this->versionUpdate();
$this->sendpush($request);
}
And next function
public function sendpush (Request $request)
{
$fcmUrl = 'https://fcm.googleapis.com/fcm/send';
$notification = [
'title' => $request->title_uz,
'text' => $request->desc_uz,
];
***** here is some functions *******
$result = curl_exec($ch);
curl_close($ch);
$result_to = json_decode($result);
if ($result_to === null) {
return redirect()->route('news.index')
->with('success','DIQQAT!!! Yangilik qo`shildi ammo push-xabar yuborilmadidi.');
}
else {
return redirect()->route('news.index')
->with('success','Yangilik qo`shildi va push-xabar muvoffaqiyatli yuborildi.');
}
}
$result_to returns value but the browser holds at blank screen. It seems the store function holds at the end.
Try this line return $this->sendpush($request);instead of this $this->sendpush($request);
you have redirect from this method so you can try like these
$result_to = $this->sendpush($request);;
if ($result_to === null) {
return redirect()->route('news.index')
->with('success','DIQQAT!!! Yangilik qo`shildi ammo push-xabar yuborilmadidi.');
}
else {
return redirect()->route('news.index')
->with('success','Yangilik qo`shildi va push-xabar muvoffaqiyatli yuborildi.');
}
the user id is existed Before doing create. so it causes an error in the first one.
I made it the other way. the second one below works correctly.
I would like to know why the first one is wrong and it's gone.
//Error
public function store(ContactRequest $request)
{
$request->user_id = $request->user()->id;
Log::debug($request->user()->id);
Log::debug($request);
Contact::create($request->all());
}
//OK
public function store(ContactRequest $request,Contact $contact)
{
$request->user_id = $request->user()->id;
$contact->title = $request->title;
$contact->body = $request->body;
$contact->user_id = $request->user()->id;
$contact->save();
}
the log of the first one is here.
What happened to the user_id!?
[2020-05-30 15:59:10] local.DEBUG: 59
[2020-05-30 15:59:10] local.DEBUG: array (
'_token' => 'gGWuxW6C2JRSCYDuCAC9HauynGclKQEQB7qUh6Rw',
'title' => 'TITLE',
'body' => 'MESSAGE',
'action' => 'SEND',
)
Contact is model class.
ContactRequest is here.
class ContactRequest extends FormRequest
{
public function authorize()
{
return true;
}
public function rules()
{
return [
'title' => 'required|max:100',
'body' => 'required|max:1000'
];
}
public function attributes() {
return [
'title' => 'title',
'body' => 'CONTENTS'
];
}
}
You will have to use $request->merge(['user_id'=>$request->user()->id]).
Another tips is that you can simply use Auth::user()->id which also return the user id of current user.
What if you do this:
Auth::user() - >contact($request->all()) - >save() ;
Or also as an experiment:
$contact = new Contact($request->all()) ;
$contact->user_id = Auth::user() - >id;
$contact->save() ;
Actually the second snippet will surely work. The first one I did not test though it looks nice. :)
In laravel 6 app I have collection defined as :
class PermissionCollection extends ResourceCollection
{
public static $wrap = 'permissions';
public function toArray($request)
{
return $this->collection->transform(function($permission){
return [
'id' => $permission->id,
'name' => $permission->name,
'is_checked' => !empty($permission->is_checked) ? $permission->is_checked : null,
'guard_name' => $permission->guard_name,
'created_at' => $permission->created_at,
];
});
}
}
I use it in a control, like :
$permissions = $user->permissions->all();
$userPermissionLabels= Permission
::get()
->map(function ($item) use($permissions) {
$is_checked= false;
foreach( $permissions as $nextPermission ) {
if($nextPermission->permission_id === $item->id) {
$is_checked= true;
break;
}
}
return [ 'id'=> $item->id, 'name'=> $item->name, 'is_checked' => $is_checked];
})
->all();
return (new PermissionCollection($userPermissionLabels));
and I got error :
Trying to get property 'id' of non-object
Looks like the reason is that collection->map returnes array of data, not objects.
If there is a way to fix it without creating new collection(using array) ?
MODIFIED :
I logged loging in my collection,
public function toArray($request)
{
return $this->collection->transform(function($permission){
\Log::info(' PermissionCollection $permission');
\Log::info($permission);
return [
'id' => $permission->id,
'name' => $permission->name,
'is_checked' => !empty($permission->is_checked) ? $permission->is_checked : null,
'guard_name' => $permission->guard_name,
'created_at' => $permission->created_at,
];
});
}
and I see in logs:
PermissionCollection $permission
array (
'id' => 1,
'name' => 'App admin',
'is_checked' => false,
)
local.ERROR: Trying to get property 'id' of non-object
The value is valid array, not null.
I mean I have already use this collenction in other part of the app, can I use it without creating a new one...
I think you get this error because you CollectionResource need to object of the Permission model, but in your case it is trying to get id from an array, after map function. Try to extend your model instead of returning an new array
Good Night,I'm using google api sheets with laravel following this tutorial
https://github.com/kawax/laravel-google-sheets
when I try to do the first example
use Sheets;
$user = $request->user();
$token = [
'access_token' => $user->access_token,
'refresh_token' => $user->refresh_token,
'expires_in' => $user->expires_in,
'created' => $user->updated_at->getTimestamp(),
];
// all() returns array
$values = Sheets::setAccessToken($token)->spreadsheet('spreadsheetId')->sheet('Sheet 1')->all();
my code:
namespace App\Http\Controllers;
use Sheets;
use Google;
class PlanilhaController extends Controller
{
public function index(Request $request)
{
$user = $request->user();
$token = [
'access_token' => $user->access_token,
'refresh_token'=> $user->refresh_token,
'expires_in'=> $user->expires_in,
'created' => $user->updated_at->getTimestamp(),
];
$values = Sheets::setAccessToken($token)
>spreadsheet('spreadsheetId')->sheet('Sheet 1')->all();
// all() returns array
return view('planilha', compact('values'));
}
error: Trying to get property 'access_token' of non-object
which is not requested, but I do not know how to solve it
Actually you do not need that token, what you need is to set up your .env so it has following key
GOOGLE_APPLICATION_NAME=
GOOGLE_CLIENT_ID=
GOOGLE_CLIENT_SECRET=
GOOGLE_REDIRECT=
GOOGLE_DEVELOPER_KEY=
GOOGLE_SERVICE_ENABLED=
GOOGLE_SERVICE_ACCOUNT_JSON_LOCATION=
POST_SPREADSHEET_ID=
POST_SHEET_ID=
then in your controller
$sheets = Sheets::spreadsheet(config('sheets.post_spreadsheet_id'))
->sheet(config('sheets.post_sheet_id'))
->get();
$header = $sheets->pull(0);
$posts = Sheets::collection($header, $sheets);
$posts = $posts->reverse()->take(10);
then in your config file write this
'post_spreadsheet_id' => env('POST_SPREADSHEET_ID'),
'post_sheet_id' => env('POST_SHEET_ID'),
I'm building a small application on laravel 5.5 where I'm getting a list of multiple users with there information, from the forms as below format:
{
"name":"Test",
"description":"Test the description",
"users":[
{
"value":"XYZabc123",
"name":"Nitish Kumar",
"email":"nitishkumar#noeticitservices.com"
},
{
"value":"MFnjMdNz2DIzMJJS",
"name":"Rajesh Kumar Sinha",
"email":"rajesh#noeticitservices.com"
}
]
}
I just want to get the value key form the users array via laravel collection something like this:
$userIds = $request->users->pluck('value');
so that I can put them into query:
$user = User::all()->whereIn('unique_id', $userIds);
May be I'm doing most of the things wrong but my main motive is to use laravel collection or helper functions and make a cleaner code for this:
$teamData['name'] = $request->name;
$teamData['description'] = $request->description;
$teamData['unique_id'] = str_random();
$users = $request->users;
$team = Team::create($teamData);
if($team)
{
$userIds = [];
foreach ($users as $user)
{
$getUser = User::where('unique_id', $user['value'])->get()->first();
$userIds [] = $getUser->id;
}
$team->users()->attach($userIds);
return response()->json(['message' => 'Created Successfully'], 200);
}
return response()->json(['message' => 'Something went wrong'], 500);
I'm still learning collections, any suggestions is appreciated. Thanks
Data that come from $request (form) isn't a collection. It's an array. If you need it to be collection, you should convert it to collection first.
PS. If you have multiple DB actions in single method, It's good to have DB transaction.
\DB::transaction(function () use ($request) {
// convert it to collection
$users = collect($request->users);
$team = Team::create([
'name' => $request->name,
'description' => $request->description,
'unique_id' => str_random(),
]);
$team->users()->attach($users->pluck('value')->toArray());
});
// HTTP Created is 201 not 200
return response()->json(['message' => 'Created Successfully'], 201);
or you'll need something like this:
return \DB::transaction(function () use ($request) {
$users = collect($request->users);
$team = Team::create([
'name' => $request->name,
'description' => $request->description,
'unique_id' => str_random(),
]);
$team->users()->attach($users->pluck('value')->toArray());
return response()->json([
'message' => 'Created Successfully',
'data' => $team,
], 201);
});
I just want to get the value key form the users array via laravel collection
Just use map then:
$userIds = $request->users->map(function($user) {
return $user->value; // or $user['value'] ? not sure if this is an array
});
Edit:
if $request->users is not a collection, make it one before calling map:
$users = collect($request->users);
$userIds = $users->map(function($user) {
return $user->value; // or $user['value'] ? not sure if this is an array
});