I am trying to use a PHP CURL request to upload data to Pass Slot to change an image, and I am continually getting errors.
This is the CURL request needed from their developer section on their website
POST https://api.passslot.com/v1/passes/pass.example.id1/27f145d2-5713-4a8d-af64-b269f95ade3b/images/thumbnail/normal
and this is the data that needs to be sent in its requested format
------------------------------330184f75e21
Content-Disposition: form-data; name="image"; filename="icon.png"
Content-Type: application/octet-stream
.PNG
imagedata
This is the code I am using currently, as I am not familiar with what is required on Multipart Form requests on API
$passId = "xxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxx";
$pass_generate_url = "pass.xxxxxxxxxxxx";
$url1 = 'https://api.passslot.com/v1/passes/'.$pass_generate_url.'/'.$passId.'/images/strip/normal';
$logo_file_location = "image.png";
$logo_file_location1 = "http://xxxxxxx.com/uploads/";
$data1 = array('image' => '#uploads/'.$logo_file_location,'application/octet-string',$logo_file_location1,'some_other_field' => 'abc',);
$auth1 = array( 'Authorization: Basic xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx=',
'Content-Type: text/plain');
$ch1 = curl_init($url1);
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch1, CURLOPT_POST, 1);
curl_setopt($ch1, CURLOPT_POSTFIELDS, $data1);
curl_setopt($ch1, CURLOPT_HEADER, 0);
curl_setopt($ch1, CURLOPT_HTTPHEADER, $auth1);
$response1 = curl_exec($ch1);
$ch1 = curl_init($url1);
When I run the code, this is the response from the CURL I get
{"message":"Validation Failed","errors":[{"field":"image","reasons":["Required"]}]}
Is there something I need to add to make the code work please?
Yes, I think you can build your own curl including to use say PHP CURLFile (sending the Multipart delimiter boundary and then the graphic data, etc) But you may choose to use an API (Say PassSlot PHP SDK)
https://github.com/passslot/passslot-php-sdk
General usage
require 'passslot-php-sdk/src/PassSlot.php';
$engine = PassSlot::start('<YOUR APP KEY>');
$pass = $engine->createPassFromTemplate(<Template ID>);
$engine->redirectToPass($pass);
For PNG file, it is like:
<?php
require_once('../src/PassSlot.php');
$appKey ='<YOUR APP KEY>';
$passTemplateId = 123456;
$outputPass = FALSE;
$values = array(
'Name' => 'John',
'Level' => 'Platinum',
'Balance' => 20.50
);
$images = array(
'thumbnail' => dirname(__FILE__) . '/thumbnail.png'
);
try {
$engine = PassSlot::start($appKey);
$pass = $engine->createPassFromTemplate($passTemplateId, $values, $images);
if($outputPass) {
$passData = $engine->downloadPass($pass);
$engine->outputPass($passData);
} else {
$engine->redirectToPass($pass);
}
} catch (PassSlotApiException $e) {
echo "Something went wrong:\n";
echo $e;
}
For further reference, please visit this
https://github.com/passslot/passslot-php-sdk/blob/master/examples/example.php
You may also view the source of the API to get inspired:
https://github.com/passslot/passslot-php-sdk/blob/master/src/PassSlot.php
Additional remark:
In case there is certificate expiry warning/error when running the SDK, please download the latest cacert.pem from https://curl.se/docs/caextract.html and replace the one in the SDK
Related
I'm using file_get_contents() to get a PHP file which I use as a template to create a PDF.
I need to pass some POST values to it, in order to fill the template and get the produced HTML back into a PHP variable. Then use it with mPDF.
This works perfectly on MY server (a VPS using PHP 5.6.24)...
Now, at the point where I'm installing the fully tested script on the client's live site (PHP 5.6.29),
I get this error:
PHP Warning: file_get_contents(http://www.example.com/wp-content/calculator/pdf_page1.php): failed to open stream: HTTP request failed! HTTP/1.1 406 Not Acceptable
So I guess this can be fixed in php.ini or some config file.
I can ask (I WANT TO!!) my client to contact his host to fix it...
But since I know that hosters are generally not inclined to change server configs...
I would like to know exactly what to change in which file to allow the code below to work.
For my personnal knowledge... Obviously.
But also to make it look "easy" for the hoster (and my client!!) to change it efficiently. ;)
I'm pretty sure this is just one PHP config param with a strange name...
<?php
$baseAddr = "http://www.example.com/wp-content/calculator/";
// ====================================================
// CLEAR OLD PDFs
$now = date("U");
$delayToKeepPDFs = 60*60*2; // 2 hours in seconds.
if ($handle = opendir('.')) {
while (false !== ($entry = readdir($handle))) {
if(substr($entry,-4)==".pdf"){
$fileTime = filemtime($entry); // Returns unix timestamp;
if($fileTime+$delayToKeepPDFs<$now){
unlink($entry); // Delete file
}
}
}
closedir($handle);
}
// ====================================================
// Random file number
$random = rand(100, 999);
$page1 = $_POST['page1']; // Here are the values, sent via ajax, to fill the template.
$page2 = $_POST['page2'];
// Instantiate mpdf
require_once __DIR__ . '/vendor/autoload.php';
$mpdf = new mPDF( __DIR__ . '/vendor/mpdf/mpdf/tmp');
// GET PDF templates from external PHP
// ==============================================================
// REF: http://stackoverflow.com/a/2445332/2159528
// ==============================================================
$postdata = http_build_query(
array(
"page1" => $page1,
"page2" => $page2
)
);
$opts = array('http' =>
array(
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
$context = stream_context_create($opts);
// ==============================================================
$STYLE .= file_get_contents("smolov.css", false, $context);
$PAGE_1 .= file_get_contents($baseAddr . "pdf_page1.php", false, $context);
$PAGE_2 .= file_get_contents($baseAddr . "pdf_page2.php", false, $context);
$mpdf->AddPage('P');
// Write style.
$mpdf->WriteHTML($STYLE,1);
// Write page 1.
$mpdf->WriteHTML($PAGE_1,2);
$mpdf->AddPage('P');
// Write page 1.
$mpdf->WriteHTML($PAGE_2,2);
// Create the pdf on server
$file = "training-" . $random . ".pdf";
$mpdf->Output(__DIR__ . "/" . $file,"F");
// Send filename to ajax success.
echo $file;
?>
Just to avoid the "What have you tried so far?" comments:
I searched those keywords in many combinaisons, but didn't found the setting that would need to be changed:
php
php.ini
request
header
content-type
application
HTTP
file_get_contents
HTTP/1.1 406 Not Acceptable
Maaaaany thanks to #Rasclatt for the priceless help! Here is a working cURL code, as an alternative to file_get_contents() (I do not quite understand it yet... But proven functional!):
function curl_get_contents($url, $fields, $fields_url_enc){
# Start curl
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, 0);
# Required to get data back
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
# Notes that request is sending a POST
curl_setopt($ch,CURLOPT_POST, count($fields));
# Send the post data
curl_setopt($ch,CURLOPT_POSTFIELDS, $fields_url_enc);
# Send a fake user agent to simulate a browser hit
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11) AppleWebKit/601.1.56 (KHTML, like Gecko) Version/9.0 Safari/601.1.56');
# Set the endpoint
curl_setopt($ch, CURLOPT_URL, $url);
# Execute the call and get the data back from the hit
$data = curl_exec($ch);
# Close the connection
curl_close($ch);
# Send back data
return $data;
}
# Store post data
$fields = array(
'page1' => $_POST['page1'],
'page2' => $_POST['page2']
);
# Create query string as noted in the curl manual
$fields_url_enc = http_build_query($fields);
# Request to page 1, sending post data
$PAGE_1 .= curl_get_contents($baseAddr . "pdf_page1.php", $fields, $fields_url_enc);
# Request to page 2, sending post data
$PAGE_2 .= curl_get_contents($baseAddr . "pdf_page2.php", $fields, $fields_url_enc);
I have a Vimeo PRO account.
I have protected videos uploaded.
Videos are also set to ONLY be embeddable on my domains (set in the video settings)
I am -not- grasping how to use their examples (sorry, for me the examples do not include real working samples for me,..or at least how to implement them to understand.. so I'm hoping to get some help)
Not clear on all the OAuth2, Oembed... authentication stuff either.. which I believe is where my problem lies.
I was following this gitHub example:
https://github.com/vimeo/vimeo-api-examples/blob/master/oembed/php-example.php
(looks to be pretty old?)
I'm looking to get JSON data returned for a video when an ID is passed along.
I was/am under the impression that I need to 'authenticate' before I can get my response/return data?
Is this best done in the CURL header or something?
Can someone guide me a bit more? (shouldnt be this hard!) haha..
Here is my code:
$video_endpoint = 'https://api.vimeo.com/videos/';
$video_url = '171811266';
//JSON url
//$json_url = $video_endpoint . '.json?url=' . rawurlencode($video_url);
//this fixes the cURL approach
$json_url = $video_endpoint . rawurlencode($video_url);
// Curl helper function
function curl_get($url) {
$curl = curl_init($url);
curl_setopt($curl, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($curl, CURLOPT_TIMEOUT, 30);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, 1);
//curl_setopt($curl, CURLOPT_HTTPHEADER, array('Authorization : bearer xxxxxx'));
$return = curl_exec($curl);
curl_close($curl);
return $return;
}
$vimeoJSON = json_decode((curl_get($json_url)));
var_dump($vimeoJSON);
And I get this response:
object(stdClass)#1 (1) { ["error"]=> string(52) "You must provide a valid authenticated access token." }
questions are:
1.) Is this even a valid approach? (assuming I just need to append some lines of code to the CURL header to send my auth over before getting a response?)
2.) How do I update my CURL snippet to work with VIEMO authentication?
I'm trying to keep this as CLEAN/SIMPLE as I can (for the JSON call/return portion)..
Any guidance is appreciated.
Thanks
update:
this code does NOT work:
$access_token = 'xxx';
$video_endpoint = 'https://api.vimeo.com/videos/';
$video_url = '171811266';
$json_url = $video_endpoint . '.json?url=' . rawurlencode($video_url);
$curl = curl_init();
curl_setopt_array($curl, array(
CURLOPT_URL => $json_url,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => array(
"authorization: Bearer ".$access_token
),
));
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}
The video I want to use is located here:
https://vimeo.com/171811266/5822169b48
IT IS A PRIVATE VIDEO. (not sure you'll be able to see it)..
When I use the latest version of the code posted above.. I get this response:
{"error":"The requested video could not be found"}
Is this because its a PRIVATE video?
(actually I just set the video to be able to be viewed by anyone.. and I still got the same error/response) (not found)
If so.. what is the fix to use MY videos.. that are set to private... but use them on my site/domain still?
===========================================================================
FINAL UPDATE:
Trying to use the code in the readme example:
https://github.com/vimeo/vimeo.php
Trying to use (un-successfully) the LIB #Dashron pointed me too.. I cant even seem to get the basics to work from the GIT Page:
Code:
//project vars
$client_id = 'xxxx';
$client_secret = 'xxx';
$access_token = 'xxx';
$redirect_uri = 'http://domain.com/file.php'; //where do I redirect them back to? the page where I have the embeded video at?
// scope is an array of permissions your token needs to access. You can read more at https://developer.vimeo.com/api/authentication#scopes
$scopes = Array('public', 'private');
$state = 'Ldhg0478y';
require("Vimeo/autoload.php");
$lib = new Vimeo\Vimeo($client_id, $client_secret);
// build a link to Vimeo so your users can authorize your app. //whatever that means and is for?
$url = $lib->buildAuthorizationEndpoint($redirect_uri, $scopes, $state);
// redirect_uri must be provided, and must match your configured uri
$token = $lib->accessToken(code, redirect_uri);
// usable access token
var_dump($token['body']['access_token']);
// accepted scopes
var_dump($token['body']['scope']);
// use the token
$lib->setToken($token['body']['access_token']);
I get this error message:
Parse error: syntax error, unexpected Fatal error: Class 'Vimeo\Vimeo' not found in /usr/www/users/aaemorg/aaem.org/video/vimeo_lib.php
Seems like its not creating instantiating my $lib object/class??
(I know I'm not great at high level PHP class/code... but this absurdly hard just to get a JSON response for video I own to embed (again) on a site I own as well)
Any direction would be appreciated?
======================================================================
Update: "what worked for me"..
I am appreciate the link to the 'official' library.. but the readme examples just didnt work for me...
To keep things nice and easy for others who may be new to the Vimeo API stuff as well.. here is a quick and dirty, simple code sample to get you up and running:
<?
//include offifial library
require("Vimeo/autoload.php");
$client_id = 'xxx';
$client_secret = 'xxx';
$access_token = 'xxx';
$video_id = 'xxx';
$lib = new Vimeo\Vimeo($client_id, $client_secret, $access_token);
$video_response = $lib->request('/videos/'.$video_id);
//dont really need this, but included in case there is some data you need to display
$token_response = $lib->clientCredentials();
//example of parsing out specific data from the array returned
//name/title
echo $video_response['body']['name'] . '<br><br>';
?>
The link you provided is very, very old. It is actually part of a different API, and no longer relevant.
The Library you should be using is located here: https://github.com/vimeo/vimeo.php with many examples in the readme, and the examples directory!
Below code works for me
Please follow this step before
Under video settings : General->privacy, Change Who can watch select box to Anyone.
$url = 'https://api.vimeo.com/videos/388591356';
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
$headers = array();
$headers[] = "Content-Type: application/x-www-form-urlencoded";
$headers[] = "Accept: application/json";
$headers[] = "Authorization: Bearer 969329f9b5b3882d74d1b39297528242";
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
$result = curl_exec($ch);
curl_close($ch);
$final_result = json_decode( preg_replace('/[\x00-\x1F\x80-\xFF]/', '', $result), true );
echo "<pre>";
print_r($final_result);
I'm going to rewrite this POST request in python:
<?php
// Set these variables
$networkid = ""; // In your HasOffers system at Support -> API
$apikey = ""; // In your HasOffers system at Support -> API
$offerid = "0"; // Specify an offer ID to add the creative to
$creativetype = "image banner"; // Types: file, image banner, flash banner, email creative, offer thumbnail, text ad, html ad, hidden
$filename = "banner_728x90.gif"; // File name; no spaces, and file must be in same directory as this script
$display = $filename; // Or change this to the "display name" for this creative
// Don't change anything below here
$creativetype = urlencode($creativetype);
$display = urlencode($display);
$fields[$filename] = "#{$filename}";
$url = "http://api.hasoffers.com/v3/OfferFile.json?Method=create&NetworkToken={$apikey}&NetworkId={$networkid}&data[offer_id]={$offerid}&data[type]={$creativetype}&data[display]={$display}&return_object=1";
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields);
$resp = curl_exec($ch);
curl_close($ch);
print_r(json_decode($resp, true)); // Final output; remove or change this if you want
?>
As I know, in pycurl the CURLOPT_POSTFIELDS attribute is absent. What can I use instead?
Thank you!
there are many python libraries that can be used:
http.client
https://docs.python.org/3.1/library/http.client.html
requests
https://pypi.python.org/pypi/requests/
the commands are pretty straightforwards:
using http.client:
import http.client
conn = http.client.HTTPConnection("www.python.org")
conn.request("HEAD","/index.html")
res = conn.getresponse()
print(res.status, res.reason)
200 OK
or requests:
import requests
r = requests.get('https://github.com/timeline.json')
print r.json
Using HTTP client, a simple POST request may be done as follows:
connect = http.client.HTTPSConnection("base_url")
connect.request('POST', '/rest/api/'+ you_can_add_variables+ '/users?userEmail=' + another_variable, headers=headers)
Using requests:
import json
url = 'https://api.github.com/some/endpoint'
payload = {'some': 'data'}
headers = {'content-type': 'application/json'}
r = requests.post(url, data=json.dumps(payload), headers=headers)
the documentation provided above should not prove difficult to understand
I should start by saying I have no php experience what so ever, but I know this script can't be that ambitious.
I'm using Wordpress' metaWeblog API to batch the creation of several hundred posts. Each post needs a discrete title, a description, and url's for two images, the latter being custom fields.
I have been successful producing one post by manually entering data into the following file;
<?php // metaWeblog.Post.php
$BLOGURL = "http://path/to/your/wordpress";
$USERNAME = "username";
$PASSWORD = "password";
function get_response($URL, $context) {
if(!function_exists('curl_init')) {
die ("Curl PHP package not installed\n");
}
/*Initializing CURL*/
$curlHandle = curl_init();
/*The URL to be downloaded is set*/
curl_setopt($curlHandle, CURLOPT_URL, $URL);
curl_setopt($curlHandle, CURLOPT_HEADER, false);
curl_setopt($curlHandle, CURLOPT_HTTPHEADER, array("Content-Type: text/xml"));
curl_setopt($curlHandle, CURLOPT_POSTFIELDS, $context);
/*Now execute the CURL, download the URL specified*/
$response = curl_exec($curlHandle);
return $response;
}
function createPost(){
/*The contents of your post*/
$description = "post description";
/*Forming the content of blog post*/
$content['title'] = $postTitle;
$content['description'] = $description;
/*Pass custom fields*/
$content['custom_fields'] = array(
array( 'key' => 'port_thumb_image_url', 'value' => "$imagePath" ),
array( 'key' => 'port_large_image_url', 'value' => "$imagePath" )
);
/*Whether the post has to be published*/
$toPublish = false;//false means post will be draft
$request = xmlrpc_encode_request("metaWeblog.newPost",
array(1,$USERNAME, $PASSWORD, $content, $toPublish));
/*Making the request to wordpress XMLRPC of your blog*/
$xmlresponse = get_response($BLOGURL."/xmlrpc.php", $request);
$postID = xmlrpc_decode($xmlresponse);
echo $postID;
}
?>
In an attempt to keep this short, here is the most basic example of the script that iterates through a directory and is "supposed" to pass the variables $postTitle, and $imagePath and create the posts.
<?php // fileLoop.php
require('path/to/metaWeblog.Post.php');
$folder = 'foldername';
$urlBase = "images/portfolio/$folder";//truncate path to images
if ($handle = opendir("path/to/local/images/portfolio/$folder/")) {
/*Loop through files in truncated directory*/
while (false !== ($file = readdir($handle))) {
$info = pathinfo($file);
$file_name = basename($file,'.'.$info['extension']); // strip file extension
$postTitle = preg_replace("/\.0|\./", " ", $file_name); // Make file name suitable for post title !LEAVE!
echo "<tr><td>$postTitle</td>";
$imagePath = "$urlBase/$file";
echo " <td>$urlBase/$file</td>";
createPost($postTitle, $imagePath);
}
closedir($handle);
}
?>
It's supposed to work like this,
fileLoop.php opens the directory and iterates through each file
for each file in the directory, a suitable post title(postTitle) is created and a url path(imagePath) to the server's file is made
each postTitle and imagePath is passed to the function createPost in metaWeblog.php
metaWeblog.php creates the post and passes back the post id to finish creating the table row for each file in the directory.
I've tried declaring the function in fileLoop.php, I've tried combining the files completely. It either creates the table with all files, or doesn't step through the directory that way. I'm missing something, I know it.
I don't know how to incorporate $POST_ here, or use sessions as I said I'm very new to programming in php.
You need to update your declaration of the createPost() function so that it takes into account the parameters you are attempting to send it.
So it should be something like this:
function createPost($postTitle, $imagePath){
/*The contents of your post*/
$description = "post description";
...
}
More information about PHP function arguments can be found on the associated manual page.
Once this has been remedied you can use CURL debugging to get more information about your external request. To get more information about a CURL request try setting the following options:
/*Initializing CURL*/
$curlHandle = curl_init();
/*The URL to be downloaded is set*/
curl_setopt($curlHandle, CURLOPT_URL, $URL);
curl_setopt($curlHandle, CURLOPT_HEADER, false);
curl_setopt($curlHandle, CURLOPT_HTTPHEADER, array("Content-Type: text/xml"));
curl_setopt($curlHandle, CURLOPT_POSTFIELDS, $context);
curl_setopt($curlHandle, CURLOPT_HEADER, true); // Display headers
curl_setopt($curlHandle, CURLOPT_VERBOSE, true); // Display communication with server
/*Now execute the CURL, download the URL specified*/
$response = curl_exec($curlHandle);
print "<pre>\n";
print_r(curl_getinfo($ch)); // get error info
echo "\n\ncURL error number:" .curl_errno($ch); // print error info
echo "\n\ncURL error:" . curl_error($ch);
print "</pre>\n";
The above debug example code is from eBay's help pages.
It should show you if Wordpress is rejecting the request.
I'm trying to convert this PHP cURL function to work with my rails app. The piece of code is from an SMS payment gateway that needs to verify the POST paramters. Since I'm a big PHP noob I have no idea how to handle this problem.
$verify_url = 'http://smsgatewayadress';
$fields = '';
$d = array(
'merchant_ID' => $_POST['merchant_ID'],
'local_ID' => $_POST['local_ID'],
'total' => $_POST['total'],
'ipn_verify' => $_POST['ipn_verify'],
'timeout' => 10,
);
foreach ($d as $k => $v)
{
$fields .= $k . "=" . urlencode($v) . "&";
}
$fields = substr($fields, 0, strlen($fields)-1);
$ch = curl_init($verify_url); //this initiates a HTTP connection to $verify_url, the connection headers will be stored in $ch
curl_setopt($ch, CURLOPT_POST, 1); //sets the delivery method as POST
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields); //The data that is being sent via POST. From what I can see the cURL lib sends them as a string that is built in the foreach loop above
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1); //This verifies if the target url sends a redirect header and if it does cURL follows that link
curl_setopt($ch, CURLOPT_HEADER, 0); //This ignores the headers from the answer
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); //This specifies that the curl_exec function below must return the result to the accesed URL
$result = curl_exec($ch); //It ransfers the data via POST to the URL, it gets read and returns the result
if ($result == true)
{
//confirmed
$can_download = true;
}
else
{
//failed
$can_download = false;
}
}
if (strpos($_SERVER['REQUEST_URI'], 'ipn.php'))
echo $can_download ? '1' : '0'; //we tell the sms sever that we processed the request
I've googled a cURL lib counterpart in Rails and found a ton of options but none that I could understand and use in the same way this script does.
If anyone could give me a hand with converting this script from php to ruby it would be greatly appreciated.
The most direct approach might be to use the Ruby curb library, which is the most straightforward wrapper for cURL. A lot of the options in Curl::Easy map directly to what you have here. A basis might be:
url = "http://smsgatewayadress/"
Curl::Easy.http_post(url,
Curl::PostField.content('merchant_ID', params[:merchant_ID]),
# ...
)