Asana upload error with Asana/php-asana - php

trying to test provided sample code:
$attachment = $client->attachments->createOnTask(
$enquiry->id,
'hello word',
'upload.txt',
'text/plain'
);
Error:
400 File is not an object
The client definitely works (able to create task just before).
The taskId ($enquiry->id) is correct (checked by going to the url etc).
Using v0.4.0 of the library and PHP 5.6.18-1 off a Homestead virtual machine.
Similar questions on SO talk about bad encoding but everything seems ok in my case.
Below is the response:
class Httpful\Response#961 (13) {
public $body =>
class stdClass#964 (1) {
public $errors =>
array(1) {
[0] =>
class stdClass#973 (2) {
...
}
}
}
public $raw_body =>
string(219) "{"errors":[{"message":"file: File is not an object","help":"For more information on API status codes and how to handle them, read the docs on errors: https://asana.com/developers/documentation/getting-started/errors"}]}"
public $headers =>
class Httpful\Response\Headers#963 (1) {
private $headers =>
array(11) {
'server' =>
string(5) "nginx"
'date' =>
string(29) "Sat, 27 Feb 2016 02:36:49 GMT"
'content-type' =>
string(31) "application/json; charset=UTF-8"
'transfer-encoding' =>
string(7) "chunked"
'connection' =>
string(10) "keep-alive"
'x-asana-content-string-length' =>
string(3) "219"
'pragma' =>
string(8) "no-cache"
'set-cookie' =>
string(22) "TooBusyRedirectCount=0"
'cache-control' =>
string(8) "no-store"
'x-asana-preferred-release-revision' =>
string(56) "20160226_220201_ce3e88b3589d50e067532bbd0e824a44148e6738"
'x-robots-tag' =>
string(4) "none"
}
}
public $raw_headers =>
string(404) "HTTP/1.1 400 Bad Request
Server: nginx
Date: Sat, 27 Feb 2016 02:36:49 GMT
Content-Type: application/json; charset=UTF-8
Transfer-Encoding: chunked
Connection: keep-alive
X-Asana-Content-String-Length: 219
Pragma: no-cache
Set-Cookie: TooBusyRedirectCount=0
Cache-Control: no-store
X-Asana-Preferred-Release-Revision: 20160226_220201_ce3e88b3589d50e067532bbd0e824a44148e6738
X-Robots-Tag: none"
public $request =>
class Httpful\Request#962 (22) {
public $uri =>
string(62) "https://app.asana.com/api/1.0/tasks/(task_id)/attachments"
public $method =>
string(4) "POST"
public $headers =>
array(2) {
'X-Asana-Client-Lib' =>
string(118) "version=0.4.0&language=PHP&language_version=5.6.18-1%2Bdeb.sury.org%7Etrusty%2B1&os=Linux&os_version=3.19.0-25-generic"
'Authorization' =>
string(41) "Bearer (valid bearer)"
}
public $raw_headers =>
string(487) "POST /api/1.0/tasks/(task_id)/attachments HTTP/1.1
Host: app.asana.com
Expect:
User-Agent: Httpful/0.2.20 (cURL/7.35.0 PHP/5.6.18-1+deb.sury.org~trusty+1 (Linux))
Content-Type: multipart/form-data
Accept: */*; q=0.5, text/plain; q=0.8, text/html;level=3;q=0.9, application/json
X-Asana-Client-Lib: version=0.4.0&language=PHP&language_version=5.6.18-1%2Bdeb.sury.org%7Etrusty%2B1&os=Linux&os_version=3.19.0-25-generic
Authorization: Bearer 0/88eebe64d4af7bd966936bbe346be679
"
public $strict_ssl =>
bool(false)
public $content_type =>
string(19) "multipart/form-data"
public $expected_type =>
string(16) "application/json"
public $additional_curl_opts =>
array(0) {
}
public $auto_parse =>
bool(true)
public $serialize_payload_method =>
int(0)
public $username =>
NULL
public $password =>
NULL
public $serialized_payload =>
array(1) {
'file' =>
string(48) "#/tmp/YCRYJd;filename=upload.txt;type=text/plain"
}
public $payload =>
array(1) {
'file' =>
string(48) "#/tmp/YCRYJd;filename=upload.txt;type=text/plain"
}
public $parse_callback =>
NULL
public $error_callback =>
NULL
public $send_callback =>
NULL
public $follow_redirects =>
bool(false)
public $max_redirects =>
int(25)
public $payload_serializers =>
array(0) {
}
public $_ch =>
resource(652) of type (Unknown)
public $_debug =>
NULL
}
public $code =>
int(400)
public $content_type =>
string(16) "application/json"
public $parent_type =>
string(16) "application/json"
public $charset =>
string(5) "UTF-8"
public $meta_data =>
array(26) {
'url' =>
string(62) "https://app.asana.com/api/1.0/tasks/(task_id)/attachments"
'content_type' =>
string(31) "application/json; charset=UTF-8"
'http_code' =>
int(400)
'header_size' =>
int(408)
'request_size' =>
int(552)
'filetime' =>
int(-1)
'ssl_verify_result' =>
int(0)
'redirect_count' =>
int(0)
'total_time' =>
double(3.435421)
'namelookup_time' =>
double(2.1E-5)
'connect_time' =>
double(0.29363)
'pretransfer_time' =>
double(2.023479)
'size_upload' =>
double(187)
'size_download' =>
double(219)
'speed_download' =>
double(63)
'speed_upload' =>
double(54)
'download_content_length' =>
double(-1)
'upload_content_length' =>
double(187)
'starttransfer_time' =>
double(2.023485)
'redirect_time' =>
double(0)
'redirect_url' =>
string(0) ""
'primary_ip' =>
string(12) "52.70.61.144"
'certinfo' =>
array(0) {
}
'primary_port' =>
int(443)
'local_ip' =>
string(9) "10.0.2.15"
'local_port' =>
int(49537)
}
public $is_mime_vendor_specific =>
bool(false)
public $is_mime_personal =>
bool(false)
private $parsers =>
NULL
}
[Asana\Errors\InvalidRequestError]
Invalid Request

Looked into it and Asana/php-asana uploadFile code is not compatible with php 5.6+.
Pull request: here

Related

WooCommerce 3.5.4 and WordPress 5.0.3 REST API: Image upload broken (woocommerce_product_invalid_image_id)

I am using v2 of the REST API. This code worked fine on an older version of WordPress and WooCommerce. I cannot upload an image to a product.
The first error after the upgrade I got was:
array (
'code' => 'woocommerce_product_image_upload_error',
'message' => 'Invalid image: Sorry, this file type is not permitted for security reasons.',
'data' =>
array (
'status' => 400,
),
Resolved by adding following in wp-config.php to the bottom of the file:
define('ALLOW_UNFILTERED_UPLOADS', true);
The 2nd error I cannot figure out. The image won't upload and leaves a ghost image where it was uploaded.
Code
<?php
require __DIR__ . '/vendor/autoload.php';
use Automattic\WooCommerce\Client;
$woocommerce = new Client(
'http://localhost/wordpress',
'ck_44b92c00ea35e6cc59c89c29051bf67c22e0df3a',
'cs_dd833592a1ef7a00a82c1711fd455db2e4c5bd15',
[
'wp_api' => true,
'version' => 'wc/v2',
]
);
$data['create'][] = array(
'name' => 'TEST',
'regular_price' => '4.50',
'description' => 'TEST DESC',
'type' => 'simple',
'images' => array(
array(
'alt' => '',
'name' => '',
'src' => 'http://demo2.phppointofsale.com/PHP-Point-Of-Sale-Prev/index.php/app_files/view/1',
'position' => 0,
),
)
);
$response = $woocommerce->post('products/batch',$data);
$headers = $woocommerce->http->getResponse()->getHeaders();
var_dump($headers);
var_dump($response);
Response Data
array(13) {
["Date"]=>
string(29) "Thu, 24 Jan 2019 18:22:16 GMT"
["Server"]=>
string(6) "Apache"
["X-Powered-By"]=>
string(9) "PHP/7.2.1"
["X-Robots-Tag"]=>
string(7) "noindex"
["Link"]=>
string(63) "<http://localhost/wordpress/wp-json/>; rel="https://api.w.org/""
["X-Content-Type-Options"]=>
string(7) "nosniff"
["Access-Control-Expose-Headers"]=>
string(27) "X-WP-Total, X-WP-TotalPages"
["Access-Control-Allow-Headers"]=>
string(27) "Authorization, Content-Type"
["Expires"]=>
string(29) "Wed, 11 Jan 1984 05:00:00 GMT"
["Cache-Control"]=>
string(36) "no-cache, must-revalidate, max-age=0"
["Allow"]=>
string(16) "POST, PUT, PATCH"
["Content-Length"]=>
string(3) "139"
["Content-Type"]=>
string(31) "application/json; charset=UTF-8"
}
array(1) {
["create"]=>
array(1) {
[0]=>
array(2) {
["id"]=>
int(0)
["error"]=>
array(3) {
["code"]=>
string(36) "woocommerce_product_invalid_image_id"
["message"]=>
string(27) "#82 is an invalid image ID."
["data"]=>
array(1) {
["status"]=>
int(400)
}
}
}
}
}
Proof https://via.placeholder.com/350x150 is an image
cmuench#cmuench:~$ curl -I "https://via.placeholder.com/350x150";
HTTP/1.1 200 OK
Server: nginx/1.6.2
Date: Mon, 28 Jan 2019 14:07:22 GMT
Content-Type: image/png
Content-Length: 1253
Last-Modified: Sun, 06 Jan 2019 22:00:10 GMT
Connection: keep-alive
ETag: "5c327a6a-4e5"
Expires: Mon, 04 Feb 2019 14:07:22 GMT
Cache-Control: max-age=604800
X-Cache: L1
Accept-Ranges: bytes
http://demo2.phppointofsale.com/PHP-Point-Of-Sale-Prev/index.php/app_files/view/1
headers from actual files (not demo example). Same error as demo example
header("Cache-Control: max-age=2592000");
header('Expires: '.gmdate('D, d M Y H:i:s', strtotime('+1 month')).' GMT');
header('Pragma: cache');
header('Content-Disposition: inline; filename="'.$file_name.'"');
header("Content-type: ".get_mime_by_extension($file->file_name));
Because the url doesn't include a file extension in it's name, Wordpress treats it as a file with no extension thus failing the wp_check_filetype_and_ext test.
You can add a filter to add the correct file extension where non exists in the url
add_filter('wp_handle_sideload_prefilter', 'add_extension_if_none_exists');
function add_extension_if_none_exists($file){
if ( pathinfo( $file['name'], PATHINFO_EXTENSION ) ) {
return $file;
}
$real_mime = wp_get_image_mime( $file['tmp_name'] );
$mime_to_ext = apply_filters(
'getimagesize_mimes_to_exts',
array(
'image/jpeg' => 'jpg',
'image/png' => 'png',
'image/gif' => 'gif',
'image/bmp' => 'bmp',
'image/tiff' => 'tif',
'image/webp' => 'webp',
)
);
if ( ! empty( $mime_to_ext[ $real_mime ] ) ) {
$file['name'] .= '.' . $mime_to_ext[ $real_mime ];
}
return $file;
}
even the remote server returns "Content-Type: image/png", Wordpress's server side retrieval function did not get the file name because lack of the name in your rest request and no filename in the remote server response, which cause the internal wp_attachment_is_image() test failed. Try set the rest request with file name with proper file extension.
refer to the woocommerce source code:
https://github.com/woocommerce/woocommerce/blob/00a93ae8f0b200b4def4aea4462fec9d1d5ea96c/includes/api/v2/class-wc-rest-products-v2-controller.php
and Wordpress code:
https://core.trac.wordpress.org/browser/tags/5.0.3/src/wp-includes/post.php
Just setup a similar environment, your code works, the problem lies with your image link, curl seems to get the url response as html rather than an image (https://via.placeholder.com/350x150). From the docs "src" is a string containing Image URL unfortunately the string you provide is NOT an image url.You'll just need to point to image files directly the code below works fine for me.
<?php
require __DIR__ . '/vendor/autoload.php';
use Automattic\WooCommerce\Client;
$woocommerce = new Client(
'http://localhost/wordpress',
'ck_a3ec02fcd547837c384e43ee6989200cca8f6178',
'cs_f60e9ad5c93c9e3bd4adaabd4bd323edddb58f7b',
[
'wp_api' => true,
'version' => 'wc/v2',
]
);
$data['create'][] = array(
'name' => 'TEST',
'regular_price' => '4.50',
'description' => 'TEST DESC',
'type' => 'simple',
'images' => array(
array(
'src' => 'http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_2_front.jpg',
),
)
);
$response = $woocommerce->post('products/batch',$data);
$headers = $woocommerce->http->getResponse()->getHeaders();
var_dump($headers);
var_dump($response);
Maybe it's a bug on WooCommerce on the version you're using. If it's the case: If you are uploading a new image by using an external URL, you should include id field and set it to "0"
"images": [
{
"src": "http://demo.woothemes.com/woocommerce/wp-content/uploads/sites/56/2013/06/T_2_front.jpg",
"id": "0"
}
]
If you are using an image from your WordPress media, you should set the id of the image along with the link on WP there.

Request URI Too Long with POST REST

I have the following peice of PHP code, using to access a POST method REST web service :
$PJS = isset($_REQUEST['arrayFile']) ? $_REQUEST['arrayFile'] : array();
foreach ($PJS as $PJ) {
$ext = explode('/', $PJ['type'])[1];
$storeAttachmentResourceParams = array(
'encodedFile' => $PJ['content'],
'resId' => $resId,
'data' => json_encode(
array(
array('column' => 'title', 'value' => 'PJ', 'type' => 'string'),
array('column' => 'attachment_type', 'value' => 'simple_attachment', 'type' => 'string'),
array('column' => 'status', 'value' => 'A_TRA', 'type' => 'string'),
)
),
'collId' => 'letterbox_coll',
'collIdMaster' => 'letterbox_coll',
'table' => 'res_attachments',
'fileFormat' => $ext
);
$storeAttachmentResource = Requests::post($cfg['url'] . '/attachments', array(), $storeAttachmentResourceParams, $options);
This piece of PHP code is call under a wordpress PHP snippet like the following :
$url = 'https://XXXX.XXX.fr/interface/iface.php';
$options = array(
'http' => array(
'header' => "",
'proxy' => "tcp://192.168.X.X:3128",
'timeout' => 100,
'method' => 'POST',
'content' => http_build_query($data)
)
);
$context = stream_context_create($options);
$return = file_get_contents($url, false, $context);
$returnIface = json_decode($return);
I modify my Apache2.conf like the following to add the LimitRequestLine:
AccessFileName .htaccess
LimitRequestLine 10000000
LimitRequestFieldSize 10000000
Restarted the Apache2 server but still have the following error in my browser :
Request-URI Too Long
The requested URL's length exceeds the capacity
limit for this server.
Apache/2.4.25 (Debian) Server at infosv47.sartrouville.lan Port 80
"
["headers"]=>
object(Requests_Response_Headers)#23 (1) {
["data":protected]=>
array(4) {
["date"]=>
array(1) {
[0]=>
string(29) "Fri, 06 Jul 2018 13:03:25 GMT"
}
["server"]=>
array(1) {
[0]=>
string(22) "Apache/2.4.25 (Debian)"
}
["content-length"]=>
array(1) {
[0]=>
string(3) "339"
}
["content-type"]=>
array(1) {
[0]=>
string(29) "text/html; charset=iso-8859-1"
}
}
}
["status_code"]=>
int(414)
["protocol_version"]=>
float(1.1)
["success"]=>
bool(false)
["redirects"]=>
int(0)
["url"]=>
string(46) "http://10.10.XX.XX/cs_maarch/rest/attachments"
["history"]=>
array(0) {
}
["cookies"]=>
object(Requests_Cookie_Jar)#20 (1) {
["cookies":protected]=>
array(0) {
}
}
}
It's under a Debian 9

PHPUnit - Guzzle: API calls not returning the desired response

I am using PHPUnit and Guzzle to test the REST api, which creates a new record in db, if the username(passed in request parameters) which is not already available in db and it sends response in JSON like below:
{
"success": true,
"id": "<unique_ID>"
}
And if the username is already available in db, then it sends response in JSON like below:
{
"success": false,
"error": "username is already available"
}
This is my PHPUnit testcase to test the above mentioned API along with Guzzle:
This is a setUp function is used to setup the Guzzle client
public function setUp()
{
$this->client = new GuzzleHttp\Client([
'base_uri' => 'http://localhost/test/'
]);
}
And this is the actual test function:
public function testActualResult()
{
$response = $this->client->post('service.php', [
'json' => [
'operation' => 'create_user',
'user_name' => 'testUser1'
]
]);
var_dump($response);
}
Whenever I test this, I get response like this:
class GuzzleHttp\Psr7\Response#99 (6) {
private $reasonPhrase =>
string(2) "OK"
private $statusCode =>
int(200)
private $headers =>
array(5) {
'Date' =>
array(1) {
[0] =>
string(29) "Tue, 21 Nov 2017 10:27:22 GMT"
}
'Server' =>
array(1) {
[0] =>
string(47) "Apache/2.4.26 (Win32) OpenSSL/1.0.2l PHP/5.6.31"
}
'X-Powered-By' =>
array(1) {
[0] =>
string(10) "PHP/5.6.31"
}
'Content-Length' =>
array(1) {
[0] =>
string(4) "1357"
}
'Content-Type' =>
array(1) {
[0] =>
string(16) "application/json"
}
}
private $headerNames =>
array(5) {
'date' =>
string(4) "Date"
'server' =>
string(6) "Server"
'x-powered-by' =>
string(12) "X-Powered-By"
'content-length' =>
string(14) "Content-Length"
'content-type' =>
string(12) "Content-Type"
}
private $protocol =>
string(3) "1.1"
private $stream =>
class GuzzleHttp\Psr7\Stream#86 (7) {
private $stream =>
resource(408) of type (stream)
private $size =>
NULL
private $seekable =>
bool(true)
private $readable =>
bool(true)
private $writable =>
bool(true)
private $uri =>
string(10) "php://temp"
private $customMetadata =>
array(0) {
}
}
}
But I am not getting the desired response sent back by an API call itself.
If I test my above mentioned API with POSTMAN, it works perfectly and gives back desired responses.
Have you read the GuzzlePHP documentation? Under 'Quickstart' -> 'Using Responses' it is described that when you want to get the body of the response you'll need to use the getBody() function on the $response.
What you are doing is just dumping the whole request variable, which contains way more information then you'll need for what you want to do.
See Using Responses for an example:
$response = $client->post('your parameters here');
$body = $response->getBody();
echo $body;

PayPal Billing Plan Key Response Error

function testing(){
$headers_array_sub_new = array("X-PAYPAL-SECURITY-USERID" => 'testing',
"X-PAYPAL-SECURITY-PASSWORD" => '12345645',
"X-PAYPAL-SECURITY-SIGNATURE" => 'Ab2145sdfd-IhWqUntNLtS4AWDawDzjOUVWjw6nXIcMtyOrkmDu',
"X-PAYPAL-APPLICATION-ID" => 'APP-80W284485P519543T',
"X-PAYPAL-REQUEST-DATA-FORMAT" => "NV",
"X-PAYPAL-RESPONSE-DATA-FORMAT" => "JSON",
"Authorization" =>array('clientId'=>'testing','secret'=>'testing'),
"Accept" =>'application/json',
);
$url = "https://api.sandbox.paypal.com/v1/payments/billing-plans";
$subscriptionplan = array(
'name'=>'T shirt Plan',
'description'=> 'welcome plan',
'type'=> 'INFINITE' ,
'payment_definitions'=>array('name'=>'welcome','type'=>'REGULAR','frequency_interval'=>'2','frequency'=>'Month','cycles'=>'10','amount'=>'100'),
'merchant_preferences'=>''
);
$pay_result_trial = wp_remote_request($url, array('method' => 'POST', 'timeout' => 20, 'headers' => $headers_array_sub_new, 'body' => $subscriptionplan));
//$pay_result_trial2 = wp_remote_request($url2, array('method' => 'POST', 'timeout' => 20, 'headers' => $headers_array_sub1, 'body' =>$subscriptionplan));
var_dump($pay_result_trial);
here is the response error
array(5) { ["headers"]=> array(7) { ["server"]=> string(17) "Apache-Coyote/1.1" ["proxy_server_info"]=> string(57) "host=slcsbplatformapiserv3002.slc.paypal.com;threadId=322" ["paypal-debug-id"]=> string(13) "c764b1af30167" ["content-type"]=> string(16) "application/json" ["content-length"]=> string(1) "0" ["date"]=> string(29) "Fri, 20 Mar 2015 05:25:30 GMT" ["connection"]=> string(5) "close" } ["body"]=> string(0) "" ["response"]=> array(2) { ["code"]=> int(401) ["message"]=> string(12) "Unauthorized" } ["cookies"]=> array(0) { } ["filename"]=> NULL ?>
}
Can any one help me?
You are not using the right credentials for the call. You are using your API User/Pwd/Signature which are used for the Classic APIs. The Billing Plans you are attempting to use are part of the RESTful APIs which use standard oAuth credentials of Client ID and Client Secret. The REST API reference can be found here and contains information regarding Authentication/Headers as well as other useful information.

400 bad request on Google API

When I make a request to https://www.googleapis.com/adsense/v1.3/adclients/XXX/adunits?key=XXX I receive a "400 bad request" error.
This is the response:
object Google_HttpRequest (10) {
private batchHeaders -> array(4) [
'Content-Type' => string (16) "application/http"
'Content-Transfer-Encoding' => string (6) "binary"
'MIME-Version' => string (3) "1.0"
'Content-Length' => string (0) ""
]
protected url -> string (118) "https://www.googleapis.com/adsense/v1.3/adclients/XXX/adunits?key=XXX"
protected requestMethod -> string (3) "GET"
protected requestHeaders -> array(1) [
'authorization' => string (84) "Bearer XXX"
]
protected postBody -> NULL
protected userAgent -> string (27) "google-api-php-client/0.6.5"
protected responseHttpCode -> integer 400
protected responseHeaders -> array(10) [
'content-type' => string (31) "application/json; charset=UTF-8"
'date' => string (29) "Thu, 16 Jan 2014 17:52:09 GMT"
'expires' => string (29) "Thu, 16 Jan 2014 17:52:09 GMT"
'cache-control' => string (18) "private, max-age=0"
'x-content-type-options' => string (7) "nosniff"
'x-frame-options' => string (10) "SAMEORIGIN"
'x-xss-protection' => string (13) "1; mode=block"
'server' => string (3) "GSE"
'alternate-protocol' => string (8) "443:quic"
'transfer-encoding' => string (7) "chunked"
]
protected responseBody -> string (176) "{
"error": {
"errors": [
{
"domain": "usageLimits",
"reason": "keyExpired",
"message": "Bad Request"
}
],
"code": 400,
"message": "Bad Request"
}
}
"
public accessKey -> NULL
}
I use the official PHP library and in the Developers Console everything is working properly...

Categories