How to order array of objects by property PHP - php

I have the following array of objects coming from a json. The idea is to sort by the observation property. How can I do this?
My Array from objects
[
[
"id" => "07e17609-2359-4b21-9161-6e10715eb2f1",
"description" => "Digital Account",
"observation" => null
],
[
"id" => "1f9a3695-dafe-46yb-9caa-7a413bedc3c9",
"description" => "Cashback",
"observation" => '1% cashback on all purchases using Méliuz'
],
[
"id" => "0f9a5695-dafe-46fb-9caa-7a418bedc3c9",
"description" => "Google Pay",
"observation" => null
],
];
The desired sort output
[
[
"id" => "1f9a3695-dafe-46yb-9caa-7a413bedc3c9",
"description" => "Cashback",
"observation" => '1% cashback on all purchases using Méliuz'
],
[
"id" => "07e17609-2359-4b21-9161-6e10715eb2f1",
"description" => "Digital Account",
"observation" => null
],
[
"id" => "0f9a5695-dafe-46fb-9caa-7a418bedc3c9",
"description" => "Google Pay",
"observation" => null
],
];
That is, if the observation field is not null, it must come first in the sort
I tried with the usert below, but it didn't work.
usort($this->rewards, fn($a, $b) => strcmp($a->observation, $b->observation));

You can extend your usort callback function as follows:
usort($data->rewards, fn ($a, $b) =>
is_null($a->observation) - is_null($b->observation) ||
strcmp($a->observation, $b->observation)
);
This will force the null values to the end.

Related

Laravel reverse a collection hierarchy

Say I have a collection that looks like this:
$subscriptions = collect([
[
"id" => 1,
"event" => "FormCompleted",
"subscriber" => [
"id" => 2929,
"name" => "Adam",
"email" => "adam#dude.com"
]
],
[
"id" => 3,
"event" => "FormCompleted",
"subscriber" => [
"id" => 1928,
"name" => "Pope",
"email" => "pope#dude.com"
],
],
[
"id" => 4,
"event" => "StatusChanged",
"subscriber" => [
"id" => 2929,
"name" => "Adam",
"email" => "adam#dude.com"
]
]
]);
This shows a list of events with its subscriber. What I want is to re-group this to show a list of subscribers with its events. How do I group these results to get a result like this?
[
[
"id" => 2929,
"name" => "Adam",
"email" => "adam#dude.com",
"subscriptions" => [
[
"id" => 1,
"event" => "FormCompleted"
],
[
"id" => 4,
"event" => "StatusChanged"
],
]
],
[
"id" => 1928,
"name" => "Pope",
"email" => "pope#dude.com",
"subscriptions" => [
[
"id" => 3,
"event" => "FormCompleted"
]
]
]
]
Here is my code... which works, but it is very messy and I feel like there is a better way to do it...
$subscribers = $subscriptions->groupBy('subscriber.id')
->map(function($group) {
$subscriber = $group[0]->subscriber;
$subscriber['subscriptions'] = $group->map(function($subscription) {
unset($subscription['subscriber']);
return $subscription;
});
return $subscriber;
})->values();
I think like that this should return you all subscribers who have groups, so guarantees return not empty subscribers with events
More details you can read this in documention
return Subscriber::has('groups')->get()->groupBy('id');

Storing key/value pairs globally in Laravel 8.x

I need to access the NAME of the languages and their respective ID from a global array. I have added PHP files under the config directory and added the following code. Is it the right way to do it? How can I access it in my controller file?
return [
'Language' => [
array(
"English" => array (
"name" => 'English',
"value" => 101
),
"Turkish" => array (
"name" => 'Turkish',
"value" => 102
))
]
];
Create a file config/language.php with the contents
///config/language.php
return [
"English" => [
"name" => 'English',
"value" => 101
],
"Turkish" => [
"name" => 100,
"value" => 101
]
];
Then anywhere your need you can access like
$lang = config('language.Turkish');
$lang['name'] //will be 100
$lang['value'] //will be 101

search for a value array in array in php

