Call Sharepoint WebService with PHP SoapClient - php

I extended the PHP SoapClient to use it with NTLM Sharepoint Authentication:
class NTLMSoapClient extends SoapClient {
function __doRequest($request, $location, $action, $version) {
$headers = array(
'Method: POST',
'Connection: Keep-Alive',
'User-Agent: PHP-SOAP-CURL',
'Content-Type: text/xml; charset=utf-8',
'SOAPAction: "' . $action . '"',
);
$this->__last_request_headers = $headers;
$ch = curl_init($location);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, false);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $request);
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_setopt($ch, CURLOPT_USERPWD, $this->user . ':' . $this->password);
$response = curl_exec($ch);
return $response;
}
function __getLastRequestHeaders() {
return implode("n", $this->__last_request_headers) . "n";
}
public final function __call($methodName, array $methodParams) {
/*
* Is soapClient set? This check may look double here but in later
* developments it might help to trace bugs better and it avoids calls
* on wrong classes if $soapClient got set to something not SoapClient.
*/
if (!$this->soapClient instanceof \SoapClient) {
// Is not set
throw new \Exception('Variable soapClient is not a SoapClient class, have: ' . gettype($this->soapClient), 0xFF);
}
// Is it a "SOAP callback"?
if (substr($methodName, 0, 2) == '__') {
// Is SoapClient's method
$returned = call_user_func_array(array($this->soapClient, $methodName), $methodParams);
} else {
// Call it
$returned = $this->soapClient->__call($methodName, $methodParams);
}
// Return any values
return $returned;
}
}
class SPNTLMSoapClient extends NTLMSoapClient {
protected $user = 'xxxxxx';
protected $password = 'xxxxxxx';
}
class NTLMStream {
private $path;
private $mode;
private $options;
private $opened_path;
private $buffer;
private $pos;
public function stream_open($path, $mode, $options, $opened_path) {
echo "[NTLMStream::stream_open] $path , mode=$mode n";
$this->path = $path;
$this->mode = $mode;
$this->options = $options;
$this->opened_path = $opened_path;
$this->createBuffer($path);
return true;
}
public function stream_close() {
echo "[NTLMStream::stream_close] n";
curl_close($this->ch);
}
public function stream_read($count) {
echo "[NTLMStream::stream_read] $count n";
if (strlen($this->buffer) == 0) {
return false;
}
$read = substr($this->buffer, $this->pos, $count);
$this->pos += $count;
return $read;
}
public function stream_write($data) {
echo "[NTLMStream::stream_write] n";
if (strlen($this->buffer) == 0) {
return false;
}
return true;
}
public function stream_eof() {
echo "[NTLMStream::stream_eof] ";
if ($this->pos > strlen($this->buffer)) {
echo "true n";
return true;
}
echo "false n";
return false;
}
/* return the position of the current read pointer */
public function stream_tell() {
echo "[NTLMStream::stream_tell] n";
return $this->pos;
}
public function stream_flush() {
echo "[NTLMStream::stream_flush] n";
$this->buffer = null;
$this->pos = null;
}
public function stream_stat() {
echo "[NTLMStream::stream_stat] n";
$this->createBuffer($this->path);
$stat = array(
'size' => strlen($this->buffer),
);
return $stat;
}
public function url_stat($path, $flags) {
echo "[NTLMStream::url_stat] n";
$this->createBuffer($path);
$stat = array(
'size' => strlen($this->buffer),
);
return $stat;
}
/* Create the buffer by requesting the url through cURL */
private function createBuffer($path) {
if ($this->buffer) {
return;
}
echo "[NTLMStream::createBuffer] create buffer from : $pathn";
$this->ch = curl_init($path);
curl_setopt($this->ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($this->ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($this->ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM);
curl_setopt($this->ch, CURLOPT_USERPWD, $this->user . ':' . $this->password);
echo $this->buffer = curl_exec($this->ch);
echo "[NTLMStream::createBuffer] buffer size : " . strlen($this->buffer) . "bytesn";
$this->pos = 0;
}
}
class SPNTLMStream extends NTLMStream {
protected $user = 'xxxxxxx';
protected $password = 'xxxxxxxx';
}
stream_wrapper_unregister('https');
stream_wrapper_register('https', 'SPNTLMStream') or die("Failed to register protocol");
$wsdl = "https://wxxxxxxxxx?WSDL";
$client = new SPNTLMSoapClient($wsdl);
I succesfully call: "print_r($client->__getFunctions())" and get the following:
Array
(
[0] => CopyIntoItemsLocalResponse CopyIntoItemsLocal(CopyIntoItemsLocal $parameters)
[1] => CopyIntoItemsResponse CopyIntoItems(CopyIntoItems $parameters)
[2] => GetItemResponse GetItem(GetItem $parameters)
[3] => CopyIntoItemsLocalResponse CopyIntoItemsLocal(CopyIntoItemsLocal $parameters)
[4] => CopyIntoItemsResponse CopyIntoItems(CopyIntoItems $parameters)
[5] => GetItemResponse GetItem(GetItem $parameters)
)
My Question now is: How do I call these Methods with $client and parameters,
$client->__call('CopyIntoItems', $params) doesnt work
$client->CopyIntoItems($params) doesnt work
I never get any Response.....
Thx in advance....

Related

Fatal error: Cannot declare class InterdraftFactuursturen, because the name is already in use in

I'm coding my first Wordpress plugin and I need to use a separate class which exists in the fsnl_api.class.php file. But no matter what I do I always get the following error message:
Fatal error: Cannot declare class InterdraftFactuursturen, because the name is already in use in
There is no other class with the same name, but when I refer to that file I always get that error. Hereunder you'll see a bit of the code in the main file. Can anyone please tell me why this is happening? I'm searching for hours right now to find a solution and I'm getting desperate and frustrated.
require_once('fsnl_api.class.php');
if (!function_exists('add_action')) {
echo "You can't access this file!";
exit;
}
class InterdraftFactuursturen {
function __construct() {
add_action('init', array($this, 'custom_post_type'));
}
// some functions
}
if (class_exists('InterdraftFactuursturen')) {
$interdraftFactuursturen = new InterdraftFactuursturen();
}
register_activation_hook( __FILE__, array($interdraftFactuursturen, 'activate') );
register_deactivation_hook( __FILE__, array($interdraftFactuursturen, 'deactivate') );
The fsnl_api.class.php class
class fsnl_api
{
protected $url;
protected $verb;
protected $requestBody;
protected $requestLength;
protected $username;
protected $password;
protected $acceptType;
protected $responseBody;
protected $responseInfo;
public function __construct ($url = null, $verb = 'GET', $requestBody = null)
{
$this->url = $url;
$this->verb = $verb;
$this->requestBody = $requestBody;
$this->requestLength = 0;
$this->username = null;
$this->password = null;
$this->acceptType = 'application/json';
$this->responseBody = null;
$this->responseInfo = null;
if ($this->requestBody !== null)
{
$this->buildPostBody();
}
}
public function flush ()
{
$this->requestBody = null;
$this->requestLength = 0;
$this->verb = 'GET';
$this->responseBody = null;
$this->responseInfo = null;
}
public function execute ()
{
$ch = curl_init();
$this->setAuth($ch);
try
{
switch (strtoupper($this->verb))
{
case 'GET':
$this->executeGet($ch);
break;
case 'POST':
$this->executePost($ch);
break;
case 'PUT':
$this->executePut($ch);
break;
case 'DELETE':
$this->executeDelete($ch);
break;
default:
throw new InvalidArgumentException('Current verb (' . $this->verb . ') is an invalid REST verb.');
}
}
catch (InvalidArgumentException $e)
{
curl_close($ch);
throw $e;
}
catch (Exception $e)
{
curl_close($ch);
throw $e;
}
}
public function buildPostBody ($data = null)
{
$data = ($data !== null) ? $data : $this->requestBody;
if (!is_array($data))
{
throw new InvalidArgumentException('Invalid data input for postBody. Array expected');
}
$data = http_build_query($data, '', '&');
$this->requestBody = $data;
}
protected function executeGet ($ch)
{
$this->doExecute($ch);
}
protected function executePost ($ch)
{
if (!is_string($this->requestBody))
{
$this->buildPostBody();
}
curl_setopt($ch, CURLOPT_POSTFIELDS, $this->requestBody);
curl_setopt($ch, CURLOPT_POST, 1);
$this->doExecute($ch);
}
protected function executePut ($ch)
{
if (!is_string($this->requestBody))
{
$this->buildPostBody();
}
$this->requestLength = strlen($this->requestBody);
$fh = fopen('php://memory', 'rw');
fwrite($fh, $this->requestBody);
rewind($fh);
curl_setopt($ch, CURLOPT_INFILE, $fh);
curl_setopt($ch, CURLOPT_INFILESIZE, $this->requestLength);
curl_setopt($ch, CURLOPT_PUT, true);
$this->doExecute($ch);
fclose($fh);
}
protected function executeDelete ($ch)
{
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE');
$this->doExecute($ch);
}
protected function doExecute (&$curlHandle)
{
$this->setCurlOpts($curlHandle);
$this->responseBody = curl_exec($curlHandle);
$this->responseInfo = curl_getinfo($curlHandle);
curl_close($curlHandle);
}
protected function setCurlOpts (&$curlHandle)
{
curl_setopt($curlHandle, CURLOPT_TIMEOUT, 10);
curl_setopt($curlHandle, CURLOPT_URL, $this->url);
curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curlHandle, CURLOPT_HTTPHEADER, array ('Accept: ' . $this->acceptType));
}
protected function setAuth (&$curlHandle)
{
if ($this->username !== null && $this->password !== null)
{
curl_setopt($curlHandle, CURLOPT_HTTPAUTH, CURLAUTH_BASIC);
curl_setopt($curlHandle, CURLOPT_USERPWD, $this->username . ':' . $this->password);
}
}
public function getAcceptType ()
{
return $this->acceptType;
}
public function setAcceptType ($acceptType)
{
$this->acceptType = $acceptType;
}
public function getPassword ()
{
return $this->password;
}
public function setPassword ($password)
{
$this->password = $password;
}
public function getResponseBody ()
{
return $this->responseBody;
}
public function getResponseInfo ()
{
return $this->responseInfo;
}
public function getUrl ()
{
return $this->url;
}
public function setUrl ($url)
{
$this->url = $url;
}
public function getUsername ()
{
return $this->username;
}
public function setUsername ($username)
{
$this->username = $username;
}
public function getVerb ()
{
return $this->verb;
}
public function setVerb ($verb)
{
$this->verb = $verb;
}
}
Try to use diffrent name or namespace this class.
May be somewhere in Wordpress this class exists.
I would recommend you for the future, when you create own class to always namespace Your class. It is a good practice to namespace your own classes.
https://www.php.net/manual/en/language.namespaces.php
You can namespace your class for example (if you really want to have all in one file) like below:
namespace YourPluginName {
class InterdraftFactuursturen {
// Code
}
}
namespace {
$interdraftFactuursturen = new YourPluginName\InterdraftFactuursturen();
}
But I would recommend to store your class namespaced in other file then import by using require_once.
Check official documentation for more informations.

PHP Curl stops after some requests

I have a class that login to a coffee machine. I have a laravel app that "scan" all the coffee machines given in a range of IP address.
The problem is that Curl stops after 39, 128 or even 90 requests. So, I don't know what is the problem or if is a memory leak because PHP and Curl doesn't show any error.
I need advice or tips how to achieve this type of problem. Below is my code.
CoffeeMachine class
<?php
namespace Starbucks\CoffeeMachine;
class CoffeeMachine
{
private $url = '';
private $username = '';
private $password = '';
private $session;
private $response;
private $responses;
private $lastMessage = '';
private $lastStatus = FALSE;
private $authenticated = FALSE;
private function setFailStatus($message = '')
{
$this->lastStatus = FALSE;
$this->lastMessage = $message;
return FALSE;
}
private function setSuccessStatus($message = '')
{
$this->lastStatus = TRUE;
$this->lastMessage = $message;
return TRUE;
}
public function __construct($url = '', $username = 'admin', $password = 'admin')
{
$this->boot();
$this->url = $url;
$this->username = $username;
$this->password = $password;
$this->session = curl_init();
curl_setopt($this->session, CURLOPT_CONNECTTIMEOUT, 5);
curl_setopt($this->session, CURLOPT_FAILONERROR, 1);
curl_setopt($this->session, CURLOPT_FORBID_REUSE, 1);
curl_setopt($this->session, CURLOPT_FRESH_CONNECT, 1);
}
public function getResponse()
{
return $this->response;
}
public function login()
{
curl_setopt($this->session, CURLOPT_URL, $this->url . '/cgi-bin/dologin');
curl_setopt($this->session, CURLOPT_POST, 1);
curl_setopt($this->session, CURLOPT_POSTFIELDS, array(
'username' => $this->username,
'password' => $this->password
)
);
curl_setopt($this->session, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this->session, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($this->session, CURLOPT_HEADER, 0);
$response = curl_exec($this->session);
$response = json_decode($response, 1);
if (!isset($response['response'])) return $this->setFailStatus('Auth with no data...');
if ($response['response'] != 'success') return $this->setFailStatus('Access denied...');
$this->response = $response;
$this->lastStatus = TRUE;
$this->lastMessage = 'OK';
$this->authenticated = TRUE;
return TRUE;
}
public function getDeviceInfo()
{
}
public function logout()
{
curl_close($this->session);
}
}
Discover method in a range of IP
<?php
public function discover(Request $request)
{
$from = ip2long($request->input('from', '0.0.0.0'));
$to = ip2long($request->input('to', '255.255.255.255'));
$ips = array();
// CHUNK IN GROUPS OF 10 FOR WAIT 60 SECONDS, BUT NOT WORK
for($i = $from; $i < $to; $i++) $ips[] = long2ip($i);
$group_of_ips = array_chunk($ips, 10);
// TESTED THIS AND NOT WORK
$default_max_execution_time = ini_get('max_execution_time');
ini_set('max_execution_time', ((abs($from - $to) * 5) + (count($group_of_ips) * 60)) );
$machine_ips = array();
foreach($group_of_ips as $index => $row) {
foreach($row as $ip) {
$gs = new CoffeeMachine($ip, 'admin', 'admin');
if ($gs->login()) {
$machine_ips[] = $ip;
}
$gs->logout();
}
sleep(60); // TESTED THIS AND NOT WORK
}
ini_set('max_execution_time', $default_max_execution_time);
/* RETURN THE COFFEE MACHINE IP ADDRESS */
return $machine_ips;
}
add more error checking. some snippets from my curl wrapper, hhb_curl:
$this->curlh = curl_init ( '' ); // why empty string? PHP Fatal error: Uncaught TypeError: curl_init() expects parameter 1 to be string, null given
if (! $this->curlh) {
throw new RuntimeException ( 'curl_init failed!' );
}
here i verify that curl_init managed to create a curl resource, if it didn't, i throw a RuntimeException. you should do the same.
$ret = curl_exec ( $this->curlh );
if ($this->errno ()) {
throw new RuntimeException ( 'curl_exec failed. errno: ' . var_export ( $this->errno (), true ) . ' error: ' . var_export ( $this->error (), true ) );
}
here, i verify that curl_exec didn't register any errors, else i throw a RuntimeException. you should do the same. (it uses curl_errno($ch) )
function setopt_array(array $options): bool {
foreach ( $options as $option => $value ) {
$this->setopt ( $option, $value );
}
return true;
}
here i make sure my setopt_array doesn't actually use curl_setopt_array, but my own curl_setopt wrapper, you should do the same, for reasons explained below.
private function _setopt(int $option, $value): bool {
$ret = curl_setopt ( $this->curlh, $option, $value );
if (! $ret) {
throw new InvalidArgumentException ( 'curl_setopt failed. errno: ' . $this->errno () . '. error: ' . $this->error () . '. option: ' . var_export ( $this->_curlopt_name ( $option ), true ) . ' (' . var_export ( $option, true ) . '). value: ' . var_export ( $value, true ) );
}
$this->curloptions [$option] = $value;
return $ret; // true...
}
here i verify that curl_setopt succeeded, if it didn't, i throw an InvalidArgumentException, you should do the same (or at least throw some kind of exception, rather than the silent ignore your current code does.), and unlike curl_setopt_array, you can actually easily determine which option couldn't be set.
and when debugging curl code, always set CURLOPT_VERBOSE. (hhb_curl always does this, and gives curl a CURLOPT_STDERR tempfile() to put the verbose/error logs in, and gives you the logs through $hc->getStdErr() ), you should at least add some form of CURLOPT_VERBOSE support for debugging. my curl wrapper, hhb_curl, is available here https://github.com/divinity76/hhb_.inc.php/blob/master/hhb_.inc.php
Adding a timeout to the curl execution solves the problem. You need to monitor the response time for each device you want to reach. for me, 10 seconds for CONNECTTIMEOUT and TIMEOUT works fine.
<?php
namespace Starbucks\CoffeeMachine;
class CoffeeMachine
{
private $url = '';
private $username = '';
private $password = '';
private $session;
private $response;
private $responses;
private $lastMessage = '';
private $lastStatus = FALSE;
private $authenticated = FALSE;
private function setFailStatus($message = '')
{
$this->lastStatus = FALSE;
$this->lastMessage = $message;
return FALSE;
}
private function setSuccessStatus($message = '')
{
$this->lastStatus = TRUE;
$this->lastMessage = $message;
return TRUE;
}
public function __construct($url = '', $username = 'admin', $password = 'admin')
{
$this->boot();
$this->url = $url;
$this->username = $username;
$this->password = $password;
$this->session = curl_init();
curl_setopt($this->session, CURLOPT_CONNECTTIMEOUT, 10);
curl_setopt($this->session, CURLOPT_TIMEOUT, 10);
curl_setopt($this->session, CURLOPT_FAILONERROR, 1);
curl_setopt($this->session, CURLOPT_FORBID_REUSE, 1);
curl_setopt($this->session, CURLOPT_FRESH_CONNECT, 1);
}
public function getResponse()
{
return $this->response;
}
public function login()
{
curl_setopt($this->session, CURLOPT_URL, $this->url . '/cgi-bin/dologin');
curl_setopt($this->session, CURLOPT_POST, 1);
curl_setopt($this->session, CURLOPT_POSTFIELDS, array(
'username' => $this->username,
'password' => $this->password
)
);
curl_setopt($this->session, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($this->session, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($this->session, CURLOPT_HEADER, 0);
$response = curl_exec($this->session);
if (curl_errno($this->session)) {
$msg = $this->url . "\n" . curl_errno($this->session) . "\n" . curl_error($this->session);
return $this->setFailStatus($msg);
}
$response = json_decode($response, 1);
if (!isset($response['response'])) return $this->setFailStatus('Auth with no data...');
if ($response['response'] != 'success') return $this->setFailStatus('Access denied...');
$this->response = $response;
$this->lastStatus = TRUE;
$this->lastMessage = 'OK';
$this->authenticated = TRUE;
return TRUE;
}
public function getDeviceInfo()
{
}
public function logout()
{
curl_close($this->session);
}
}
Now I can loop and reach CoffeeMachines =)

Shopify private app- php

updated shopify.php
<?php
include('shopify_api_config.php');
class ShopifyClient {
public $shop_domain;
private $token;
private $api_key;
private $secret;
private $last_response_headers = null;
public function __construct($shop_domain, $token, $api_key, $secret) {
$this->name = "ShopifyClient";
$this->shop_domain = 'https://#4ef34cd22b136c1a7b869e77c8ce8b3c:#fb2b17c283a27c65e4461d0ce8e5871b#discountshop-8.myshopify.com';
$this->token = $token;
$this->api_key = '4ef34cd22b136c1a7b869e77c8ce8b3c';
$this->secret = '28cdbeb0b925bba5b8c9a60cfbb8c3cb';
$client = new ShopifyClient($shop_domain, $token, $api_key, $secret);
}
// Get the URL required to request authorization
public function getAuthorizeUrl($scope, $redirect_url='') {
$url = "http://{$this->shop_domain}/admin/oauth/authorize?client_id={$this->api_key}&scope=" . urlencode($scope);
if ($redirect_url != '')
{
$url .= "&redirect_uri=" . urlencode($redirect_url);
}
return $url;
}
// Once the User has authorized the app, call this with the code to get the access token
public function getAccessToken($code) {
// POST to POST https://SHOP_NAME.myshopify.com/admin/oauth/access_token
$url = "https://{$this->shop_domain}/admin/oauth/access_token";
$payload = "client_id={$this->api_key}&client_secret={$this->secret}&code=$code";
$response = $this->curlHttpApiRequest('POST', $url, '', $payload, array());
$response = json_decode($response, true);
if (isset($response['access_token']))
return $response['access_token'];
return '';
}
public function callsMade()
{
return $this->shopApiCallLimitParam(0);
}
public function callLimit()
{
return $this->shopApiCallLimitParam(1);
}
public function callsLeft($response_headers)
{
return $this->callLimit() - $this->callsMade();
}
public function call($method, $path, $params=array())
{
$baseurl = "https://{$this->shop_domain}/";
$url = $baseurl.ltrim($path, '/');
$query = in_array($method, array('GET','DELETE')) ? $params : array();
$payload = in_array($method, array('POST','PUT')) ? stripslashes(json_encode($params)) : array();
$request_headers = in_array($method, array('POST','PUT')) ? array("Content-Type: application/json; charset=utf-8", 'Expect:') : array();
// add auth headers
$request_headers[] = 'X-Shopify-Access-Token: ' . $this->token;
$response = $this->curlHttpApiRequest($method, $url, $query, $payload, $request_headers);
$response = json_decode($response, true);
if (isset($response['errors']) or ($this->last_response_headers['http_status_code'] >= 400))
throw new ShopifyApiException($method, $path, $params, $this->last_response_headers, $response);
return (is_array($response) and (count($response) > 0)) ? array_shift($response) : $response;
}
public function validateSignature($query)
{
if(!is_array($query) || empty($query['signature']) || !is_string($query['signature']))
return false;
foreach($query as $k => $v) {
if($k == 'signature') continue;
$signature[] = $k . '=' . $v;
}
sort($signature);
$signature = md5($this->secret . implode('', $signature));
return $query['signature'] == $signature;
}
private function curlHttpApiRequest($method, $url, $query='', $payload='', $request_headers=array())
{
$url = $this->curlAppendQuery($url, $query);
$ch = curl_init($url);
$this->curlSetopts($ch, $method, $payload, $request_headers);
$response = curl_exec($ch);
$errno = curl_errno($ch);
$error = curl_error($ch);
curl_close($ch);
if ($errno) throw new ShopifyCurlException($error, $errno);
list($message_headers, $message_body) = preg_split("/\r\n\r\n|\n\n|\r\r/", $response, 2);
$this->last_response_headers = $this->curlParseHeaders($message_headers);
return $message_body;
}
private function curlAppendQuery($url, $query)
{
if (empty($query)) return $url;
if (is_array($query)) return "$url?".http_build_query($query);
else return "$url?$query";
}
private function curlSetopts($ch, $method, $payload, $request_headers)
{
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_USERAGENT, 'ohShopify-php-api-client');
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, $method);
if (!empty($request_headers)) curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
if ($method != 'GET' && !empty($payload))
{
if (is_array($payload)) $payload = http_build_query($payload);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $payload);
}
}
private function curlParseHeaders($message_headers)
{
$header_lines = preg_split("/\r\n|\n|\r/", $message_headers);
$headers = array();
list(, $headers['http_status_code'], $headers['http_status_message']) = explode(' ', trim(array_shift($header_lines)), 3);
foreach ($header_lines as $header_line)
{
list($name, $value) = explode(':', $header_line, 2);
$name = strtolower($name);
$headers[$name] = trim($value);
}
return $headers;
}
private function shopApiCallLimitParam($index)
{
if ($this->last_response_headers == null)
{
throw new Exception('Cannot be called before an API call.');
}
$params = explode('/', $this->last_response_headers['http_x_shopify_shop_api_call_limit']);
return (int) $params[$index];
}
}
class ShopifyCurlException extends Exception { }
class ShopifyApiException extends Exception
{
protected $method;
protected $path;
protected $params;
protected $response_headers;
protected $response;
function __construct($method, $path, $params, $response_headers, $response)
{
$this->method = $method;
$this->path = $path;
$this->params = $params;
$this->response_headers = $response_headers;
$this->response = $response;
parent::__construct($response_headers['http_status_message'], $response_headers['http_status_code']);
}
function getMethod() { return $this->method; }
function getPath() { return $this->path; }
function getParams() { return $this->params; }
function getResponseHeaders() { return $this->response_headers; }
function getResponse() { return $this->response; }
}
?>
I installed one private app in my shopify store for download csv file, after installed, when click download button, it will display like
Fatal error: Uncaught exception 'ShopifyCurlException' with message 'Could not
resolve host: http:; Host not found' in C:\xampp\htdocs\cat\lib\shopify.php:102
Stack trace: #0 C:\xampp\htdocs\cat\lib\shopify.php(67): ShopifyClient->curlHttpApiRequest('GET', 'https://http://...', Array, Array, Array)
#1 C:\xampp\htdocs\cat\index-oauth.php(26): ShopifyClient->call('GET', 'admin/orders.js...', Array)
#2 {main} thrown in C:\xampp\htdocs\cat\lib\shopify.php on line 102.
I dont know how to fix. If anybody know, please help.
Thank you!.
I had the same problem. Try this.
In your constructor pass the following argument as the $shop_domain.
https:// #apikey:#password#hostname
Replace #apiKey, #password and hostname with your values. Also leave '#' in hostname.
I.e. #yourshop.com
$shop_domain = 'https://#apikey:#password#hostname';
$token = 'your token';
$key = 'your key';
$secret = 'your secret';
$client = new ShopifyClient($shop_domain, $token, $api_key, $secret);

