PHP Search for all entries in an array by value - php

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;
}

Related

Show only a specific part of html response in php

I am trying to get tracking information from amazon using provided url
https://www.amazon.co.uk/progress-tracker/package/ref=pe_3187911_189395841_TE_typ?_encoding=UTF8&from=gp&itemId=&orderId=203-2171364-3066749&packageIndex=0&shipmentId=23796758607302
I am getting response using file_get_contents() function in php,
what I want is to show only that part of the response which contains the tracking information as an output of my php script and eliminate/hide all the unnecessary content from file_get_contents() response.
One way to do what you're looking for is use DomDocument to filter out the json data in the source ($file) and then use a recursive function to get the elements you need.
You can set the elements you need using an array, $filter. In this example we've taken a sample of some of the available data, i.e. :
$filter = [
'orderId', 'shortStatus', 'promiseMessage',
'lastTransitionPercentComplete', 'lastReachedMilestone', 'shipmentId',
];
The code
<?php
$filename = 'https://www.amazon.co.uk/progress-tracker/package/ref=pe_3187911_189395841_TE_typ?_encoding=UTF8&from=gp&itemId=&orderId=203-2171364-3066749&packageIndex=0&shipmentId=23796758607302';
$file = file_get_contents($filename);
$trackingData = []; // store for order tracking data
$html = new DOMDocument();
#$html->loadHTML($file);
foreach ($html->getElementsByTagName('script') as $a) {
$data = $a->textContent;
if (stripos($data, 'shortStatus') !== false) {
$trackingData = json_decode($data, true);
break;
}
}
// set the items we need
$filter = [
'orderId', 'shortStatus', 'promiseMessage',
'lastTransitionPercentComplete', 'lastReachedMilestone', 'shipmentId',
];
// invoke recursive function to pick up the data items specified in $filter
$result = getTrackingData($filter, $trackingData);
echo '<pre>';
print_r($result);
echo '</pre>';
function getTrackingData(array $filter, array $data, array &$result = []) {
foreach($data as $key => $value) {
if(is_array($value)) {
getTrackingData($filter, $value, $result);
} else {
foreach($filter as $item) {
if($item === $key) {
$result[$key] = $value;
}
}
}
}
return $result;
}
Output:
Array
(
[orderId] => 203-2171364-3066749
[shortStatus] => IN_TRANSIT
[promiseMessage] => Arriving tomorrow by 9 PM
[lastTransitionPercentComplete] => 92
[lastReachedMilestone] => SHIPPED
[shipmentId] => 23796758607302
)
Try this
<?php
$filename = 'https://www.amazon.co.uk/progress-tracker/package/ref=pe_3187911_189395841_TE_typ?_encoding=UTF8&from=gp&itemId=&orderId=203-2171364-3066749&packageIndex=0&shipmentId=23796758607302';
$file = file_get_contents($filename);
$html = new DOMDocument();
#$html->loadHTML($file);
foreach($html->getElementsByTagName('span') as $a) {
$property=$a->getAttribute('id');
if (strpos($property , "primaryStatus"))
print_r($property);
}
?>
It should show "Arriving tomorrow by 9 PM" status.

Create JSON response from Parsed XML PHP