In my program i have arrays in the following format . I need to find whether a value is present in an the array
return [
"affiliates" => [
"name" => 'Affiliates',
"value" => 11
],
"business" => [
"name" => 'Business',
"value" => 12
],
"inquiries" => [
"name" => 'Inquiries',
"value" => 13
],
"students" => [
"name" => 'Students',
"value" => 14
],
"teachers" => [
"name" => 'Teachers',
"value" => 15
],
"Personal" => [
"name" => 'Personal',
"value" => 3
],
];
I am doing the following. I am expecting that the search will find the value(12) which is a business, but It is returning false.
$searchcategoryid = '12';
$key = array_search($searchcategoryid, array_column(config('peopletypes.students'), 'value'));
Please note that config('peopletypes.students')will return the array above mentioned. I am using laravel.
You have some sort of configuration problem, this code prints 1.
<?php
$searchcategoryid = '12';
$key = array_search($searchcategoryid, array_column([
"affiliates" => [
"name" => 'Affiliates',
"value" => 11
],
"business" => [
"name" => 'Business',
"value" => 12
],
"inquiries" => [
"name" => 'Inquiries',
"value" => 13
],
"students" => [
"name" => 'Students',
"value" => 14
],
"teachers" => [
"name" => 'Teachers',
"value" => 15
],
"Personal" => [
"name" => 'Personal',
"value" => 3
],
], 'value'));
echo $key;
Try to make sure that your config function actually returns the array you claim it to.

PHP MongoDB\Client updateOne add new field to existing document array

