WooCommerce REST API - how to get product resized images url? - woocommerce-rest-api

all images in wordpress will auto resize and save in uploads folder like this:
sample_product_image-100x100.png
sample_product_image-150x150.png
sample_product_image-180x113.png
sample_product_image-300x189.png
...
sample_product_image-555x349.png
sample_product_image-600x378.png
sample_product_image.png (original large file)
for faster loading I need smaller size of product image in rest api like this one:
sample_product_image-300x189.png
but woocommerce rest api just send me original largest file (sample_product_image.png):
"images": [
{
"id": 7291,
"date_created": "2018-06-12T03:17:03",
"date_created_gmt": "2018-06-11T13:47:03",
"date_modified": "2018-06-12T03:17:03",
"date_modified_gmt": "2018-06-11T13:47:03",
"src": "http://example.com/wp-content/uploads/2018/06/sample_product_image.png",
"name": "sample_product_image",
"alt": "",
"position": 0
},
how can I get smaller image urls in wc rest api?
btw I found this plugin for wordpress rest api that is not working for woocommerce.

found a solution here.
Just need to add this filter to your theme's function.php
function prepare_product_images($response, $post, $request) {
global $_wp_additional_image_sizes;
if (empty($response->data)) {
return $response;
}
foreach ($response->data['images'] as $key => $image) {
$image_urls = [];
foreach ($_wp_additional_image_sizes as $size => $value) {
$image_info = wp_get_attachment_image_src($image['id'], $size);
$response->data['images'][$key][$size] = $image_info[0];
}
}
return $response;
}
add_filter("woocommerce_rest_prepare_product_object", "prepare_product_images", 10, 3);
Also if you need only 1 special size you can remove second foreach and manually initialize $size to 'thumbnail' , 'medium' , 'medium_large' or 'large'

Related

Icecast/Shoutcast radio stream: extracting now playing info

How do I extract "current track / now playing" info from a shoutcast/icecast radio stream? I tried following solutions:
https://github.com/ghaiklor/icecast-parser
https://code.google.com/archive/p/streamscraper/
Parsing the .xspf file Can't extract metdata from some icecast streams
Analyzing the audio stream in PHP/native Android (get info from streaming radio, Pulling Track Info From an Audio Stream Using PHP, http://www.smackfu.com/stuff/programming/shoutcast.html
All of the methods above work for some radiostations, such as
http://icecast.vrtcdn.be/stubru-high.mp3
However, for a number of icecast/shoutcast streams, all of them fail. Example: http://icecast-qmusic.cdp.triple-it.nl/Qmusic_be_live_64.aac. When analyzing the audio stream itself, the streamTitle is always empty. The xspf file always has an empty title tag. However, I notice other apps and websites do succeed in gathering current track info for this radio station. The homepage of the radio station also contains the current track/playlist info: https://qmusic.be/playlist/qmusic.
I know I could go and write an html scraper that extracts this data, but I only want to use this as a last resort. Besides, I have multiple streams with similar problems and this would not be a generic solution that can be applied to all of them.
So, am I missing something? Is there another general way in which metadata can be extracted from an icecast/shoutcast server? I also tried using the 7.html file or the /stats?sid=1 files, but did not have a lot of luck with these approaches (as in: files not present/invalid urls). Below a php script from one of the hyperlinks that works in some cases. Any help or feedback would be greatly appreciated!
PS: Sorry for the mixup of tools/frameworks/languages. Tried lots of stuff here. Extra thanks for answers that are React-Native compatible!
<?php
function getMp3StreamTitle($streamingUrl, $interval, $offset = 0, $headers = true)
{
$needle = 'StreamTitle=';
$ua = 'Mozilla';
$opts = [
'http' => [
'header' => 'Icy-MetaData: 1',
'user_agent' => $ua
]
];
if (($headers = get_headers($streamingUrl))) {
foreach ($headers as $h) {
if (strpos(strtolower($h), 'icy-metaint') !== false && ($interval = explode(':', $h)[1])) {
break;
}
}
}
$context = stream_context_create($opts);
if ($stream = fopen($streamingUrl, 'r', false, $context)) {
$buffer = stream_get_contents($stream, $interval, $offset);
fclose($stream);
if (strpos($buffer, $needle) !== false) {
$title = explode($needle, $buffer)[1];
return substr($title, 1, strpos($title, ';') - 2);
} else {
return getMp3StreamTitle($streamingUrl, $interval, $offset + $interval, false);
}
} else {
throw new Exception("Unable to open stream [{$streamingUrl}]");
}
}
var_dump(getMp3StreamTitle('http://icecast.vrtcdn.be/stubru-high.mp3', 16000));

What to do when an API has no documentation

I'm currently trying to use a REST API to insert data from Powershell into a Jira custom field made by a certain plugin (Easy links for JIRA). Unfortunately there's no documentation on the required syntax. Does anyone who's run into this plugin know the commands/syntax I'll need to use the REST API (It's quite a small plugin so I'll be surprised if anyone else has seen it)? Failing that, does anyone have any advice on discovering how to use APIs with no/bad documentation i.e. some standard method of making an API return a list of commands and syntax (preferably by using powershell)?
I've tried contacting the developer but haven't heard back from them.
The code I'm using is here, if that's helpful:
function Test-Upload(){
Param()
Process{
$data=#"
{
"fields":
{
"project":
{
"key": "CCWASSET"
},
"summary": "Testing Linked Field",
"issuetype":
{
"name": "Asset"
},
"description" : "Testing Linked Field"
},
"update":{
"customfield_10500":[
{
"set":{
"type":{
"name":"Asset PO",
"inward":"Asset",
"outward":"Purchase Order"
},
"outwardIssue":{
"key":""
}
}
}
]
}
}
"#
return Jira-WebRequest -data $data
}
}
function Jira-WebRequest(){
Param(
[Parameter(mandatory=$false)]$data,
[Parameter(mandatory=$false)]$requesttype="issue",
[Parameter(mandatory=$false)]$method="POST",
[Parameter(mandatory=$false)]$ContentType='application/json'
)
Process{
$path = $("/rest/api/2/$requesttype/")
$Uri = ""
[URI]::TryCreate([URI]::new($Settings.Jira.URL),"$path",$([ref]$Uri))
$Params = #{
ContentType = $ContentType
Body = $data #$(#{"vlan_id"=$vlanID;"port_id"="$portID";"port_mode"="$portMode"} | ConvertTo-JSON)
Method = $method
URI = $uri.AbsoluteUri
Headers = $JiraHeaders
#WebSession = $Session
}
try{
$result = Invoke-RestMethod #Params -Verbose
return $result
} Catch [System.Net.WebException] {
$exception = $_.Exception
$respstream = $exception.Response.GetResponseStream()
$sr = new-object System.IO.StreamReader $respstream
$ErrorResult = $sr.ReadToEnd()
return $ErrorResult
}
}
}
It doesn't matter if the custom field made by a plugin or by you. At the end it's custom field so since the plugin doesn't have a good documentation, I would recommend you to stay with Atlassian Documentation and update / edit your issues base on official REST API. You can see Atlassian examples with Custom Fields here
What you need to do is you just need to figure out what's the custom field ID and that would be easy by going towards admin panel and clicking on the custom field and check it from URL if you don't want to go to database.
I know it's pain to see API without documents but at least you can workaround it this way.
Managed to get it working for this particular plugin. Had to include the ID field as well as the Key of the issue that I want to link to. I'd still be interested to hear if anyone has some tips for working with API's that have no/bad documentation.
"update":{
"customfield_10500":[
{
"set":{
"type":{
"name":"Asset PO",
"inward":"Asset",
"outward":"Purchase Order"
},
"outwardIssue":{
"key":""
"ID":""
}
}
}
]
}
}