I am parsing thorugh a eBay API response. I want to deliver this back to a website cleaner and easier to parse with JavaScript. I successfuly Parsed through the XML... but now turning that into JSON to resend back to the client is giving me some headaches.
NOTE: $resp is the response from eBay. It's their full length XML that is successfully parsed with the code below.
For example... $valueName could be Grade. And then I go into the next foreach loop and get the values for this. These values may be 10, 9.5, 9 etc.
Here is my PHP code.
$arrayName = array();
$arrayValue = array();
foreach($resp->aspectHistogramContainer->aspect as $name) {
$nameAspect = $name['name'];
//$arrayName["aspectName"] = $nameAspect;
foreach($name->valueHistogram as $value) {
$valueAspect = $value['valueName'];
//$arrayValue["aspectValue"] = $valueAspect;
}
//array_push($arrayName, $arrayValue);
}
echo json_encode($arrayName);
So, without me trying to create my own JSON, I am getting that I need. I echos results and it was similar to this...
NAME
----- Value
----- Value
----- Value
NAME
----- Value
NAME
etc etc
For a JSON response... Im looking for something like...
[
{
"name": "NAME",
"value": ["value", "value"]
}, {
"name": "name",
"value": ["value", "value"]
}
]
Any help and guidance would be greatly appreciated.
eBay's response is like this (there are A LOT more <aspect> and <valueHistogram>)
<getHistogramsResponse xmlns="http://www.ebay.com/marketplace/search/v1/services">
<ack>Success</ack>
<version>1.13.0</version>
<timestamp>2018-11-07T15:32:20.380Z</timestamp>
<aspectHistogramContainer>
<domainDisplayName>Baseball Cards</domainDisplayName>
<aspect name="Card Manufacturer">
<valueHistogram valueName="Ace Authentic">
<count>19</count>
</valueHistogram>
<valueHistogram valueName="American Caramel">
<count>2024</count>
</valueHistogram>
<valueHistogram valueName="APBA">
<count>10554</count>
</valueHistogram>
<valueHistogram valueName="Bazooka">
<count>8826</count>
</valueHistogram>
<valueHistogram valueName="Be A Player">
<count>17</count>
</valueHistogram>
<valueHistogram valueName="Bell Brand Dodgers">
<count>334</count>
To encode it (and assuming SimpleXML), then it's just a case of building each internal $aspect data array and then adding the values to it. I use (string) to ensure the data is not stored as a SimpleXMLElement, which can cause side effects...
$arrayName = array();
foreach($resp->aspectHistogramContainer->aspect as $name) {
$aspect = [ "name" => (string)$name['name']];
foreach($name->valueHistogram as $value) {
$aspect["value"][] = (string)$value['valueName'];
}
$arrayName[] = $aspect;
}
echo json_encode($arrayName);
with the sample XML, this gives...
[{"name":"Card Manufacturer","value":["Ace Authentic","American Caramel","APBA","Bazooka","Be A Player","Bell Brand Dodgers"]}]
Create one single array $resultArray and store values in it. By maintaining your current code structure with minimal changes, here is the updated code snippet,
$resultArray = array();
$i = 0; // Maintain Array Index value
foreach($resp->aspectHistogramContainer->aspect as $name) {
$resultArray[$i]["aspectName"] = (string)$name['name'];;
foreach($name->valueHistogram as $value) {
$resultArray[$i]["aspectValue"][] = (string)$value['valueName'];
}
$i++; // Increment array index to store next value
}
echo json_encode($resultArray);
$results = array();
// Parse the XML into a keyed array
foreach($resp->aspectHistogramContainer->aspect as $name) {
$nameAspect = (string) $name['name'];
$values = array();
foreach($name->valueHistogram as $value) {
$values[] = (string) $value['valueName'];
}
$results[$nameAspect] = $values;
}
// This keeps things simple - rewrite to the required JSON format
$outputForJSON = array();
foreach ($results as $name => $values) {
$outputForJSON[] = array(
"name" => $name,
"values" => $values
);
}
echo json_encode($outputForJSON);

Arrays from Twitter json

I am trying to convert json feed from Twitter API 1.1 to arrays. What I am trying is
foreach($user))
Main_Array{
Name:
Id:
Array{
Array {
Tweet:
created at:
}
Array {
Tweet:
created at:
}
}
}
}
var_dump(Main_Array()); //unable to get the main array here. Only the last element of array is pulled
Here is what I tried:
$tweets = $connection->get("https://api.twitter.com/1.1/statuses/user_timeline.json?screen_name=".$user."&count=".$notweets);
$status = array();
foreach($tweets as $key) {
$status['text'] = $key ->text;
$status['stamp'] = $key -> created_at;
}
$tweetfeed = array (
'name' => $name,
'id' => $tweetname,
'status' => $status
);
I am only getting the last value for status array.
Also, I want to know if the structure I am using is good or please suggest if this can be better.
Thanks in advance.
You overwrite the previous $status entries every time in your foreach loop. You've to create a new sub-array for each tweet.
Here is a way to do it :
$i = 0;
foreach($tweets as $key) {
$status[$i]['text'] = $key ->text;
$status[$i]['stamp'] = $key -> created_at;
++$i;
}

