Craft Element API data output as a hash instead of an array - php

I'm building and API feed using Element API plugin from Craft, and I'd like the data output to be serialized as a hash, but currently it's returning an array, as example bellow:
<?php
namespace Craft;
return [
'endpoints' => [
'event-name/feed.json' => [
'elementType' => ElementType::Entry,
'criteria' => ['section' => 'event1'],
'transformer' => function(EntryModel $entry) {
$speakersList = [];
foreach ($entry->speakersList as $speaker) {
$speakersList[] = [
'name' => $speaker->speakerFullName,
'jobTitle' => $speaker->speakerJobTitle,
'company' => $speaker->speakerCompany,
];
}
return [
'speakers' => $speakersList,
];
},
],
];
And the output:
{
"data": [
{
"speakers": [
{
"name": "John Doe",
"jobTitle": "Marketing",
"company": "Company 1",
},
...
I've tried the serialize options in the documentation, but none seemed to solve the issue.
Currently if I'd like to access the speakers within data I'd have to first access index[0] to be able to get to the speakers key.
Is there a way to get rid of this array level?

Related

PHP: array_map to return specific array of objects

I have a codepen here which shows a large array of objects. From which I would like to extract a specific property and display as shown in the console log, but in PHP.
Unfortunately for me, I'm quite new to PHP and can't seem to figure it out:
My attempt so far:
$suppliersNotInDB = array_map(function ($order) {
if (isset($order->items) && is_array($order->items)) {
return array_map(function ($item) {
return [...$item];
}, $order->items);
}
}, $ordersData);
Which, I understand isn't even remotely close, but I've been at it for hours now. Any help would be appreciated.
The long and short is that I want to perform this filtering and sorting in the backend(Laravel), not the frontend, where there is already too much going on.
Since you are using Laravel, start using Collections.
If I understood correctly what you are trying to do in your Javascript example, this can be done in a one-liner:
$suppliersNotInDB = collect($ordersData)
->pluck('items')
->flatten()
->pluck('supplier')
->unique()
->map(
fn($supplier) => ['name' => $supplier, 'lowercased' => strtolower($supplier)]
)
->values();
This can probably be further refined, just quickly jotted it down to reproduce your result.
The output of this would then be:
=> Illuminate\Support\Collection {#4999
all: [
[
"name" => "Walmart",
"lowercased" => "walmart",
],
[
"name" => "Bestbuy",
"lowercased" => "bestbuy",
],
[
"name" => "TCI",
"lowercased" => "tci",
],
[
"name" => "lkj",
"lowercased" => "lkj",
],
[
"name" => "Thousand Needles",
"lowercased" => "thousand needles",
],
],
}

Get specific value from json response not working

enter image description here
I have the following json response as in the image. I would want to access specific value, like: "ROUMANIE ROVA AROMANIA" but I can't seem to get to it. I tried the following:
$response = json_decode($r->getBody(),true);
foreach($response['ParsedResults'] as $key)
{
foreach($key['TextOverlay']['Lines'] as $bla)
{
echo $bla['LineText'];
echo $bla[0]['LineText'];
}
}
If I only echo one depth, it's working. I searched for a solution but none did the trick. Thanks.
0 is the current index of the first item, $bla contains already the data you're looking for, so doing this directly should work:
echo $bla['LineText'];
Here is how the full code should look like:
$response = [
'ParsedResults' => [
[
'TextOverlay' => [
'Lines' => [
[
'LineText' => 'ROUMANIE ROVA AROMANIA',
'Words' => [
[
'WordText' => 'ROUMANIE',
'OtherData' => 'whatever'
],
[
'WordText' => 'ROVA',
'OtherData' => 'whatever'
],
[
'WordText' => 'AROMANIA',
'OtherData' => 'whatever'
],
]
]
]
]
]
]
];
foreach($response['ParsedResults'] as $key)
{
foreach($key['TextOverlay']['Lines'] as $bla)
{
echo $bla['LineText'];
}
}
Tested here: http://sandbox.onlinephpfunctions.com/code/0577e854eed73dfb33193c391acc37dd81baf982

Firebase PHP Data Submission - arrayValue, mapValue

I am trying to push data to a firestore DB using PHP and the Google apis.
Inside the documentation and examples I have seen around the web, I am able to use mapValue and arrayValue when sending data.
The example I am using is as follows:-
[
"orderName" => [
"stringValue" => "Gbeila Aliu Wahab"
],
"orderLocationName" => [
"stringValue" => "Accra Mall Limited"
],
"orderTotalAmount" => [
"doubleValue" => 150.5
],
"orderDescription" => [
"stringValue" => "Lorem Ipsum is simply dummy text of the printing and typesetting industry"
],
"orderLocationGeoPoints" => [
"geoPointValue" => (object) [
"latitude" => 5.5557,
"longitude" => -0.1963
]
],
"orderStatus" => [
"stringValue" => "NotAssigned"
],
]
This works perfectly fine, but when I attempt to send an object or an array I get the following error returned to me:-
"message": "Invalid JSON payload received. Unknown name \"map_value\" at 'document.fields[0].value': Proto field is not repeating, cannot start list.",
when attempting to map the value using the following code:-
"orderName" => [
"mapValue" => ["Gbeila Aliu Wahab", 123]
]
// or
"orderName" => [
"arrayValue" => [
"first" => [
"stringValue" => "test"
],
"second" => [
"stringValue" => "test123"
]
]
]
I have tried many variations to try to get this to work.
How am I supposed to be using the mapValue and arrayValue I can see a lot of mentions regarding the value option but I cannot see any examples on how to use the.
Any help would be greatly appreciated.
Payload to your array or map you're generating is incorrect as per the documentation. You need to wrap your actual data (to store) under values key, your final array should be:
["orderName" => ["arrayValue" => ["values" => [["stringValue" => "test"], ["stringValue" => "test123"]]]]]
Similarly your mapValue should be
["orderName" => ["mapValue" => ["fields" => ["field1" => ["stringValue" => "Gbeila Aliu Wahab"]]]]]
Also, you can play with other data mapper via this package.

DBIx::Class (Perl ORM) equivalent in PHP

We started our web-based app back in 2012 when Perl was still popular. Now we want to reimplement it in PHP, preferably Laravel. However, I miss the power of DBIx::Class in their default ORM, Eloquent, and the alternative, Doctrine, from reading the docs seems more complicated, but doesn't solve the issue either. What I use DBIx::Class for:
Regenerate model classes from reading the DB structure, preserving any code that has been added to them (should have).
Generate complex queries (incl. nested joins, subqueries) from pure language constructs, no SQL needed (must have).
Code sample:
rows => $rows,
page => $page,
'select' => [
'entity_id',
{ group_concat => [ { distinct => 'pictures.id' } ], -as => 'photos' },
{ '' => [ 'entity.name' ], -as => 'entity_name' },
{ '' => [ 'municipality.name' ], -as => 'municipality_name' },
{ '' => [ 'me.birth_date' ], -as => 'bd' },
{ concat => [ { date_format => [ 'me.birth_date', \$c->config->{dateFormat} ] }, \"' ('", { timestampdiff => [ \'YEAR', 'me.birth_date', \'CURDATE()' ] }, \"')'" ], -as
{ date_format => [ 'me.birth_date', \$c->config->{dateFormat} ], -as => 'bd1' },
{ timestampdiff => [ \'YEAR', 'me.birth_date', \'CURDATE()' ], -as => 'bd2' },
{ '' => [ 'entity_state_type.name' ], -as => 'entity_state_name' },
{ '' => [ 'data_list_item.name' ], -as => 'entity_state_reason_name' },
{ '' => [ 'entity_state.note_text' ], -as => 'entity_state_note' },
{ '' => [ { if => [ 'entity.archived', \"'Yes'", \"''" ] } ], -as => 'entity_archived' },
],
join => {
entity => [ 'municipality', 'pictures', { 'entity_state' => [ 'entity_state_type', 'data_list_item' ] } ],
},
group_by => [ 'entity.id' ],
Subclass the result (row) and resultset classes to add user role-based limiting conditions transparently to the application code (must have, or equivalent).
The call and the resulting query:
$c->model('DB::Person')->all
SELECT * FROM person WHERE owner = <user_id>
...if the user role security settings indicate user should only access his own persons.
The security settings are read from DB on request start and specify which security conditions (separate classes) should apply to which table.
This moves all security away from application code, where mistakes are made most often.
Which PHP library would allow us to implement this?

Filter off some elements away from php object

Not sure if this is a php or cakephp question. I am using cakephp ver3.1.3. I have a cakephp query object $query that look like this when I call debug($query->toArray());
[
(int) 0 => object(App\Model\Entity\Customer) {
'id' => (int) 1,
'username' => 'asd',
'password' => '123',
'fullname' => 'asd',
'email_addr' => 'asd#gmail.com',
'[new]' => false,
'[accessible]' => [
'*' => true
],
'[dirty]' => [],
'[original]' => [],
'[virtual]' => [],
'[errors]' => [],
'[repository]' => 'Customers'
}
]
When I call json_encode($query), it looks like this;
[
{
"id": 1,
"username": "asd",
"password": "123",
"fullname": "asd",
"email_addr": "asd#gmail.com"
}
]
How do I process $query such that when I call json_encode($query), the output will look like this?
[
{
"email_addr": "asd#gmail.com"
}
]
To only receive the field 'email_addr' from the database, modify your query using the method select():
$query->select(['email_addr']);
If you want to remove all other fields after the query already ran, you can just loop over the array and modify the elements:
$simplified = array();
foreach($query as $row) {
$simplified[] = array(
'email_addr' => $row->get('email_addr')
);
}
echo json_encode($simplified);
On a side note, an important warning: Do not, under no circumstance, store passwords in clear text. Read this answer, specifically the section about storing passwords!

Categories