Problem with update database from API in Laravel PHP - php

I have a database of items, now I need to update the pictures in 10,000 records in the database, I make an API request, I receive an answer, but I just cannot process the answer correctly.
I received result:
{"result":{"items":{"★ StatTrak™ Bowie Knife | Safari Mesh (Battle-Scarred)":{"actions":[{"link":"steam://rungame/730/76561202255233023/+csgo_econ_action_preview%20S%owner_steamid%A%assetid%D751048845621896210","name":"Inspect in Game..."}],"background_color":null,"commodity":false,"descriptions":[{"app_data":"","type":"html","value":"Exterior: Battle-Scarred"},{"app_data":"","color":"#99CCFF","type":"html","value":"This item features StatTrak™ technology, which tracks certain statistics when equipped by its owner."},{"app_data":"","color":"#CF6A32","type":"html","value":"This item tracks Confirmed Kills."},{"app_data":"","type":"html","value":"This full-tang sawback Bowie knife is designed for heavy use in brutal survival situations. It has been spray-painted using mesh fencing and cardboard cutouts as stencils.\n\n<i>A predator is a predator, no matter the environment</i>"}],"icon_url":"-9a81dlWLwJ2UUGcVs_nsVtzdOEdtWwKGZZLQHTxDZ7I56KU0Zwwo4NUX4oFJZEHLbXH5ApeO4YmlhxYQknCRvCo04DEVlxkKgpovbSsLQJfwObaZzRU7dCJlo-cnvLLIKvum25C4Ppli-f-_Yn0nk36-EZrYjz2cNedIVRqMFCE_VO3xOfqgpfutJWfySRi7nRw7Snan0DmhQYMMLIiC3JRKA"
And i need compare the name, and write in database icon_url value.
But always i received error:
Undefined array key "items" in:
foreach ($prices['items'] as $key => $price) {
$newPrices[$key] = $price['icon_url'];
}
My code:
public function update_information()
{
$prices = json_decode(file_get_contents('https://api.hexa.one/market/items/730?key=O2XDN99XN45XY5EN83CEP3ZZ8X5WDRY4'), true);
if (!$prices['result']) {
dd('Error');
}
$newPrices = [];
foreach ($prices['items'] as $key => $price) {
$newPrices[$key] = $price['icon_url'];
}
$totalUpdated = 0;
foreach (AllItem::query()->get() as $itemDB) {
$fullName = $itemDB->market_hash_name;
if( $itemDB->exterior ) {
$fullName = $itemDB->market_hash_name . '(' . $itemDB->exterior . ')';
}
if (!isset($newPrices[$fullName])) {
continue;
}
$itemDB->update(['image' => $newPrices[$fullName]]);
$totalUpdated++;
$itemDB->save();
$totalUpdated++;
}
dd('done. Updated: ' . $totalUpdated);
}
How i can fix it? Hope for your help!

You forgot the result. The items key is in the result.
array:1 [
"result" => array:2 [
"items" => array:17990 [
....
]
"updated" => 1618501391
]
]
So, you have to replace it with:
foreach ($prices['result']['items'] as $key => $price) {
...
}

Related

Dynamically parse multiple json array objects with php

I have a json file as below name "brands.json"
{
"title":"List of brands",
"version" : 1,
"nike": [
{"type":"shoes","size":10,"color":"black"},
{"type":"shirt","size":"S","color":"black"}
],
"converse": [
{"type":"shoes","size":10,"color":"red"},
{"type":"backpack","size":"N/A","color":"red"}
],
"champion": [
{"type":"shoes","size":10,"color":"blue"},
{"type":"pants","size":"M","color":"grey"}
]
}
I looked at some example online and get this piece of code
<?php
$read = file_get_contents("report.json");
$json = json_decode($read, true);
foreach($json as $key => $val){
if(is_array($val)){
echo "$key : <br>";
foreach($key as $k => $v){
echo "$k => $v<br>";
}
}
else {
echo "$key => $val<br>";
}
}
?>
I would be able to print out
title => List of brands
version => 1
nike :
converse :
champion :
But I would like to get the array inside of those brands. I was thinking of having a foreach loop inside the if statement. However, it returns errors
nike : Warning: Invalid argument supplied for foreach().
Some resources suggested to do something like $json->nike as $item => $v but that will be redundant since I also have converse and champion arrays. If someone could direct me to a good resource or provide a code example, it'd be very much appreciated.
Expected table
Nike:
type | size | color
shoes| 10 | black
shirt| S | black
Create function that buffers output and display it
$read = '{
"title":"List of brands",
"version" : 1,
"nike": [
{"type":"shoes","size":10,"color":"black"},
{"type":"shirt","size":"S","color":"black"}
],
"converse": [
{"type":"shoes","size":10,"color":"red"},
{"type":"backpack","size":"N/A","color":"red"}
],
"champion": [
{"type":"shoes","size":10,"color":"blue"},
{"type":"pants","size":"M","color":"grey"}
]
}';
$json = json_decode($read, true);
// this function will run recursively
function display($val){
// create output buffer variable
$output = "";
// check is array or not
if(is_array($val)){
// check is multimensional or not
if(isset($val[0])){
foreach($val as $v){
$output .= "<br/>".display($v);
}
}else{
foreach($val as $k => $v){
$output .= $k." => ".display($v)."<br/>";
}
}
}else{
// append output if it just a value
$output .= $val;
}
return $output;
}
echo display($json);
?>
Preview
https://code.sololearn.com/wkeim4HQO9zP#php

PHP Search for all entries in an array by value

So for like an hour I'am struggling with this...
I'am working with MusicBrainz api, as a result I'am trying to retrieve all releases by an artist, ColdPlay for now (Becouse he have couple releases in diffrent countries).
What I want to do is:
• Search MusicBrainz response array for a duplicate song title.
• For each of the duplicates find the countries with dates that it was released
So the response would look like this:
{
"title": "Parachutes",
"releaseDates": {
"UK": "2010-10-10",
"USA": "2010-10-12",
"AU": "2010-10-20",
"XW": "2010-11-11",
}
}
instead of this: https://hastebin.com/fejazububi.php
I tried using array_filter, foreach etc.. No luck what so ever.
Do someone of you have a suggesstion for this? Thank You!
SOLVED:
Generated response: https://hastebin.com/ubiqasugav.php
Code:
$Data = [];
$ReleasesData = $ArtistData->releases['releases'];
foreach ($ReleasesData as $rel) {
if(!isset($Data[$rel['title']]['releaseDates'][$rel['country']])) {
$Data[$rel['title']]['releaseDates'][$rel['country']] = [
'date' => $rel['date'],
'status' => $rel['status']
];
}
}
return print_r($Data);
Through loop the simple code is:
$titles = array_unique(array_column($myarray, 'title'));
$result = array();
foreach ($titles as $title) {
$releaseDates = array();
foreach ($myarray as $event) {
if ($event['title'] == $title) {
$releaseDates[$event['country']] = $event['date'];
}
}
$data['title'] = $title;
$data['releaseDates'] = $releaseDates;
$result[] = $data;
}

CSV to Output an Array that contains a field with JSON data

Using Laravel 5.2 and I want to import a CSV and store the records in the database. Name, Surname and Contact Number will be core fields and anything else will just be additional data that I want to store as JSON in an additional info field
example
* | name | surname | contact_number | gender | race |"
* | piet | pokol | 0111111111 | male | race |"
will be stored like so:
* ['name'=>'piet','surname'=>'pokol', 'contact_number'=>'0111111111', 'additional_data'=>'{gender:"male", race:"green"}']
My question is,is it possible to combine an array with JSON array like this?
So far I have it working to make a traditional array with this code
foreach ($reader as $index => $row) {
if ($index === 0) {
$headers = $row;
} else {
$data = array_combine($headers, $row);
$array = array_merge($data, ['client_id' => $client_id, 'list_id' => $list_id]);
Customer::create($array);
}
}
But I need to JSON encode all the field that are not core fields and then add them to the array.
Any body have any advice on this?
Check the below code, it might help you. You can use result array to store in database.
<?php
$data = array(
'name'=> "My Name",
'surname'=> 'My Surname',
'contact_number'=> '0987456321',
'age'=> '38',
'gender'=> 'female',
'address'=> 'NewYork, USA',
);
$core = array('name','surname','contact_number');
$result = array();
$additional = array();
foreach($data as $key => $val) {
if(in_array($key, $core)) {
$result[$key] = $val;
} else {
$additional[$key]= $val;
}
}
if(count($additional)) {
$result['additional'] = json_encode($additional);
}
echo "<pre>";
print_r($result);
?>

Echo Mongo Data into categories with single database hit in PHP

I want to print data from a mongodb into categories based on a particular field with a single cursor. I am not extremely adept with php so I'm having trouble executing it.
Here is the code that I got:
$mongo = new MongoClient();
$cursor1 = $mongo->phone->users_new->find(array('step'=>'current'));
$cursor1->sort(array('date_created'=>-1));
$cursor2 = $mongo->phone->users_new->find(array('step'=>'web'));
$cursor2->sort(array('date_created'=>-1));
foreach($cursor1 as $a){
foreach($a as $b=>$c){
$value = $c;
if($b == 'date_created'){
$value = date('m/d/Y', $c->sec);
}
$record[$b] = $value;
}
$result['records']['current'][]= $record;
}
foreach($cursor2 as $a){
foreach($a as $b=>$c){
$value = $c;
if($b == 'date_created'){
$value = date('m/d/Y', $c->sec);
}
$record[$b] = $value;
}
$result['records']['web'][]= $record;
}
header("Content-Type: application/json");
echo '<pre>'.json_encode($result, JSON_PRETTY_PRINT);
Essentially I want the data to print out like this:
{
"records": {
"web": [
{
"name": "bob",
"age": 32
}
],
"current": [
{
"name": "jones",
"age": 72
}
]
}
}
It's not really clear from your code how you expect to get to the end output, and mostly because we have no idea what your documents look like or how your current logic is working to produce this. But I can help you with the single cursor part and general logic.
All you really need here is an $or condition, or better yet an $in operator, which is shorter syntax. Simply select both of your queried values for "step" and then discern between which array you are adding to in your code:
# Single query and better syntax
$cursor = $mongo->phone->users_new->find(array(
'step' => array( '$in' => array( 'current', 'web' ) )
))->sort(array( 'date_created' => -1))
# Basically copying your block of code
foreach ( cursor as $a ) {
foreach( $a as $b=>$c){
$value = $c;
if ( $b == 'date_created' ) {
$value = date('m/d/Y', $c->sec);
}
$record[$b] = $value;
}
# But decide on the array based on content. If not 'current' it's 'web'
if ( $a["step"] == 'current' ) {
$result['records']['current'][]= $record;
} else {
$result['records']['web'][]= $record;
}
}
# The rest of your code
So basically "step" is the field you are selecting on and it will be present in the results. Just ask for "both" terms to be returned with a single query and then logically determine which array to add to.
Hopefully some of those added lines might give you some pointers on how to more efficiently code the rest of what you need to do here as well.

Search in hierarchical data in PHP

Here is the data structure I have (it's simplified for clearlier understanding):
• USA
• Alabama
• Montgomery
• Birmingham
• Arizona
• Phoenix
• Mesa
• Gilbert
• Germany
• West Germany
• Bonn
• Cologne
I need to return all path for given node – i.e.: if user enter Arizona, I need to return USA → Arizona. If enter Birmingham, I need to return USA → Alabama → Birmingham.
Is there in PHP simple way to search in such structures?
If you haven't huge data structure, you can use XML parsing. It's well known and easy to implement. It has desired ability to access parent element.
Here is an simple example:
$xml = <<<XML
<list>
<state name="USA">
<region name="Alabama">
<city name="Montgomery" />
<city name="Birmingham" />
</region>
<region name="Arizona">
<city name="Phoenix" />
<city name="Mesa" />
<city name="Gilbert" />
</region>
</state>
<state name="Germany">
<region name="West Germany">
<city name="Bonn" />
<city name="Cologne" />
</region>
</state>
</list>
XML;
$doc = new \DOMDocument;
$doc->preserveWhiteSpace = false;
$doc->loadXML($xml);
$xpath = new \DOMXPath($doc);
// XPath query to match all elements with
// attribute name equals to your searched phrase
$locations = $xpath->query("//*[#name='Cologne']");
function parse($list) {
$response = [];
foreach ($list as $node) {
$response[] = $node->attributes->getNamedItem('name')->nodeValue;
$parentNode = $node->parentNode;
// traverse up to root element
// root element has no attributes
// feel free to use any other condition, such as checking to element's name
while ($parentNode->hasAttributes()) {
$response[] = $parentNode->attributes->getNamedItem('name')->nodeValue;
$parentNode = $parentNode->parentNode;
}
}
return $response;
}
$parsedLocations = array_reverse(parse($locations));
echo implode(' → ', $parsedLocations), PHP_EOL;
Here is a possible strategy that builds up the path piece by piece: you start from the first level of the array and you check whether the searc term equals the key. If not, you check the value and otherwise if the value is an array (is_array()) you repeat the search recursively by using a prefix.
The data set:
$str = array(
"USA" => array(
"Alabama" => array(
"Montgomery",
"Birmingham"
),
"Arizona" => array(
"Phoenix",
"",
"Gilbert"
),
"West Germany" => array(
"Bonn",
"",
"Cologne"
)
),
"Germany" => array(
"West Germany" => array(
"Bonn",
"Mesa",
"Cologne"
)
)
);
The function:
function getPath($haystack, $needle, $prefix=""){
$path = "";
foreach($haystack as $key=>$value){
if($path!="")break;
if($key===$needle){
return $prefix.$key;
break;
}
elseif($value===$needle) {
return $prefix.$value;
break;
}
elseif(is_array($value)) {
$path.=getPath($value,$needle,$prefix.$key."=>");
}
}
return $path;
}
a test:
echo getPath($str,"Mesa");
In case of duplicates you will get the first result. If the search term is not found, you get an empty string.
Since "data structure" is very vague, and your only hint is that you're using PHP, I will assume that your "data structure" means the following:
[
'USA' =>
[
'Alabama' =>
[
'Montgomery',
'Birmingham'
],
'Arizona' =>
[
'Phoenix',
'Mesa',
'Gilbert'
]
],
'Germany' =>
[
'West Germany' =>
[
'Bonn',
'Cologne'
]
]
]
And I assume that you want your result in the form
['USA', 'Alabama', 'Birmingham']
If this is not the case, please inform us about how your data is actually available and how you want your result.
Is there in PHP simple way to search in such structures?
That depends on your definition of "simple".
For me, a solution that fits into a single function is "simple".
However, there is no out-of-the-box solution for this that you can use in a one-liner.
If you only need to find the "leafs", you could use a RecursiveIteratorIterator over a RecursiveArrayIterator as in this StackOverflow question.
But since you need to find intermediary keys too, that it not really an option.
The same goes for array_walk_recursive.
You could probably use ArrayIterator or array_walk, but in this example they can't really do anything a foreach loop can't, besides complicate things.
So I'd just go with a foreach loop:
function findMyThing($needle, $haystack) // Keep argument order from PHP array functions
{
// We need to set up a stack array + a while loop to avoid recursive functions for those are evil.
// Recursive functions would also complicate things further in regard of returning.
$stack =
[
[
'prefix' => [],
'value' => $haystack
]
];
// As long as there's still something there, don't stop
while(count($stack) > 0)
{
// Copy the current stack and create a new, empty one
$currentStack = $stack;
$stack = [];
// Work the stack
for($i = 0; $i < count($currentStack); $i++)
{
// Iterate over the actual array
foreach($currentStack[$i]['value'] as $key => $value)
{
// If the value is an array, then
// 1. the key is a string (so we need to match against it)
// 2. we might have to go deeper
if(is_array($value))
{
// We need to build the current prefix list regardless of what we're gonna do below
$prefix = $currentStack[$i]['prefix'];
$prefix[] = $key;
// If the current key, is the one we're looking for, heureka!
if($key == $needle)
{
return $prefix;
}
// Otherwise, push prefix & value onto the stack for the next loop to pick up
else
{
$stack[] =
[
'prefix' => $prefix,
'value' => $value
];
}
}
// If the value is NOT an array, then
// 1. the key is an integer, so we DO NOT want to match against it
// 2. we need to match against the value itself
elseif($value == $needle)
{
// This time append $value, not $key
$prefix = $currentStack[$i]['prefix'];
$prefix[] = $value;
return $prefix;
}
}
}
}
// At this point we searched the entire array and didn't find anything, so we return an empty array
return [];
}
Then just use it like
$path = findMyThing('Alabama', $array);
#Siguza
avoid recursive functions for those are evil
Recursion is not evil (or eval) and works well with stacks to
function df($v,array &$in,array &$stack,$search) {
$stack[] = $v;
if ( $v == $search ) {
return [true,$stack];
}
if ( is_array($in) ) {
foreach ($in as $vv => $k) {
if ( is_array($k) ) {
$r = df($vv, $k, $stack, $search);
if ($r[0]) {
return $r;
}
}
else if ($k == $search) {
$stack[] = $k;
return [true,$stack];
}
}
}
array_pop($stack);
return [false,null];
}
Usage:
$s = [];
$r = df('',$in,$s,'Bonn');
print_r($r);
$s = [];
$r = df('',$in,$s,'West Germany');
print_r($r);
$s = [];
$r = df('',$in,$s,'NtFound');
print_r($r);
Output:
Array
(
[0] => 1
[1] => Array
(
[0] =>
[1] => Germany
[2] => West Germany
[3] => Bonn
)
)
Array
(
[0] => 1
[1] => Array
(
[0] =>
[1] => Germany
[2] => West Germany
)
)
Array
(
[0] =>
[1] =>
)
According to you data structure.
$data['USA'] = ['Alabama' => ['Montgomery','Birmingham'],'Arizona' => ['Phoenix','Mesa','Gilbert']];
$data['Germany'] = ['West Germany' => ['Bonn','Cologne']];
function getHierarchy($location, $data){
$totalCountries = count($data);
//Get Array Keys of rows eg countries.
$keys = array_keys($data);
$hierarchy= [];
//Loop Through Countries
for($i = 0; $i < $totalCountries; $i++){
//If we have found the country then return it.
if($location == $keys[$i]) return [$keys[$i]];
$hierarchy[] = $keys[$i];
foreach($data[$keys[$i]] as $city => $places){
// if we have found the city then return it with country.
if($city == $location){
$hierarchy[] = $city;
return $hierarchy;
}
// if we have found the place in our places array then return it with country -> city -> place.
if(in_array($location, $places)){
$hierarchy[] = $city;
$hierarchy[] = $location;
return $hierarchy;
}
}
// Reset Hirarcy if we do not found our location in previous country.
$hierarchy = [];
}
}
$found = getHierarchy('Birmingham', $data);
if($found){
echo implode(' -> ', $found);
// Output will be USA -> Alabama -> Birmingham
}
It can only find only one country city and places and if any location is found then it will break the whole function and return the first location with city and place.
Here is more improved version which can find multiple locations as well.
https://gist.github.com/touqeershafi/bf89351f3b226aae1a29
Hope it helps you.

Categories