DialMyCalls where do I put the API Key

I'm trying to pull data from the DialMyCalls database and add data to it. They sent me some code and I have found my API key but I don't know how to connect it all. I uploaded the PHP code onto my server and tried running it but I get no results because I'm not exactly sure what to edit. I know I need to edit the "null" areas I presume but I'm not entirely sure. Any help is welcomed.
here is the code they sent me, so if you could tell me what to edit to pull information from their database I'd be grateful. Thanks.
<?php
class RestRequest
{
protected $url;
protected $verb;
protected $requestBody;
protected $requestLength;
protected $apikey;
protected $acceptType;
var $responseBody;
protected $responseInfo;
public function __construct ($apikey = null) {
$this->url = null;
$this->verb = null;
$this->requestBody = null;
$this->requestLength = 0;
$this->apikey = $apikey;
$this->acceptType = 'application/json';
$this->responseBody = null;
$this->responseInfo = null;
}
public function flush ()
{
$this->requestBody = null;
$this->requestLength = 0;
$this->verb = 'POST';
$this->responseBody = null;
$this->responseInfo = null;
}
public function execute ($url = null, $verb = 'POST', $requestBody = null) {
$ch = curl_init();
$this->url = "https://www.dialmycalls.com/api".$url;
$this->verb = $verb;
$this->requestBody = $requestBody;
try
{
switch (strtoupper($this->verb))
{
case 'POST':
$this->doExecute($ch);
break;
default:
throw new InvalidArgumentException('Current verb (' . $this->verb . ') is an invalid REST verb.');
}
}
catch (InvalidArgumentException $e)
{
curl_close($ch);
throw $e;
}
catch (Exception $e)
{
curl_close($ch);
throw $e;
}
}
protected function doExecute (&$curlHandle) {
curl_setopt($curlHandle, CURLOPT_POST, 1);
$this->requestBody["apikey"] = $this->apikey;
curl_setopt($curlHandle, CURLOPT_POSTFIELDS, $this->requestBody);
// curl_setopt($curlHandle, CURLOPT_TIMEOUT, 60);
curl_setopt($curlHandle, CURLOPT_URL, $this->url);
curl_setopt($curlHandle, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curlHandle, CURLOPT_VERBOSE, 0);
curl_setopt($curlHandle, CURLOPT_HTTPHEADER, array ('Accept: ' . $this->acceptType,'Expect:'));
$this->responseBody = curl_exec($curlHandle);
$this->responseInfo = curl_getinfo($curlHandle);
curl_close($curlHandle);
}
}
?>
Thanks again for any help,
Matt
From what it looks like, you would just throw it in the constructor.
Example:
<?php
$rest = new RestRequest("yourAPIkey");
?>
Then you can do the rest. I noticed this because in the constructor it has
public function __construct ($apikey = null) {
Which means when you open the new class whatever variable is in the function __construct is what you would send in the new class.
Hope this helps.

Call to undefined function that isn't undefined?

So, when I try and run this line of code, I'm getting the following error:
Fatal error: Call to undefined function curl_http_api_request_() in /Applications/XAMPP/xamppfiles/htdocs/CI/application/libraries/Shopify.php on line 58
Where line 58 is specifically this line:
$response = curl_http_api_request_($method, $url, $query, $payload, $request_headers, $response_headers);
I'm not really sure why it can't call the second function. The code is below. I've got no clue and am at a loss as to what the issue is.
class Shopify
{
public $_api_key;
public $_shared_secret;
public $CI; // To hold the CI superglobal
public function __construct ()
{
$this->_assign_libraries(); // Loads the CI superglobal and loads the config into it
// Get values from the CI config
$this->_api_key = $this->CI->config->item('api_key', 'shopify');
$this->_shared_secret = $this->CI->config->item('shared_secret', 'shopify');
}
public function shopify_app_install_url($shop_domain)
{
return "http://$shop_domain/admin/api/auth?api_key=". $this->_api_key;
}
public function shopify_is_app_installed($shop, $t, $timestamp, $signature)
{
return (md5($this->_shared_secret . "shop={$shop}t={$t}timestamp={$timestamp}") === $signature);
}
public function shopify_api_client($shops_myshopify_domain, $shops_token, $private_app=false)
{
$password = $private_app ? $this->_shared_secret : md5($this->_shared_secret.$shops_token);
$baseurl = "https://" . $this->_api_key . ":$password#$shops_myshopify_domain/";
return function ($method, $path, $params=array(), &$response_headers=array()) use ($baseurl)
{
$url = $baseurl.ltrim($path, '/');
$query = in_array($method, array('GET','DELETE')) ? $params : array();
$payload = in_array($method, array('POST','PUT')) ? stripslashes(json_encode($params)) : array();
$request_headers = in_array($method, array('POST','PUT')) ? array("Content-Type: application/json; charset=utf-8", 'Expect:') : array();
$response = curl_http_api_request_($method, $url, $query, $payload, $request_headers, $response_headers);
$response = json_decode($response, true);
if (isset($response['errors']) or ($response_headers['http_status_code'] >= 400))
throw new ShopifyApiException(compact('method', 'path', 'params', 'response_headers', 'response', 'shops_myshopify_domain', 'shops_token'));
return (is_array($response) and (count($response) > 0)) ? array_shift($response) : $response;
};
}
public function curl_http_api_request_($method, $url, $query='', $payload='', $request_headers=array(), &$response_headers=array())
{
$url = curl_append_query_($url, $query);
$ch = curl_init($url);
curl_setopts_($ch, $method, $payload, $request_headers);
$response = curl_exec($ch);
$errno = curl_errno($ch);
$error = curl_error($ch);
curl_close($ch);
if ($errno) throw new ShopifyCurlException($error, $errno);
list($message_headers, $message_body) = preg_split("/\r\n\r\n|\n\n|\r\r/", $response, 2);
$response_headers = $this->curl_parse_headers_($message_headers);
return $message_body;
}
private function curl_append_query_($url, $query)
{
if (empty($query)) return $url;
if (is_array($query)) return "$url?".http_build_query($query);
else return "$url?$query";
}
private function curl_setopts_($ch, $method, $payload, $request_headers)
{
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_MAXREDIRS, 3);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_setopt($ch, CURLOPT_USERAGENT, 'HAC');
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
if ('GET' == $method)
{
curl_setopt($ch, CURLOPT_HTTPGET, true);
}
else
{
curl_setopt ($ch, CURLOPT_CUSTOMREQUEST, $method);
if (!empty($request_headers)) curl_setopt($ch, CURLOPT_HTTPHEADER, $request_headers);
if (!empty($payload))
{
if (is_array($payload)) $payload = http_build_query($payload);
curl_setopt ($ch, CURLOPT_POSTFIELDS, $payload);
}
}
}
private function curl_parse_headers_($message_headers)
{
$header_lines = preg_split("/\r\n|\n|\r/", $message_headers);
$headers = array();
list(, $headers['http_status_code'], $headers['http_status_message']) = explode(' ', trim(array_shift($header_lines)), 3);
foreach ($header_lines as $header_line)
{
list($name, $value) = explode(':', $header_line, 2);
$name = strtolower($name);
$headers[$name] = trim($value);
}
return $headers;
}
public function shopify_calls_made($response_headers)
{
return shopify_shop_api_call_limit_param_(0, $response_headers);
}
public function shopify_call_limit($response_headers)
{
return shopify_shop_api_call_limit_param_(1, $response_headers);
}
public function shopify_calls_left($response_headers)
{
return shopify_call_limit($response_headers) - shopify_calls_made($response_headers);
}
private function shopify_shop_api_call_limit_param_($index, $response_headers)
{
$params = explode('/', $response_headers['http_x_shopify_shop_api_call_limit']);
return (int) $params[$index];
}
/**
* Shopify::_assign_libraries()
*
* Grab everything from the CI superobject that we need
*/
public function _assign_libraries()
{
$this->CI =& get_instance();
$this->CI->load->config('shopify', TRUE);
return;
}
UPDATE:
This whole line is started off by me calling this line of code:
$shopify = $this->shopify->shopify_api_client($shops_myshopify_domain, $shops_token);
I have also updated the code above to include the entire file.
You can achieve it only by passing $this as object to anonymous function, as it has its own context:
class example {
public function trigger() {
$func = $this->func();
$func($this);
}
public function func() {
return function($obj) {
$obj->inner();
};
}
public function inner() {
die('inside inner');
}
}
$obj = new example();
$obj->trigger();
EDIT: So in response to your problem:
Change this line:
return function ($method, $path, $params=array(), &$response_headers=array()) use ($baseurl)
into this:
return function ($instance, $method, $path, $params=array(), &$response_headers=array()) use ($baseurl)
Inside anonymous function change this line:
$response = curl_http_api_request_($method, $url, $query, $payload, $request_headers, $response_headers);
into this:
$response = $instance->curl_http_api_request_($method, $url, $query, $payload, $request_headers, $response_headers);
Now shopify_api_client function will return you this ANONYMOUS FUNCTION with no error:
$shopify = $this->shopify->shopify_api_client($shops_myshopify_domain, $shops_token);
You need to call this function in this way:
$shopify($this->shopify, ... AND HERE THE REST OF ARGUMENTS WHICH ANONYMOUS FUNCTION REQUIRE ...);
Is it clearer now? I have never used shopify, but general way it should work is as I wrote.
If your accessing a method from outside the class you need to state it, if your accessing the method from within the class you need use $this->methodname()
<?php
class shopify_api{
...
...
...
public function curl_http_api_request_($method, $url, $query='', $payload='', $request_headers=array(), &$response_headers=array())
{
$url = curl_append_query_($url, $query);
$ch = curl_init($url);
curl_setopts_($ch, $method, $payload, $request_headers);
$response = curl_exec($ch);
$errno = curl_errno($ch);
$error = curl_error($ch);
curl_close($ch);
if ($errno) throw new ShopifyCurlException($error, $errno);
list($message_headers, $message_body) = preg_split("/\r\n\r\n|\n\n|\r\r/", $response, 2);
$response_headers = $this->curl_parse_headers_($message_headers);
return $message_body;
}
}
$shopify = new shopify_api();
//--------V
$response=$shopify->curl_http_api_request_();
?>
Since you have updated your question have you tried changing:
$shopify = $this->shopify->shopify_api_client($shops_myshopify_domain, $shops_token);
too: (as it seems your adding extra shopify property, i cant see from yourcode where you have set & injected your methods to it)
$shopify = $this->shopify_api_client($shops_myshopify_domain, $shops_token);

Categories