How to add product image via the woocommerce REST API? - php

I am working with the Woocommerce REST API and need to add a product to the store.
It worked before. Now I have this error:
stdClass Object ( [errors] => Array (
[0] => stdClass Object ( [code] =>
woocommerce_api_invalid_remote_product_image
[message] => Error getting remote image
https://www.google.lt/images/srpr/logo11w.png ) ) )
Here is the documentation for adding a product via the WooCommerce REST API
http://woothemes.github.io/woocommerce-rest-api-docs/#create-a-product
Here is my code:
$dataArray = array(
'title' => 'xxxxxxxxxx',
'description' => 'description1',
'price' => '69',
'sku' => 'sku2',
'tags' => 'tag1, tag2, tag3',
'color' => array('red', 'blue'),
'size' => array('S', 'M'),
'image' => 'https://www.google.lt/images/srpr/logo11w.png'
);
public function addProduct($data)
{
$wc_api = $this->_getClient();
$newProductData = array(
'product' => array(
'title' => $data['title'],
'type' => 'variable',
'regular_price' => $data['price'],
'description' => $data['description'],
'sku' => $data['sku'],
'tags' => [ $data['tags'] ],
'images' => [ array('src' => $data['image'], 'position' => '0') ],
'virtual' => true
)
);
return $wc_api->create_product($newProductData);
}
I'm using this client to call the REST API
https://github.com/kloon/WooCommerce-REST-API-Client-Library
EDITED:
If I get image from wordpress where woocommerce is hosted then all is fine. But, if I use a link from another site then I get an error.

I had a similar issue and the error that cURL was generating inside WordPress which leads to woocommerce_api_invalid_remote_product_image was {"errors":{"http_request_failed":["SSLRead() return error -9806"]},"error_data":[]} which means, according to Asaph in https://stackoverflow.com/a/26538127/266531,
php is compiled with a version of cURL that uses Apple's Secure
Transport under Yosemite and the target of the URL request doesn't
support SSLv3 (which was probably disabled due to the POODLE
vulnerability).
My guess is that you are experiencing errors with using SSL over cURL.
Have you tried it with an http link rather thank https?
If you can debug the server side, take a look at what's happening inside class-wc-api-products.php around line 1700. That's what's generating the error. You may be experiencing SSL errors.
If it is the same type of SSL issue, then your possible solutions are
Use a non-secure image link (http instead of https), or
Follow Asaph's steps to install PHP using OpenSSL instead of SecureSSL in his answer at https://stackoverflow.com/a/26538127/266531

In Woocommerce REST API liblary You can also set option to dont validate SSL.
$options = array(
'debug' => true,
'return_as_array' => false,
'validate_url' => false,
'timeout' => 60,
'ssl_verify' => false,
);

Related

Post to remote WordPress site to custom post type

I'm using the WordPress REST API and trying to post to a remote WordPress website, but it doesn't seem to post to my 'clothes' registered custom post type.
Here's the code:
$api_response = wp_remote_post( 'https://example.com/wp-json/wp/v2/posts', array(
'headers' => array(
'Authorization' => 'Basic ' . base64_encode( 'admin:5mMcJGUGNFYq9PxU5P0ad0Np' )
),
'body' => array(
'title' => 'Pink Shirt',
'status' => 'publish',
'post_type' => 'clothes',
'categories' => 2,
'slug' => 'pink-shirt',
'meta' => array('amount' => '12.50', 'style' => 'petite', 'size' => 'small', 'gender' => 'ladies', 'author' => 1)
)
));
The post does indeed get created on the remote website, but it always ends up as a standard post (and so it appears with all the other posts), instead of the 'clothes' custom post type.
I've tried both this...
'post_type' => 'clothes',
...and this...
'type' => 'clothes',
...but it's the same result.
What am I doing wrong?
I've triple checked and 'clothes' is a registered post type with the 'show_in_rest' parameter set to true.
According to the documentation, https://example.com/wp-json/wp/v2/posts should be https://example.com/wp-json/wp/v2/[custom-post-type-slug-here] instead:
When registering a custom post type, if you want it to be available via the REST API you should set 'show_in_rest' => true in the arguments passed to register_post_type. Setting this argument to true will add a route in the wp/v2 namespace.
You can optionally set the rest_base argument to change the base url, which will otherwise default to the post type’s name. In the example below, “books” is used as the value of rest_base. This will make the URL for the route wp-json/wp/v2/books instead of wp-json/wp/v2/book/, which would have been the default.
So, assuming that you're not using the rest_base parameter, the URL you should be using in your POST request is https://example.com/wp-json/wp/v2/clothes instead.

SimpleSAMLphp shows saml2-acs.php not found (error 404) when integrating with Microsoft Azure Directory SSO using SAML2

I have created a link from my web directory such that https://resolute.organization.in/sso points to the simplesaml directory /var/www/simplesamlphp/www
My simpleSAML configuration page:
The complete link https://resolute.organization.in/sso/module.php/saml/sp/saml2-acs.php/default-sp shows 404 Not Found while testing Authentication Sources --> default-sp.
My config.php:
$config = ['baseurlpath' => 'https://resolute.organization.in/sso/',
'secretsalt' => 'my_secret_salt',
'auth.adminpassword' => 'my_admin_pass',
];
Rest all are default values in config.php
My authsources.php:
$config = [
'admin' => [
'core:AdminPassword',
],
'default-sp' => [
'saml:SP',
'entityID' => 'https://resolute.organization.in/',
'idp' => 'https://sts.windows.net/{some-unique-key}/', //From metadata.xml for the app with entity ID in AD as *https://resolute.organization.in/*
'discoURL' => null,
'NameIDFormat' => 'urn:oasis:names:tc:SAML:2.0:nameid-format:persistent',
'simplesaml.nameidattribute' => 'eduPersonTargetedID',
],
]
My metadata array in saml20-idp-remote.php:
$metadata['https://sts.windows.net/{some-unique-key}/'] = array (
'entityid' => 'https://sts.windows.net/{some-unique-key}/',
'contacts' =>
array (
),
'metadata-set' => 'saml20-idp-remote',
'SingleSignOnService' =>
array (
0 =>
array (
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
'Location' => 'https://login.microsoftonline.com/{some-unique-key}/saml2',
),
1 =>
array (
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-POST',
'Location' => 'https://login.microsoftonline.com/{some-unique-key}/saml2',
),
),
'SingleLogoutService' =>
array (
0 =>
array (
'Binding' => 'urn:oasis:names:tc:SAML:2.0:bindings:HTTP-Redirect',
'Location' => 'https://login.microsoftonline.com/{some-unique-key}/saml2',
),
),
'ArtifactResolutionService' =>
array (
),
'NameIDFormats' =>
array (
),
'keys' =>
array (
0 =>
array (
'encryption' => false,
'signing' => true,
'type' => 'X509Certificate',
'X509Certificate' => '{really_long_key}',
),
),
);
My Federation page:
The [show metadata] link shows 404 as well, the link in the URL bar in this case is:
https://resolute.organization.in/sso/module.php/saml/sp/metadata.php/default-sp?output=xhtml
IdP metadata link shows the metadata array properly.
Please help me out with what am I missing here as I have been breaking my head over this for a few days now.
Figured out the issue, it had something to do with Nginx server configuration that could not handle multiple php pages in one link. Switched to Apache and everything works fine.
It depends on how php handles the url parameters and occurs when using php-fpm either with NGINX or Apache mpm_worker/event.
In order to fix this, set
cgi.fix_pathinfo=1 in php.ini

Add `alt` parameter while generating reports from AdExchange Seller API

I'm trying to retrieve a report from the AdExchange Seller API.
I am using the maximum allowed amount of dimensions and metrics so the reports is quite big (>100.000 rows). According to the documentation on large reports this is possible using the limit break feature by adding the alt=media parameter. But I can't figure out how to add that parameter using the Google API client for PHP. I would prefer to stick to the official Google libraries, but I'm open for suggestions.
Note: adding alt=csv or alt=media to the optParams does not work and I can easily access the data if I remove some of the dimensions and metrics.
More specifically I'm using the accounts_reports resource and then the generate method. Looking at the source code (shown below), I can't see anywhere that it would be able to accept a alt parameter, but I'm obviously missing something.
$this->accounts_reports = new Google_Service_AdExchangeSeller_Resource_AccountsReports(
$this,
$this->serviceName,
'reports',
array(
'methods' => array(
'generate' => array(
'path' => 'accounts/{accountId}/reports',
'httpMethod' => 'GET',
'parameters' => array(
'accountId' => array(
'location' => 'path',
'type' => 'string',
'required' => true,
),
'startDate' => array(
'location' => 'query',
'type' => 'string',
'required' => true,
),
'endDate' => array(
'location' => 'query',
'type' => 'string',
'required' => true,
),
'dimension' => array(
'location' => 'query',
'type' => 'string',
'repeated' => true,
),
'filter' => array(
'location' => 'query',
'type' => 'string',
'repeated' => true,
),
'locale' => array(
'location' => 'query',
'type' => 'string',
),
'maxResults' => array(
'location' => 'query',
'type' => 'integer',
),
'metric' => array(
'location' => 'query',
'type' => 'string',
'repeated' => true,
),
'sort' => array(
'location' => 'query',
'type' => 'string',
'repeated' => true,
),
'startIndex' => array(
'location' => 'query',
'type' => 'integer',
),
),
),
)
)
);
Digging further I found this statement in the Google_Service_AdExchangeSeller_Resource_AccountsReports class.
Generate an Ad Exchange report based on the report request sent in the query
parameters. Returns the result as JSON; to retrieve output in CSV format
specify "alt=csv" as a query parameter. (reports.generate)
But how exactly would that work? As far as I can figure out, it doesn't.
Not really an answer but to long for a comment.
I don't think you are going to get that to work with the client library. The client libraries are generated via the Discovery Services API. Which gives information about what parameters the API takes. For some reason this alt=csv is not registered in the discovery services for that API. Its there in the description but its not registered as a parameter. So the Client library itself isn't going to build it for you.
You can see the response I am looking at here
An idea would be to make the change to the client library yourself you have the code. While altering the client libraries manually is not ideal it is doable.
Try and add alt and give it a value of CSV.
I don't have enough experience with the inner workings of the PHP client library but you can post this as an issue on their forum. Mention that its not in discovery they may have an easer way of applying a random parameter to the query string. I doubt it but its worth a shot.
This should be possible with the PHP client library. The following example demonstrates how to do it with the Drive API:
$fileId = '0BwwA4oUTeiV1UVNwOHItT0xfa2M';
$content = $driveService->files->get($fileId, array(
'alt' => 'media' ));
https://developers.google.com/drive/v3/web/manage-downloads#examples

Redux Framework creating a Protocol Relative URL Filter

I'm working on a WP Theme that uses Redux Framework and I am trying to create a filter for fields that have a URL attached to them, ie, Background Fields, Media Fields, so that I can make them Protocol relative and able to use SSL site-wide without conflicts.
So far I have the following function in my options-init.php file for a Background Field but to be honest I have very little experience with Filters, and the documentation for Redux Framework is very vague.
Field is as follows:
array(
'id' => 'front-background',
'type' => 'background',
'url' => true,
'title' => __('Front Page Background', 'blanque'),
'desc' => __('Background image for Front Page', 'blanque'),
'subtitle' => __('', 'blanque'),
'compiler' => true,
'output' => array(
'background' => 'body.home',
),
'default' => array(
'url' => '',
),
'background-color' => false,
'preview_height' => '100px',
)
Fuction to filter output:
function the_theme_redux_filters($url) {
$relativeURL = str_replace(array('http://','https://'), '//', $url);
return $relativeURL;
}
add_filter( 'redux/validate/front-background/class/{field.validate}', '', 10, 1 );
Would someone be able to give me a clue as to what I should actually be doing please?

Woocommerce product api not accept images in some urls

I am creating products from external in woocommerce site. My code is like bellow:
if($_POST["Type"] == "CREATE"){
$data = array(
'product' => array(
'title' => $_POST["Title"],
'type' => 'simple',
'regular_price' => $_POST["Regular_price"],
'description' => $_POST["Description"],
'short_description' => $_POST["Short_description"],
'categories' => array(
$_POST['CategoryName']
),
'images' => array(
array(
'src' => $_POST["Image_url"],
'position' => 0
),
array(
'src' => $_POST["Image_url"],
'position' => 1
)
)
)
);
$res = $client->products->create($data);
}
When using $_POST["Image_url"] such like http://app.test.net:8080/test/img/company-logo.png gives the following error:
PHP Fatal error: Uncaught exception 'WC_API_Client_HTTP_Exception' with message 'Error: Error getting remote image
But if we give a normal url(url do not contain the specific port) such like http://test.com/wp-content/uploads/2016/02/test.png it's working properly.
How to resolve this?
In my case above mentioned code in the such a URL (http://app.test.net:8080/api/v1/product.php). Calling this API from .net application by (http://appname.test.net). Both are having the same domain part (test.net).
There fore difficult to find the URL to woo commerce.I have change URL the of .net application by my server configuration(I have using virtual hosts).Then it works properly.
---- (Edit 2) ----
Sorry but your question is Not clear at all. You have to update it, because it is very incomplete and fuzzy. Same thing for the title.
The medias images are located in a 2nd server on port 8080, right…
Form me the problem is here in:
'images' => array(
array(
'src' => $_POST["Image_url"],
'position' => 0
),
array(
'src' => $_POST["Image_url"],
'position' => 0
)
)
with 'src' => $_POST["Image_url"]
Have a look to this interesting related thread: Synchronize external database with woocommerce database

Categories