Integration tests with mongodb

I'm using mongodb as my main database, so on my integration tests I try to test if my system handles the data as expected. The process is as follow:
Insert data on needed collections to prepare scenario
Perform call to the system
Validate data change or exist on database, depending of the scenario
I'm using behat as my BDD testing tool and I implement on my FeatureContext to insert and read data from collections, something like this:
Given I have the following data on collection Brand
[
{
"_id": "575df0b00419c905492d0461",
"name": "Adidas",
"image": "adidas.png"
}
]
Then I validate the following data exists on collection Brand
[
{
"_id": "575df0b00419c905492d0461",
"name": "Adidas",
"image": "adidas.png"
}
]
EDIT
/**
* #Given I have the following data on collection :collectionName
* #param string $collectionName
* #param PyStringNode $collectionData
* #throws Exception
*/
public function iHaveTheFollowingDataOnCollection($collectionName, PyStringNode $collectionData)
{
$data = json_decode($collectionData->getRaw(), true);
foreach ($data as $index => $element) {
foreach ($element as $key => $value) {
if ($key === '_id') {
$data[$index][$key] = new \MongoDB\BSON\ObjectID($value);
}
if (strpos($key, "#") !== false) {
$key = explode("#", $key)[1];
$data[$index][$key] = array(
"\$ref" => $value["\$ref"],
"\$id" => new \MongoDB\BSON\ObjectID($value["\$id"]),
"\$db" => $value["\$db"],
);
}
if ($value === "UNIX_TIME()") {
$data[$index][$key] = time();
}
}
}
$collection = $this->db->$collectionName;
foreach ($data as $document) {
$collection->insertOne($document);
}
}
END EDIT
The issue is that I have at least 1k different scenarios on different features and with that heavy usage test randomly fails becase it don't find expected data on collection.
My first thought is that exist some delay on insertion and availability of the data.
Any thoughts and how to fix it?

XML::FeedPP and accessing media:* property