Get node from php array by one of the fields

I have an array with structure generated like this:
$groups = array();
while ($group = mysql_fetch_array($groups_result)) {
$groups[] = array( 'id' => $group['id'], 'name' => $group['name']);
}
How can I later in the code get the name of the group by its id? For example, I would like a function like:
function get_name_by_id($id, $array);
But I'm looking for some solution which is already implemented in PHP. I know it would be easier to make arrays with array[5] = array('name' => "foo") etc where 5 in this case is id, but in my code there is a lot of arrays already created like i mentioned above and I cannot easily switch it.
$groups = array();
while ($group = mysql_fetch_assoc($groups_result)) {
$groups[$group['id']] = array( 'name' => $group['name']);
}
$name = $groups['beer']['name'];
also please not using fetch_assoc is more efficient than fetch array
function get_name_by_id($id, $data) {
foreach($data as $d) {
if ($d['id'] == $id) {
return $d['name'];
}
}
// return something else, id was not found
}

building an associative array

This is going to be my first time building an associative array. And if anyone can help me I would be grateful.
Basically, I want to loop through a directory of XML files. I want to find out if a certain editor was the editor of this file, and if the query is true, I would like to grab two pieces of information and achieve the result of an associate array with those two pieces of information for every case where the editor's name is found.
So here's what I have got so far:
function getTitleandID($editorName) {
$listofTitlesandIDs = array();
$filename = readDirectory('../editedtranscriptions');
foreach($filename as $file)
{
$xmldoc = simplexml_load_file("../editedtranscriptions/$file");
$xmldoc->registerXPathNamespace("tei", "http://www.tei-c.org/ns/1.0");
if ($editorName == $xmldoc->xpath("//tei:editor[#role='PeerReviewEditor']/text()"))
{
$title = $xmldoc->xpath("//tei:teiHeader/tei:title[1]");
$id = $xmldoc->xpath("//tei:text/tei:body/tei:div/#xml:id[1]");
$listofTitlesandIDs[] = //I don't know what to do here
}
else
{
$listofTitlesandIDs = null;
}
}
return $listofTitlesandIDs
}
This is about where I get stuck. I'd like to be able have $listofTitlesandIDs as an associative array where I could call up the values for two different keys, e.g. $listofTitlesandIDs['title'] and $listofTitlesandIDs[$id]
So that's about it. I'm grateful for any help you have time to provide.
Well I'm sure this is a little clumsy (the result of an amateur) but it has given me the result I want.
function getTitlesandIDs($EditorName) //gets titles and IDs for given author
{
$list = array();
$filename = readDirectory('../editedtranscriptions');
foreach($filename as $file)
{
$xmldoc = simplexml_load_file("../editedtranscriptions/$file");
$xmldoc->registerXPathNamespace("tei", "http://www.tei-c.org/ns/1.0");
$title = $xmldoc->xpath("//tei:teiHeader/tei:fileDesc/tei:titleStmt/tei:title[1]");
$id = $xmldoc->xpath("//tei:text/tei:body/tei:div/#xml:id");
$editorName = $xmldoc->xpath("//tei:editor[#role='PeerReviewEditor']/text()")
if ($editorName[0] == "$EditorName")
{
$result = array("title"=>$title[0], "id"=>$id[0]);
$list[] = $result;
}
}
return $list;
}
With this I can call the function $list = getTitlesandIDs('John Doe') and then access both the title and id in the associative array for each instance. Like so:
foreach ($list as $instance)
{
echo $instance['title'];
echo $instance['id'];
}
Maybe that will help somebody some day -- let me know if you have any advice on making this more elegant.
$listofTitlesandIDs[$id] = $title;
You should loop over the array then using the foreach loop.

Categories