I'm struggling to update a document and add new elements (fields) into it's existing array without losing the array elements on update.
This is my code which inserts a new document into the collection if it doesn't already exist (upsert):
$updateResult = $collection->findOneAndUpdate(
[
'recording-id' => $out['recording']->id
],
['$set' => [
'release' => [
'id' => $out['release']->id,
'title' => $out['release']->title,
'date' => $out['release']->date,
'country' => $out['release']->country
],
'artist' => [
'id' => $out['artist']->id,
'name' => $out['artist']->name,
],
'recording' => [
'id' => $out['recording']->id,
'title' => $out['recording']->title,
'score' => $out['recording']->score,
'length' => $out['recording']->length,
'release-count' => count($out['recording']->releases),
],
'release-group' => [
'id' => $out['release-group']['id'],
'title' => $out['release-group']['title'],
'first-release-date'=>$out['release-group']['first-release-date'],
'primary-type' => $out['release-group']['primary-type'],
'musicbrainz' => $out['release-group']['musicbrainz'],
'url-rels' => $out['release-group']['url-rels'],
'coverart' => $out['release-group']['coverart']
],
'execution' => [
'firstfind' => $out['execution']->time
]
]
],
['upsert' => true,
'projection' =>
[
'_id' => 0,
'release' => 1,
'artist' => 1,
'recording' => 1,
'release-group' => 1,
'execution' => 1
],
'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER,
]
);
So now I have an existing document in a collection:
{
"_id" : ObjectId("5d1a6aaf5ecc8001ee858f6c"),
"recording-id" : "d0d439f9-5324-4728-8706-2da39adb89c5",
"artist" : {
"id" : "9d97b077-b28d-4ba8-a3d9-c71926e3b2b6",
"name" : "Gordon Lightfoot"
},
"recording" : {
"id" : "d0d439f9-5324-4728-8706-2da39adb89c5",
"title" : "Sundown",
"score" : 100,
"length" : 184000,
"release-count" : 2
},
"release" : {
"id" : "0c008d76-2bc9-44a3-854b-0a08cde89337",
"title" : "All Live",
"date" : "2012-04-24",
"country" : "CA"
},
"release-group" : {
"id" : "0a5d5f33-8e9d-4fa4-b622-a95e4218a3c4",
"title" : "All Live",
"first-release-date" : "2012-04-24",
"primary-type" : "Album",
"musicbrainz" : "https://musicbrainz.org/release-group/0a5d5f33-8e9d-4fa4-b622-a95e4218a3c4",
"url-rels" : "https://musicbrainz.org/ws/2/release-group/0a5d5f33-8e9d-4fa4-b622-a95e4218a3c4?inc=url-rels&fmt=json",
"coverart" : null
}
}
Now, I would like to update this document, and add new fields into the arrays. The new fields are to be added to certain fields.
Here is the code doing that:
$collection = (new MongoDB\Client)->stream->musicbrainz;
$updateResult = $collection->updateOne(
[
'recording-id' => $out['recording']['id']
],
['$addToSet' => [
'artist' => [
'wikiQiD' => $out['artist']['qid'],
'wiki-extract' => $out['artist']['wiki-extract'],
'wiki-pageid' => $out['artist']['pageid'],
],
'release-group' => [
'wikiQiD' => $out['release-group']['qid'],
'wiki-extract' => $out['release-group']['wiki-extract']
]
]
],
[
'upsert' => true,
'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER,
]
);
I've noticed there's "$addToSet" and "$push" commands, and could use assistance with what the difference is between these two commands.
If the field is absent in the document to update, $push adds the array
field with the value as its element.
The $addToSet operator adds a value to an array unless the value is
already present, in which case $addToSet does nothing to that array.
I did some googling, and reading of the MongoDB/Client UpdateOne function, but can't seem to find a way to append these fields to the existing arrays.
The error I'm getting is:
Fatal error: Uncaught MongoDB\Driver\Exception\BulkWriteException: The field 'artist' must be an array but is of type object in document {_id: ObjectId('5d1a6aaf5ecc8001ee858f6c')} in ...
I know the following:
It could be my document, as it's not a proper array that Fatal error is complaining about.
It could be my `findOneAndUpdate' formatting, and I'm not doing that correctly.
It could be both and I have it all wrong from the very start.
Any insight or constructive criticism is appreciated, just refrain from flames, pls.
Here's the working code I finally use to get it do what I want it to.
It's a simple matter of just setting your field names and values and mongo will update the found record replacing it with the array sent to it. No need to push or anything.
function firstFindMongoUpdate($out) {
$collection = (new MongoDB\Client)->stream->musicbrainz;
$updateResult = $collection->findOneAndUpdate(
[
'recording-id' => $out['recording']->id
],
['$set' => [
'query' => $out['query'],
'release' => [
'id' => $out['release']->id,
'title' => $out['release']->title,
'date' => $out['release']->date,
'country' => $out['release']->country,
'label' => $out['release']->label,
],
'artist' => [
'id' => $out['artist']->id,
'name' => $out['artist']->name,
'wiki' => $out['artist']->wiki,
],
'recording' => [
'id' => $out['recording']->id,
'title' => $out['recording']->title, // sometimes contains apostophe ie; Bill‘s Love (option ] key)
'score' => $out['recording']->score,
'length' => $out['recording']->length,
'release-count' => count($out['recording']->releases)
],
'release-group' => [
'id' => $out['release-group']['id'],
'title' => $out['release-group']['title'],
'first-release-date'=>$out['release-group']['first-release-date'],
'primary-type' => $out['release-group']['primary-type'],
'musicbrainz' => $out['release-group']['musicbrainz'],
'url-rels' => $out['release-group']['url-rels'],
'coverart' => $out['release-group']['coverart'],
'wiki' => $out['release-group']['wiki']
],
'execution' => [
'artistQuery' => $out['execution']->artistQuery,
'recordingQuery'=> $out['execution']->recordingQuery,
'time' => $out['execution']->time
]
]
],
['upsert' => true,
'projection' =>
[
'_id' => 1,
'query' => 1,
'release' => 1,
'artist' => 1,
'recording' => 1,
'release-group' => 1,
'execution' => 1
],
'returnDocument' => MongoDB\Operation\FindOneAndUpdate::RETURN_DOCUMENT_AFTER,
]
);

REST API SkypeBot suggested actions

Trying to make REST API skype bot but have a problem with a suggested actions message.
I prepare JSON with code like this:
$message = [
"type" => "message",
"from" => [
"id" => $clientid,
],
"conversation" => [
"id" => $chatid,
],
"recipient" => [
"id" => $chatid,
],
"text" => "Color",
"inputHint" => "expectingInput",
"suggestedActions" => [
"to" => [ $reptoid ],
"actions" => [
[
"type" => "imBack",
"title" => "Blue",
"value" => "Blue"
],
[
"type" => "imBack",
"title" => "Green",
"value" => "Green"
],
],
],
"replyToId" => $replyid
];
And after I send - I get in skype only text, wihout any buttons.
What I'm doing wring?
Based on the Channel Inspector, it seems that Suggested Actions in Skype are only available in the context of Cards.

Categories