I'm trying to parse a youtube xml feed and want to access certain media elements in the feed.
I'm able to access basic elements such as title and link but accessing anything under media:group returns empty string.
use XML::FeedPP;
my $feed = XML::FeedPP->new("https://www.youtube.com/feeds/videos.xml\?channel_id\=UCzJuUAme9EABE1quatA8z-Q");
foreach my $item ( $feed->get_item() ) {
print $item->get("media:group") . "\n";
}
Any suggestions on how I can access the media:group and its child elements ?
Inspecting the $item objects in that feed with Data::Printer shows that the objects know about the media:group and other things in the media: namespace.
use strict;
use warnings;
use Data::Printer;
use XML::FeedPP;
my $feed = XML::FeedPP->new("https://www.youtube.com/feeds/videos.xml?channel_id=UCzJuUAme9EABE1quatA8z-Q");
foreach my $item ( $feed->get_item() ) {
p $item;
}
__END__
XML::FeedPP::Atom::Atom10::Entry {
Parents XML::FeedPP::Atom::Common::Entry
public methods (6) : category, description, get_pubDate_native, link, pubDate, title
private methods (0)
internals: {
author {
name "Fun to Origami",
uri "http://www.youtube.com/channel/UCzJuUAme9EABE1quatA8z-Q"
},
id "yt:video:332UeGpfY3E",
link {
-href "http://www.youtube.com/watch?v=332UeGpfY3E",
-rel "alternate"
},
media:group {
media:community {
media:starRating {
-average 4.56,
-count 9,
-max 5,
-min 1
},
media:statistics {
-views 940
}
},
media:content {
-height 390,
-type "application/x-shockwave-flash",
-url "https://www.youtube.com/v/332UeGpfY3E?version=3",
-width 640
},
media:description "...",
media:thumbnail {
-height 360,
-url "https://i4.ytimg.com/vi/332UeGpfY3E/hqdefault.jpg",
-width 480
},
media:title "Origami Pteranodon : Paper Dinosaur Tutorial"
},
published "2015-02-20T01:22:36+00:00",
title "Origami Pteranodon : Paper Dinosaur Tutorial",
updated "2016-02-15T13:42:07+00:00",
yt:channelId "UCzJuUAme9EABE1quatA8z-Q",
yt:videoId "332UeGpfY3E"
}
}
Source: Youtube, Omission mine
So the most obvious way would be to just access the data structure directly. Of course you don't want to do that, as it's bad style, and the underlying implementation might change.
foreach my $item ( $feed->get_item() ) {
say $item->{'media:group'}->{'media:content'}->{'-height'};
}
__END__
390
...
If this is a run-once-and-forget script, stop here.
Now the fun part begins. The $item is an XML::FeedPP::Atom::Atom10::Entry, which is an XML::FeedPP::Item, which is an XML::FeedPP::Element. That guy has a method get. It looks like it would not have a problem dealing with the : part, but it returns undef.
This module seems to be extensively tested. There is an 11_media.t that actually plays around with the media: namespace. In the examples there, however, it not only probably work (or I could not have installed the module), but it's also a bit different. The media: element is not very deep. It's just one tag with attributes.
Feel free to take the research further from this point.

Selecting Data from JSON object using php

I have json data i want to select some data before i tell you please read the data carefully.
{
"response": {
"status": 1,
"httpStatus": 200,
"data": [{
"offer_id": "6912",
"Thumbnail": {
"10116": {
"id": "10116",
"offer_id": "6912",
"display": "Icandytv_IN_Call-30-19-20-51).gif",
"thumbnail": "https:\/\/media.go2speed.org\/brand\/files\/mobvista\/6912\/thumbnails_100\/Icandytv_IN_Call(04-30-19-20-51).gif"
}
}
}],
"errors":[] ,
"errorMessage": null
}
}
From above Data i want to collect the value of thumbnail plese help me to find it out using PHP
Maybe that is an copy/paste problem, but your JSON-String is missing some }. But that is not the issue. If you want to access thumbnail (lowercase) in your json, try following:
<?php
$json = '{"response": {"status":1,"httpStatus":200,"data":[{"offer_id":"6912","Thumbnail":{"10116":{"id":"10116","offer_id":"6912","display":"Icandytv_IN_Call (04-30-19-20-51).gif","thumbnail":"https://media.go2speed.org/brand/files/mobvista/6912/thumbnails_100/Icandytv_IN_Call(04-30-19-20-51).gif"}}}],"errors":[],"errorMessage":null}}';
// Make JSON accessible for PHP
$data = json_decode($json);
// Get access to Thumbnail object
$thumbnail0 = $data->response->data[0]->Thumbnail;
// Get access to thumbnail object "10116"
$thumbnail_10116 = $thumbnail0->{"10116"};
// Thumbnail Url
$thumbnailUrl = $thumbnail_10116->thumbnail;
echo $thumbnailUrl . "\n";
// or in one swoop
$thumbnailUrl2 = $data->response->data[0]->Thumbnail->{"10116"}->thumbnail;
echo $thumbnailUrl2 . "\n";
?>
Hope, that helps