PHP API Call function is not working - php

I have a Question about calling a other script.
I want to make an api whit ExactOnline... But i need to call an other script for that I used "require DIR ." That works fine but my code still doesn't get the script. Can someone explane to me why this is not working?
(My script that need to call is in "C:\xampp\htdocs\CM\EO\exactphpclientmaster\vendor\picqer\exactphpclient\src\Picqer\Financials\Exact\Connection.php")
=ERROR=
Fatal error: Class 'vendor\picqer\exactphpclient\src\Picqer\Financials\Exact\Connection' not found in C:\xampp\htdocs\CM\EO\exactphpclientmaster\ConntectEO.php on line 3
=SCRIPT That is calling connection.php=
<?php
require __DIR__ . '\vendor\picqer\exactphpclient\src\Picqer\Financials\Exact\Connection.php';
$connection = new \vendor\picqer\exactphpclient\src\Picqer\Financials\Exact\Connection.php();
$connection->setRedirectUrl('**************************'); // Same as entered online in the App Center
$connection->setExactClientId('****************************************');
$connection->setExactClientSecret('************************');
if (getValue('authorizationcode')) // Retrieves authorizationcode from database
$connection->setAuthorizationCode(getValue('authorizationcode'));
if (getValue('accesstoken')) // Retrieves accesstoken from database
$connection->setAccessToken(unserialize(getValue('accesstoken')));
if (getValue('refreshtoken')) // Retrieves refreshtoken from database
$connection->setRefreshToken(getValue('refreshtoken'));
if (getValue('expires_in')) // Retrieves expires timestamp from database
$connection->setTokenExpires(getValue('expires_in'));
// Make the client connect and exchange tokens
try {
$connection->connect();
} catch (\Exception $e)
{
throw new Exception('Could not connect to Exact: ' . $e->getMessage());
}
// Save the new tokens for next connections
setValue('accesstoken', serialize($connection->getAccessToken()));
setValue('refreshtoken', $connection->getRefreshToken());
// Optionally, save the expiry-timestamp. This prevents exchanging valid tokens (ie. saves you some requests)
setValue('expires_in', $connection->getTokenExpires());
=SCRIPT Connection.php=
<?php namespace Picqer\Financials\Exact;
use Exception;
use GuzzleHttp\Client;
use GuzzleHttp\Exception\BadResponseException;
use GuzzleHttp\HandlerStack;
use GuzzleHttp\Psr7\Request;
use GuzzleHttp\Psr7\Response;
use GuzzleHttp\Psr7;
/**
* Class Connection
*
* #package Picqer\Financials\Exact
*
*/
class Connection
{
/**
* #var string
*/
private $baseUrl = 'https://start.exactonline.nl';
/**
* #var string
*/
private $apiUrl = '/api/v1';
/**
* #var string
*/
private $authUrl = '/api/oauth2/auth';
/**
* #var string
*/
private $tokenUrl = '/api/oauth2/token';
/**
* #var
*/
private $exactClientId;
/**
* #var
*/
private $exactClientSecret;
/**
* #var
*/
private $authorizationCode;
/**
* #var
*/
private $accessToken;
/**
* #var
*/
private $tokenExpires;
/**
* #var
*/
private $refreshToken;
/**
* #var
*/
private $redirectUrl;
/**
* #var
*/
private $division;
/**
* #var Client
*/
private $client;
/**
* #var callable(Connection)
*/
private $tokenUpdateCallback;
/**
*
*/
protected $middleWares = [];
/**
* #var
*/
public $nextUrl = null;
/**
* #return Client
*/
private function client()
{
if ($this->client) {
return $this->client;
}
$handlerStack = HandlerStack::create();
foreach ($this->middleWares as $middleWare) {
$handlerStack->push($middleWare);
}
$this->client = new Client([
'http_errors' => true,
'handler' => $handlerStack,
'expect' => false,
]);
return $this->client;
}
public function insertMiddleWare($middleWare)
{
$this->middleWares[] = $middleWare;
}
public function connect()
{
// Redirect for authorization if needed (no access token or refresh token given)
if ($this->needsAuthentication()) {
$this->redirectForAuthorization();
}
// If access token is not set or token has expired, acquire new token
if (empty($this->accessToken) || $this->tokenHasExpired()) {
$this->acquireAccessToken();
}
$client = $this->client();
return $client;
}
/**
* #param string $method
* #param $endpoint
* #param null $body
* #param array $params
* #param array $headers
* #return Request
*/
private function createRequest($method = 'GET', $endpoint, $body = null, array $params = [], array $headers = [])
{
// Add default json headers to the request
$headers = array_merge($headers, [
'Accept' => 'application/json',
'Content-Type' => 'application/json',
'Prefer' => 'return=representation'
]);
// If access token is not set or token has expired, acquire new token
if (empty($this->accessToken) || $this->tokenHasExpired()) {
$this->acquireAccessToken();
}
// If we have a token, sign the request
if (!$this->needsAuthentication() && !empty($this->accessToken)) {
$headers['Authorization'] = 'Bearer ' . $this->accessToken;
}
// Create param string
if (!empty($params)) {
$endpoint .= '?' . http_build_query($params);
}
// Create the request
$request = new Request($method, $endpoint, $headers, $body);
return $request;
}
/**
* #param $url
* #param array $params
* #return mixed
* #throws ApiException
*/
public function get($url, array $params = [])
{
$url = $this->formatUrl($url, $url !== 'current/Me', $url == $this->nextUrl);
try {
$request = $this->createRequest('GET', $url, null, $params);
$response = $this->client()->send($request);
return $this->parseResponse($response, $url != $this->nextUrl);
} catch (Exception $e) {
$this->parseExceptionForErrorMessages($e);
}
}
/**
* #param $url
* #param $body
* #return mixed
* #throws ApiException
*/
public function post($url, $body)
{
$url = $this->formatUrl($url);
try {
$request = $this->createRequest('POST', $url, $body);
$response = $this->client()->send($request);
return $this->parseResponse($response);
} catch (Exception $e) {
$this->parseExceptionForErrorMessages($e);
}
}
/**
* #param $url
* #param $body
* #return mixed
* #throws ApiException
*/
public function put($url, $body)
{
$url = $this->formatUrl($url);
try {
$request = $this->createRequest('PUT', $url, $body);
$response = $this->client()->send($request);
return $this->parseResponse($response);
} catch (Exception $e) {
$this->parseExceptionForErrorMessages($e);
}
}
/**
* #param $url
* #return mixed
* #throws ApiException
*/
public function delete($url)
{
$url = $this->formatUrl($url);
try {
$request = $this->createRequest('DELETE', $url);
$response = $this->client()->send($request);
return $this->parseResponse($response);
} catch (Exception $e) {
$this->parseExceptionForErrorMessages($e);
}
}
/**
* #return string
*/
public function getAuthUrl()
{
return $this->baseUrl . $this->authUrl . '?' . http_build_query(array(
'client_id' => $this->exactClientId,
'redirect_uri' => $this->redirectUrl,
'response_type' => 'code'
));
}
/**
* #param mixed $exactClientId
*/
public function setExactClientId($exactClientId)
{
$this->exactClientId = $exactClientId;
}
/**
* #param mixed $exactClientSecret
*/
public function setExactClientSecret($exactClientSecret)
{
$this->exactClientSecret = $exactClientSecret;
}
/**
* #param mixed $authorizationCode
*/
public function setAuthorizationCode($authorizationCode)
{
$this->authorizationCode = $authorizationCode;
}
/**
* #param mixed $accessToken
*/
public function setAccessToken($accessToken)
{
$this->accessToken = $accessToken;
}
/**
* #param mixed $refreshToken
*/
public function setRefreshToken($refreshToken)
{
$this->refreshToken = $refreshToken;
}
/**
*
*/
public function redirectForAuthorization()
{
$authUrl = $this->getAuthUrl();
header('Location: ' . $authUrl);
exit;
}
/**
* #param mixed $redirectUrl
*/
public function setRedirectUrl($redirectUrl)
{
$this->redirectUrl = $redirectUrl;
}
/**
* #return bool
*/
public function needsAuthentication()
{
return empty($this->refreshToken) && empty($this->authorizationCode);
}
/**
* #param Response $response
* #param bool $returnSingleIfPossible
* #return mixed
* #throws ApiException
*/
private function parseResponse(Response $response, $returnSingleIfPossible = true)
{
try {
if ($response->getStatusCode() === 204) {
return [];
}
Psr7\rewind_body($response);
$json = json_decode($response->getBody()->getContents(), true);
if (array_key_exists('d', $json)) {
if (array_key_exists('__next', $json['d'])) {
$this->nextUrl = $json['d']['__next'];
}
else {
$this->nextUrl = null;
}
if (array_key_exists('results', $json['d'])) {
if ($returnSingleIfPossible && count($json['d']['results']) == 1) {
return $json['d']['results'][0];
}
return $json['d']['results'];
}
return $json['d'];
}
return $json;
} catch (\RuntimeException $e) {
throw new ApiException($e->getMessage());
}
}
/**
* #return mixed
*/
private function getCurrentDivisionNumber()
{
if (empty($this->division)) {
$me = new Me($this);
$this->division = $me->find()->CurrentDivision;
}
return $this->division;
}
/**
* #return mixed
*/
public function getRefreshToken()
{
return $this->refreshToken;
}
/**
* #return mixed
*/
public function getAccessToken()
{
return $this->accessToken;
}
private function acquireAccessToken()
{
// If refresh token not yet acquired, do token request
if (empty($this->refreshToken)) {
$body = [
'form_params' => [
'redirect_uri' => $this->redirectUrl,
'grant_type' => 'authorization_code',
'client_id' => $this->exactClientId,
'client_secret' => $this->exactClientSecret,
'code' => $this->authorizationCode
]
];
} else { // else do refresh token request
$body = [
'form_params' => [
'refresh_token' => $this->refreshToken,
'grant_type' => 'refresh_token',
'client_id' => $this->exactClientId,
'client_secret' => $this->exactClientSecret,
]
];
}
$response = $this->client()->post($this->getTokenUrl(), $body);
if ($response->getStatusCode() == 200) {
Psr7\rewind_body($response);
$body = json_decode($response->getBody()->getContents(), true);
if (json_last_error() === JSON_ERROR_NONE) {
$this->accessToken = $body['access_token'];
$this->refreshToken = $body['refresh_token'];
$this->tokenExpires = $this->getDateTimeFromExpires($body['expires_in']);
if (is_callable($this->tokenUpdateCallback)) {
call_user_func($this->tokenUpdateCallback, $this);
}
} else {
throw new ApiException('Could not acquire tokens, json decode failed. Got response: ' . $response->getBody()->getContents());
}
} else {
throw new ApiException('Could not acquire or refresh tokens');
}
}
private function getDateTimeFromExpires($expires)
{
if (!is_numeric($expires)) {
throw new \InvalidArgumentException('Function requires a numeric expires value');
}
return time() + 600;
}
/**
* #return mixed
*/
public function getTokenExpires()
{
return $this->tokenExpires;
}
/**
* #param mixed $tokenExpires
*/
public function setTokenExpires($tokenExpires)
{
$this->tokenExpires = $tokenExpires;
}
private function tokenHasExpired()
{
if (empty($this->tokenExpires)) {
return true;
}
return $this->tokenExpires <= time() + 10;
}
private function formatUrl($endPoint, $includeDivision = true, $formatNextUrl = false)
{
if ($formatNextUrl) {
return $endPoint;
}
if ($includeDivision) {
return implode('/', [
$this->getApiUrl(),
$this->getCurrentDivisionNumber(),
$endPoint
]);
}
return implode('/', [
$this->getApiUrl(),
$endPoint
]);
}
/**
* #return mixed
*/
public function getDivision()
{
return $this->division;
}
/**
* #param mixed $division
*/
public function setDivision($division)
{
$this->division = $division;
}
/**
* #param callable $callback
*/
public function setTokenUpdateCallback($callback) {
$this->tokenUpdateCallback = $callback;
}
/**
* Parse the reponse in the Exception to return the Exact error messages
* #param Exception $e
* #throws ApiException
*/
private function parseExceptionForErrorMessages(Exception $e)
{
if (! $e instanceof BadResponseException) {
throw new ApiException($e->getMessage());
}
$response = $e->getResponse();
Psr7\rewind_body($response);
$responseBody = $response->getBody()->getContents();
$decodedResponseBody = json_decode($responseBody, true);
if (! is_null($decodedResponseBody) && isset($decodedResponseBody['error']['message']['value'])) {
$errorMessage = $decodedResponseBody['error']['message']['value'];
} else {
$errorMessage = $responseBody;
}
throw new ApiException('Error ' . $response->getStatusCode() .': ' . $errorMessage);
}
/**
* #return string
*/
protected function getBaseUrl()
{
return $this->baseUrl;
}
/**
* #return string
*/
private function getApiUrl()
{
return $this->baseUrl . $this->apiUrl;
}
/**
* #return string
*/
private function getTokenUrl()
{
return $this->baseUrl . $this->tokenUrl;
}
/**
* Set base URL for different countries according to
* https://developers.exactonline.com/#Exact%20Online%20sites.html
*
* #param string $baseUrl
*/
public function setBaseUrl($baseUrl)
{
$this->baseUrl = $baseUrl;
}
/**
* #param string $apiUrl
*/
public function setApiUrl($apiUrl)
{
$this->apiUrl = $apiUrl;
}
/**
* #param string $authUrl
*/
public function setAuthUrl($authUrl)
{
$this->authUrl = $authUrl;
}
/**
* #param string $tokenUrl
*/
public function setTokenUrl($tokenUrl)
{
$this->tokenUrl = $tokenUrl;
}
}

The error itself is pretty self-explanatory. You are trying to include a file and it cannot be found with the path you provided.
Try printing what the magic constant __DIR__ contains in order to see the full path you are trying to include.
You can use var_dump(__DIR__);exit; at the start of your script.
As an additional note, you should consider using composer's autoload.

As you mention your trying to load Connection class as below
require __DIR__ . '\vendor\picqer\exactphpclient\src\Picqer\Financials\Exact\Connection.php';
When we using composer, instead of loading individual class files try to use composer auto load, its automatically loads the name spaces of the required class.
If you implement auto load in your code, the code may look like this.
require __DIR__ . '/vendor/autoload.php';
use Picqer\Financials\Exact\Connection;
$connection = new Connection();

Related

How to pass storeUrl to default Magento oauth script?

I'm trying to create my first Magento 2 extension and integration and I've been following the guide in their docs here. All good so far, I've completed the auth handshake, stored all the required keys for api requests and can make requests back to my extension fine.
Looking at the OauthClient.php script provided at the foot of the tutorial, the url is hardcoded like so:
return new Uri('http://magento.host/oauth/token/request'); and the tutorial advises you to "Change the instances of http://magento.host in this example to a valid base URL."
<?php
use OAuth\Common\Consumer\Credentials;
use OAuth\Common\Http\Client\ClientInterface;
use OAuth\Common\Http\Exception\TokenResponseException;
use OAuth\Common\Http\Uri\Uri;
use OAuth\Common\Http\Uri\UriInterface;
use OAuth\Common\Storage\TokenStorageInterface;
use OAuth\OAuth1\Service\AbstractService;
use OAuth\OAuth1\Signature\SignatureInterface;
use OAuth\OAuth1\Token\StdOAuth1Token;
use OAuth\OAuth1\Token\TokenInterface;
class OauthClient extends AbstractService
{
/** #var string|null */
protected $_oauthVerifier = null;
public function __construct(
Credentials $credentials,
ClientInterface $httpClient = null,
TokenStorageInterface $storage = null,
SignatureInterface $signature = null,
UriInterface $baseApiUri = null
) {
if (!isset($httpClient)) {
$httpClient = new \OAuth\Common\Http\Client\StreamClient();
}
if (!isset($storage)) {
$storage = new \OAuth\Common\Storage\Session();
}
if (!isset($signature)) {
$signature = new \OAuth\OAuth1\Signature\Signature($credentials);
}
parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri);
}
/**
* #return UriInterface
*/
public function getRequestTokenEndpoint()
{
return new Uri('http://magento.host/oauth/token/request');
}
/**
* Returns the authorization API endpoint.
*
* #throws \OAuth\Common\Exception\Exception
*/
public function getAuthorizationEndpoint()
{
throw new \OAuth\Common\Exception\Exception(
'Magento REST API is 2-legged. Current operation is not available.'
);
}
/**
* Returns the access token API endpoint.
*
* #return UriInterface
*/
public function getAccessTokenEndpoint()
{
return new Uri('http://magento.host/oauth/token/access');
}
/**
* Parses the access token response and returns a TokenInterface.
*
* #param string $responseBody
* #return TokenInterface
*/
protected function parseAccessTokenResponse($responseBody)
{
return $this->_parseToken($responseBody);
}
/**
* Parses the request token response and returns a TokenInterface.
*
* #param string $responseBody
* #return TokenInterface
* #throws TokenResponseException
*/
protected function parseRequestTokenResponse($responseBody)
{
$data = $this->_parseResponseBody($responseBody);
if (isset($data['oauth_verifier'])) {
$this->_oauthVerifier = $data['oauth_verifier'];
}
return $this->_parseToken($responseBody);
}
/**
* Parse response body and create oAuth token object based on parameters provided.
*
* #param string $responseBody
* #return StdOAuth1Token
* #throws TokenResponseException
*/
protected function _parseToken($responseBody)
{
$data = $this->_parseResponseBody($responseBody);
$token = new StdOAuth1Token();
$token->setRequestToken($data['oauth_token']);
$token->setRequestTokenSecret($data['oauth_token_secret']);
$token->setAccessToken($data['oauth_token']);
$token->setAccessTokenSecret($data['oauth_token_secret']);
$token->setEndOfLife(StdOAuth1Token::EOL_NEVER_EXPIRES);
unset($data['oauth_token'], $data['oauth_token_secret']);
$token->setExtraParams($data);
return $token;
}
/**
* Parse response body and return data in array.
*
* #param string $responseBody
* #return array
* #throws \OAuth\Common\Http\Exception\TokenResponseException
*/
protected function _parseResponseBody($responseBody)
{
if (!is_string($responseBody)) {
throw new TokenResponseException("Response body is expected to be a string.");
}
parse_str($responseBody, $data);
if (null === $data || !is_array($data)) {
throw new TokenResponseException('Unable to parse response.');
} elseif (isset($data['error'])) {
throw new TokenResponseException("Error occurred: '{$data['error']}'");
}
return $data;
}
/**
* #override to fix since parent implementation from lib not sending the oauth_verifier when requesting access token
* Builds the authorization header for an authenticated API request
*
* #param string $method
* #param UriInterface $uri the uri the request is headed
* #param \OAuth\OAuth1\Token\TokenInterface $token
* #param $bodyParams array
* #return string
*/
protected function buildAuthorizationHeaderForAPIRequest(
$method,
UriInterface $uri,
TokenInterface $token,
$bodyParams = null
) {
$this->signature->setTokenSecret($token->getAccessTokenSecret());
$parameters = $this->getBasicAuthorizationHeaderInfo();
if (isset($parameters['oauth_callback'])) {
unset($parameters['oauth_callback']);
}
$parameters = array_merge($parameters, ['oauth_token' => $token->getAccessToken()]);
$parameters = array_merge($parameters, $bodyParams);
$parameters['oauth_signature'] = $this->signature->getSignature($uri, $parameters, $method);
$authorizationHeader = 'OAuth ';
$delimiter = '';
foreach ($parameters as $key => $value) {
$authorizationHeader .= $delimiter . rawurlencode($key) . '="' . rawurlencode($value) . '"';
$delimiter = ', ';
}
return $authorizationHeader;
}
}
My Question is how do I pass the url from the store that the integration has been set up on back as a variable in here?(I have it stored in my db)
Thanks for taking the time to take a look.
For anyone who might come across this in future after getting the saved data from the table in my db, I added the Url into the call to make the new class on the checklogin.php script in the documentation:
$oAuthClient = new OauthClient($credentials,$magentoBaseUrl);
And then in OauthClient.php, I added the url to the construct and updated the getRequestTokenEndpoint method and the getAcessTokenEndpoint:
public function __construct(
Credentials $credentials,
$magentoBaseUrl = null,
ClientInterface $httpClient = null,
TokenStorageInterface $storage = null,
SignatureInterface $signature = null,
UriInterface $baseApiUri = null
) {
if (!isset($httpClient)) {
$httpClient = new \OAuth\Common\Http\Client\CurlClient();
}
if (!isset($storage)) {
$storage = new \OAuth\Common\Storage\Session();
}
if (!isset($signature)) {
$signature = new \OAuth\OAuth1\Signature\Signature($credentials);
}
if (!isset($magentoBaseUrl)) {
die();
}
$this->magentoBaseUrl = $magentoBaseUrl;
parent::__construct($credentials, $httpClient, $storage, $signature, $baseApiUri);
}
...
/**
* #return UriInterface
*/
public function getRequestTokenEndpoint()
{
return new Uri($this->magentoBaseUrl.'/oauth/token/request');
}
...
/**
* Returns the access token API endpoint.
*
* #return UriInterface
*/
public function getAccessTokenEndpoint()
{
return new Uri($this->magentoBaseUrl.'/oauth/token/access');
}

Laravel Guzzle - cURL error 3: (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)

I created a simple wrapper around shopify's REST api (private application using basic auth) like this using Guzzle:
<?php
namespace App\Services;
use stdClass;
use Exception;
use GuzzleHttp\Client as GuzzleClient;
/**
* Class ShopifyService
* #package App\Services
*/
class ShopifyService
{
/**
* #var array $config
*/
private $config = [];
/**
* #var GuzzleClient$guzzleClient
*/
private $guzzleClient;
/**
* ShopifyService constructor.
*/
public function __construct()
{
$this->config = config('shopify');
}
/**
* #return ShopifyService
*/
public function Retail(): ShopifyService
{
return $this->initGuzzleClient(__FUNCTION__);
}
/**
* #return ShopifyService
*/
public function Trade(): ShopifyService
{
return $this->initGuzzleClient(__FUNCTION__);
}
/**
* #param string $uri
* #return stdClass
* #throws \GuzzleHttp\Exception\GuzzleException
* #throws Exception
*/
public function Get(string $uri): stdClass
{
$this->checkIfGuzzleClientInitiated();;
$result = $this->guzzleClient->request('GET', $uri);
return \GuzzleHttp\json_decode($result->getBody());
}
/**
* #throws Exception
*/
private function checkIfGuzzleClientInitiated(): void
{
if (!$this->guzzleClient) {
throw new Exception('Guzzle Client Not Initiated');
}
}
/**
* #param string $storeName
* #return ShopifyService
*/
private function initGuzzleClient(string $storeName): ShopifyService
{
if (!$this->guzzleClient) {
$this->guzzleClient = new GuzzleClient([
'base_url' => $this->config[$storeName]['baseUrl'],
'auth' => [
$this->config[$storeName]['username'],
$this->config[$storeName]['password'],
],
'timeout' => 30,
]);
}
return $this;
}
}
Where the config/shopify.php looks like this:
<?php
use Constants\System;
return [
System::STORE_RETAIL => [
'baseUrl' => env('SHOPIFY_API_RETAIL_BASE_URL'),
'username' => env('SHOPIFY_API_RETAIL_USERNAME'),
'password' => env('SHOPIFY_API_RETAIL_PASSWORD'),
],
System::STORE_TRADE => [
'baseUrl' => env('SHOPIFY_API_TRADE_BASE_URL'),
'username' => env('SHOPIFY_API_TRADE_USERNAME'),
'password' => env('SHOPIFY_API_TRADE_PASSWORD'),
],
];
When I use the service like this:
$retailShopifySerice = app()->make(\App\Services\ShopifyService::class);
dd($retailShopifySerice->Retail()->Get('/products/1234567890.json'));
I get the following error:
GuzzleHttp\Exception\RequestException
cURL error 3: (see https://curl.haxx.se/libcurl/c/libcurl-errors.html)
As you can see, I am making a simple guzzle http client with default option (for base uri + basic auth) and making subsequent GET request.
This should work in theory, but I can't figure out why it's throwing this error?
I've already verified the config is correct (i.e. it has the values I expect) and tried clearing all the laravel cache also.
Any ideas what might be wrong here?
I could not get the base_url option to work with Guzzle\Client for some reason, so I solved it in a different way:
<?php
namespace App\Services;
use Exception;
use App\DTOs\ShopifyResult;
use GuzzleHttp\Client as GuzzleClient;
use GuzzleHttp\Exception\GuzzleException;
/**
* Class ShopifyService
* #package App\Services
*/
class ShopifyService
{
const REQUEST_TYPE_GET = 'GET';
const REQUEST_TYPE_POST = 'POST';
const REQUEST_TIMEOUT = 30;
/**
* #var array $shopifyConfig
*/
private $shopifyConfig = [];
/**
* ShopifyService constructor.
*/
public function __construct()
{
$this->shopifyConfig = config('shopify');
}
/**
* #param string $storeName
* #param string $requestUri
* #return ShopifyResult
* #throws GuzzleException
*/
public function Get(string $storeName, string $requestUri): ShopifyResult
{
return $this->guzzleRequest(
self::REQUEST_TYPE_GET,
$storeName,
$requestUri
);
}
/**
* #param string $storeName
* #param string $requestUri
* #param array $requestPayload
* #return ShopifyResult
* #throws GuzzleException
*/
public function Post(string $storeName, string $requestUri, array $requestPayload = []): ShopifyResult
{
return $this->guzzleRequest(
self::REQUEST_TYPE_POST,
$storeName,
$requestUri,
$requestPayload
);
}
/**
* #param string $requestType
* #param string $storeName
* #param $requestUri
* #param array $requestPayload
* #return ShopifyResult
* #throws GuzzleException
* #throws Exception
*/
private function guzzleRequest(string $requestType, string $storeName, $requestUri, array $requestPayload = []): ShopifyResult
{
$this->validateShopifyConfig($storeName);
$guzzleClient = new GuzzleClient();
$requestOptions = [
'auth' => [
$this->shopifyConfig[$storeName]['username'],
$this->shopifyConfig[$storeName]['password']
],
'timeout' => self::REQUEST_TIMEOUT,
];
if (count($requestPayload)) {
$requestOptions['json'] = $requestPayload;
}
$response = $guzzleClient->request(
$requestType,
$this->shopifyConfig[$storeName]['baseUrl'] . $requestUri,
$requestOptions
);
list ($usedApiCall, $totalApiCallAllowed) = explode(
'/',
$response->getHeader('X-Shopify-Shop-Api-Call-Limit')[0]
);
$shopifyResult = new ShopifyResult(
$response->getStatusCode(),
$response->getReasonPhrase(),
((int) $totalApiCallAllowed - (int) $usedApiCall),
\GuzzleHttp\json_decode($response->getBody()->getContents())
);
$guzzleClient = null;
unset($guzzleClient);
return $shopifyResult;
}
/**
* #param string $storeName
* #throws Exception
*/
private function validateShopifyConfig(string $storeName): void
{
if (!array_key_exists($storeName, $this->shopifyConfig)) {
throw new Exception("Invalid shopify store {$storeName}");
}
foreach (['baseUrl', 'username', 'password'] as $configFieldName) {
if (!array_key_exists($configFieldName, $this->shopifyConfig[$storeName])) {
throw new Exception("Shopify config missing {$configFieldName} for store {$storeName}");
}
}
}
}

Task runs on my local machine but not production Laravel Lumen

I am having an issue with my production env. On my local machine when I run the command I built:
php artisan updateusers:badcustomernumbers
everything runs as expected, no jobs fail.
When I deployed and tried to run this same task I get:
Symfony\Component\Debug\Exception\FatalThrowableError: Call to undefined method App\Services\MiddlewareApi::get_lowest_active_customer_number_by_email() in .../app/Jobs/UpdateBadCustomerNumbersJob.php:48
Here is UpdateBadCustomerNumbersJob.php:
<?php
namespace App\Jobs;
use App\AppUser;
use Illuminate\Support\Facades\Log;
use App\Subscription;
use Illuminate\Bus\Queueable;
use Illuminate\Queue\SerializesModels;
use Illuminate\Queue\InteractsWithQueue;
use Illuminate\Contracts\Queue\ShouldQueue;
use Mockery\Exception;
use App\Http\Controllers\UpdateUserController;
use App\Services\MiddlewareApi;
class UpdateBadCustomerNumbersJob extends Job
{
/**
* App users to update customer number for
* #var AppUser
*/
protected $appUsers;
/**
* The number of times the job may be attempted.
*
* #var int
*/
public $tries = 2;
/**
* UpdateBadCustomerNumbersJob constructor.
* #param $appUsers
*/
public function __construct($appUsers)
{
$this->appUsers = $appUsers;
}
/**
* #param UpdateUserController $updateUserController
*/
public function handle(UpdateUserController $updateUserController)
{
$middlewareApi = new MiddlewareApi();
foreach ($this->appUsers as $user) {
$userCustomerNumber = $middlewareApi->get_lowest_active_customer_number_by_email($user->email);
if(!is_null($userCustomerNumber) AND $userCustomerNumber !== false AND !empty($userCustomerNumber->customerNumber)) {
$updateUserController->updateAggregateCustomerNumber($user, $userCustomerNumber, true);
$updateUserController->updateAppDatasCustomerNumber($user, $userCustomerNumber, true);
$updateUserController->updateSubscriptionsCustomerNumber($user, $userCustomerNumber, true);
$updateUserController->updateAppUserCustomerNumber($user, $userCustomerNumber, true);
} else {
//if there is no customer number available just delete this user because they must not have any active subscriptions any longer
$updateUserController->deleteAggregateData($user);
$updateUserController->deleteAppDatas($user);
$updateUserController->deleteSubscriptions($user);
$updateUserController->deleteAppUser($user);
}
}
}
}
and here is MiddlewareAPI.php:
<?php
namespace App\Services;
use Illuminate\Support\Facades\Log;
use Mockery\Exception;
use GuzzleHttp\Client;
class MiddlewareApi
{
/**
* #var $middlewareToken
*/
private $middlewareToken;
/**
* #var $middlewareUrl
*/
private $middlewareUrl;
public function __construct()
{
$this->setMiddlewareToken(env('MIDDLEWARE_TOKEN'));
$this->setMiddlewareUrl(env('MIDDLEWARE_BASE_URL'));
}
/**
* Sets the Middleware API Token
* #param $token
*/
public function setMiddlewareToken( $token )
{
$this->middlewareToken = $token;
}
/**
* Gets the Middleware API Token
* #return mixed
*/
public function getMiddlewareToken()
{
return $this->middlewareToken;
}
/**
* Sets the Middleware base url
* #param $url
*/
public function setMiddlewareUrl( $url )
{
$this->middlewareUrl = $url;
}
/**
* Gets the Middleware base url
* #return mixed
*/
public function getMiddlewareUrl()
{
return $this->middlewareUrl;
}
/**
* Retrieves the Active subscriptions of a customer
* based on customer number
* #param $customerNumber
* #return bool|mixed
*/
public function get_customer_subscriptions_by_customer_number( $customerNumber )
{
$url = $this->getMiddlewareUrl() . 'sub/active/customernumber/' . $customerNumber;
$header = ['Token' => $this->getMiddlewareToken()];
$errorText = 'Error in get_customer_subscriptions_by_customer_number: ';
return $this->_get($url,$header,$errorText);
}
/**
* Retrieves the Active subscriptions and Products of a customer
* #param $customerNumber
* #return bool|mixed
*/
public function get_customer_subscriptions_and_products_by_customer_number( $customerNumber )
{
$url = $this->getMiddlewareUrl() . 'data/customernumber/' . $customerNumber;
$header = ['Token' => $this->getMiddlewareToken()];
$errorText = 'Error in get_customer_subscriptions_by_customer_number: ';
return $this->_get($url,$header,$errorText);
}
/**
* Retrieve the lowest active customer number by email address
* #param $email
* #return bool|mixed
*/
public function get_lowest_active_customer_number_by_email( $email )
{
$url = $this->getMiddlewareUrl() . 'customer/findlowestactivecustomernumber/emailaddress/' . $email;
$header = ['Token' => $this->getMiddlewareToken()];
$errorText = 'Error in get_lowest_active_customer_number_by_email: ';
return $this->_get($url, $header, $errorText);
}
/**
* Get method to make all get calls from middleware
* #param $endpoint
* #param $headers
* #param $errorText
* #return bool|mixed
*/
public function _get($endpoint, $headers, $errorText)
{
$client = new Client();
try {
$response = $client->request('GET', $endpoint,
['headers' => $headers]
);
$responseData = json_decode($response->getBody()->getContents());
return $responseData;
} catch (Exception $e) {
Log::error($errorText. $e);
return false;
}
}
/**
* Returns data with status code in json format
* #param $statusCode
* #param $data
* #return \Illuminate\Http\JsonResponse
*/
public function apiReturnResponseInJson( $statusCode, $data )
{
$content = ['status' => $statusCode, 'data' => $data];
return response()->json($content, $statusCode);
}
}
I tried running composer update and php artisan cache:clear but I am still getting the same error. I even ssh'd in and get_lowest_active_customer_number_by_email method is present in MiddlewareApi.php.
Any ideas what the problem may be?

Catchable fatal error: Object of class Instamojo could not be converted to string

I just working on some project which have use instamojo for payment. I have two file one is the instamojo.php file another file is call.php file when i call instamojo constructor into call.php then i getting error code.
*<?php
class Instamojo {
const version = '1.1';
protected $curl;
protected $endpoint = 'https://www.instamojo.com/api/1.1/';
protected $api_key = null;
protected $auth_token = null;
/**
* #param string $api_key
* #param string $auth_token is available on the d
* #param string $endpoint can be set if you are working on an alternative server.
* #return array AuthToken object.
*/
function __construct($api_key, $auth_token=null, $endpoint=null)
{
$this->api_key = (string) $api_key;
$this->auth_token = (string) $auth_token;
if(!is_null($endpoint)){
$this->endpoint = (string) $endpoint;
}
}
public function __destruct()
{
if(!is_null($this->curl)) {
curl_close($this->curl);
}
}
/**
* #return array headers with Authentication tokens added
*/
private function build_curl_headers()
{
$headers = array("X-Api-key: $this->api_key");
if($this->auth_token) {
$headers[] = "X-Auth-Token: $this->auth_token";
}
return $headers;
}
/**
* #param string $path
* #return string adds the path to endpoint with.
*/
private function build_api_call_url($path)
{
if (strpos($path, '/?') === false and strpos($path, '?') === false) {
return $this->endpoint . $path . '/';
}
return $this->endpoint . $path;
}
/**
* #param string $method ('GET', 'POST', 'DELETE', 'PATCH')
* #param string $path whichever API path you want to target.
* #param array $data contains the POST data to be sent to the API.
* #return array decoded json returned by API.
*/
private function api_call($method, $path, array $data=null)
{
$path = (string) $path;
$method = (string) $method;
$data = (array) $data;
$headers = $this->build_curl_headers();
$request_url = $this-> build_api_call_url($path);
$options = array();
$options[CURLOPT_HTTPHEADER] = $headers;
$options[CURLOPT_RETURNTRANSFER] = true;
if($method == 'POST') {
$options[CURLOPT_POST] = 1;
$options[CURLOPT_POSTFIELDS] = http_build_query($data);
} else if($method == 'DELETE') {
$options[CURLOPT_CUSTOMREQUEST] = 'DELETE';
} else if($method == 'PATCH') {
$options[CURLOPT_POST] = 1;
$options[CURLOPT_POSTFIELDS] = http_build_query($data);
$options[CURLOPT_CUSTOMREQUEST] = 'PATCH';
} else if ($method == 'GET' or $method == 'HEAD') {
if (!empty($data)) {
/* Update URL to container Query String of Paramaters */
$request_url .= '?' . http_build_query($data);
}
}
// $options[CURLOPT_VERBOSE] = true;
$options[CURLOPT_URL] = $request_url;
$options[CURLOPT_SSL_VERIFYPEER] = true;
$options[CURLOPT_CAINFO] = dirname(__FILE__) . DIRECTORY_SEPARATOR . 'cacert.pem';
$this->curl = curl_init();
$setopt = curl_setopt_array($this->curl, $options);
$response = curl_exec($this->curl);
$headers = curl_getinfo($this->curl);
$error_number = curl_errno($this->curl);
$error_message = curl_error($this->curl);
$response_obj = json_decode($response, true);
if($error_number != 0){
if($error_number == 60){
throw new \Exception("Something went wrong. cURL raised an error with number: $error_number and message: $error_message. " .
"Please check http://stackoverflow.com/a/21114601/846892 for a fix." . PHP_EOL);
}
else{
throw new \Exception("Something went wrong. cURL raised an error with number: $error_number and message: $error_message." . PHP_EOL);
}
}
if($response_obj['success'] == false) {
$message = json_encode($response_obj['message']);
throw new \Exception($message . PHP_EOL);
}
return $response_obj;
}
/**
* #return string URL to upload file or cover image asynchronously
*/
public function getUploadUrl()
{
$result = $this->api_call('GET', 'links/get_file_upload_url', array());
return $result['upload_url'];
}
/**
* #param string $file_path
* #return string JSON returned when the file upload is complete.
*/
public function uploadFile($file_path)
{
$upload_url = $this->getUploadUrl();
$file_path = realpath($file_path);
$file_name = basename($file_path);
$ch = curl_init();
$data = array('fileUpload' => $this->getCurlValue($file_path, $file_name));
curl_setopt($ch, CURLOPT_URL, $upload_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
return curl_exec($ch);
}
public function getCurlValue($file_path, $file_name, $content_type='')
{
// http://stackoverflow.com/a/21048702/846892
// PHP 5.5 introduced a CurlFile object that deprecates the old #filename syntax
// See: https://wiki.php.net/rfc/curl-file-upload
if (function_exists('curl_file_create')) {
return curl_file_create($file_path, $content_type, $file_name);
}
// Use the old style if using an older version of PHP
$value = "#{$file_path};filename=$file_name";
if ($content_type) {
$value .= ';type=' . $content_type;
}
return $value;
}
/**
* Uploads any file or cover image mentioned in $link and
* updates it with the json required by the API.
* #param array $link
* #return array $link updated with uploaded file information if applicable.
*/
public function uploadMagic(array $link)
{
if(!empty($link['file_upload'])) {
$file_upload_json = $this->uploadFile($link['file_upload']);
$link['file_upload_json'] = $file_upload_json;
unset($link['file_upload']);
}
if(!empty($link['cover_image'])) {
$cover_image_json = $this->uploadFile($link['cover_image']);
$link['cover_image_json'] = $cover_image_json;
unset($link['cover_image']);
}
return $link;
}
/**
* Authenticate using username and password of a user.
* Automatically updates the auth_token value.
* #param array $args contains username=>USERNAME and password=PASSWORD
* #return array AuthToken object.
*/
public function auth(array $args)
{
$response = $this->api_call('POST', 'auth', $args);
$this->auth_token = $response['auth_token']['auth_token'];
return $this->auth_token;
}
/**
* #return array list of Link objects.
*/
public function linksList()
{
$response = $this->api_call('GET', 'links', array());
return $response['links'];
}
/**
* #return array single Link object.
*/
public function linkDetail($slug)
{
$response = $this->api_call('GET', 'links/' . $slug, array());
return $response['link'];
}
/**
* #return array single Link object.
*/
public function linkCreate(array $link)
{
if(empty($link['currency'])){
$link['currency'] = 'INR';
}
$link = $this->uploadMagic($link);
$response = $this->api_call('POST', 'links', $link);
return $response['link'];
}
/**
* #return array single Link object.
*/
public function linkEdit($slug, array $link)
{
$link = $this->uploadMagic($link);
$response = $this->api_call('PATCH', 'links/' . $slug, $link);
return $response['link'];
}
/**
* #return array single Link object.
*/
public function linkDelete($slug)
{
$response = $this->api_call('DELETE', 'links/' . $slug, array());
return $response;
}
/**
* #return array list of Payment objects.
*/
public function paymentsList($limit = null, $page = null)
{
$params = array();
if (!is_null($limit)) {
$params['limit'] = $limit;
}
if (!is_null($page)) {
$params['page'] = $page;
}
$response = $this->api_call('GET', 'payments', $params);
return $response['payments'];
}
/**
* #param string payment_id as provided by paymentsList() or Instamojo's webhook or redirect functions.
* #return array single Payment object.
*/
public function paymentDetail($payment_id)
{
$response = $this->api_call('GET', 'payments/' . $payment_id, array());
return $response['payment'];
}
///// Request a Payment /////
/**
* #param array single PaymentRequest object.
* #return array single PaymentRequest object.
*/
public function paymentRequestCreate(array $payment_request)
{
$response = $this->api_call('POST', 'payment-requests', $payment_request);
return $response['payment_request'];
}
/**
* #param string id as provided by paymentRequestCreate, paymentRequestsList, webhook or redirect.
* #return array single PaymentRequest object.
*/
public function paymentRequestStatus($id)
{
$response = $this->api_call('GET', 'payment-requests/' . $id, array());
return $response['payment_request'];
}
/**
* #param string id as provided by paymentRequestCreate, paymentRequestsList, webhook or redirect.
* #param string payment_id as received with the redirection URL or webhook.
* #return array single PaymentRequest object.
*/
public function paymentRequestPaymentStatus($id, $payment_id)
{
$response = $this->api_call('GET', 'payment-requests/' . $id . '/' . $payment_id, array());
return $response['payment_request'];
}
/**
* #param array datetime_limits containing datetime data with keys 'max_created_at', 'min_created_at',
* 'min_modified_at' and 'max_modified_at' in ISO 8601 format(optional).
* #return array containing list of PaymentRequest objects.
* For more information on the allowed date formats check the
* docs: https://www.instamojo.com/developers/request-a-payment-api/#toc-filtering-payment-requests
*/
public function paymentRequestsList($datetime_limits=null)
{
$endpoint = 'payment-requests';
if(!empty($datetime_limits)){
$query_string = http_build_query($datetime_limits);
if(!empty($query_string)){
$endpoint .= '/?' . $query_string;
}
}
$response = $this->api_call('GET', $endpoint, array());
return $response['payment_requests'];
}
///// Refunds /////
/**
* #param array single Refund object.
* #return array single Refund object.
*/
public function refundCreate(array $refund)
{
$response = $this->api_call('POST', 'refunds', $refund);
return $response['refund'];
}
/**
* #param string id as provided by refundCreate or refundsList.
* #return array single Refund object.
*/
public function refundDetail($id)
{
$response = $this->api_call('GET', 'refunds/' . $id, array());
return $response['refund'];
}
/**
* #return array containing list of Refund objects.
*/
public function refundsList()
{
$response = $this->api_call('GET', 'refunds', array());
return $response['refunds'];
}
}
?>*
And this instamojo.php call.php
<?php
require_once('Instamojo.php');
function get_value()
{
$apii = new Instamojo("ba93dee8f492c9e6e98284decce6c5b4","838c8bc1cbd71c30e5c98bebb9e99968");
echo $apii;
/*try {
$response = $apii->paymentRequestCreate(array(
"purpose" => "FIFA 16",
"amount" => "3499",
"send_email" => true,
"email" => "foo#example.com",
"redirect_url" => "http://www.example.com/handle_redirect.php"
));
print_r($response);
}
catch (Exception $e) {
print('Error: ' . $e->getMessage());
}-->*/
}
if(function_exists($_GET['f'])) {
$_GET['f']();
}
?>
But when i call to call.php into browser i am getting some error
Catchable fatal error: Object of class Instamojo could not be converted to string
Unless you implement a _toString() method, you can't echo and object. You can use var_dump() or print_r() to inspect its properties.

403 Forbidden Error : JSON-RPC PHP

I tried to implement json-rpc server on local for some test.
But when I send some request, it returns the "Forbidden Error".
I made a clone from git (https://github.com/fguillot/JsonRPC), but for now I wanted to make sure something could be returned. So I used command line, instead of running program named Client.php.
example.php
<?php
require 'Server.php';
use JsonRPC\Server;
$server = new Server;
$server->register('addition', function ($a, $b) {
return $a + $b;
});
$server->register('random', function ($start, $end) {
return mt_rand($start, $end);
});
echo $server->execute();
?>
Server.php
<?php
namespace JsonRPC;
use Closure;
use BadFunctionCallException;
use Exception;
use InvalidArgumentException;
use LogicException;
use ReflectionFunction;
use ReflectionMethod;
class InvalidJsonRpcFormat extends Exception {};
class InvalidJsonFormat extends Exception {};
/**
* JsonRPC server class
*
* #package JsonRPC
* #author Frederic Guillot
* #license Unlicense http://unlicense.org/
*/
class Server
{
/**
* Data received from the client
*
* #access private
* #var string
*/
private $payload;
/**
* List of procedures
*
* #static
* #access private
* #var array
*/
private $callbacks = array();
/**
* List of classes
*
* #static
* #access private
* #var array
*/
private $classes = array();
/**
* Constructor
*
* #access public
* #param string $payload Client data
* #param array $callbacks Callbacks
* #param array $classes Classes
*/
public function __construct($payload = '', array $callbacks = array(), array $classes = array())
{
$this->payload = $payload;
$this->callbacks = $callbacks;
$this->classes = $classes;
}
/**
* IP based client restrictions
*
* Return an HTTP error 403 if the client is not allowed
*
* #access public
* #param array $hosts List of hosts
*/
public function allowHosts(array $hosts) {
if (! in_array($_SERVER['REMOTE_ADDR'], $hosts)) {
header('Content-Type: application/json');
header('HTTP/1.0 403 Forbidden');
echo '{"error": "Access Forbidden"}';
exit;
}
}
/**
* HTTP Basic authentication
*
* Return an HTTP error 401 if the client is not allowed
*
* #access public
* #param array $users Map of username/password
*/
public function authentication(array $users)
{
if (! isset($_SERVER['PHP_AUTH_USER']) ||
! isset($users[$_SERVER['PHP_AUTH_USER']]) ||
$users[$_SERVER['PHP_AUTH_USER']] !== $_SERVER['PHP_AUTH_PW']) {
header('WWW-Authenticate: Basic realm="JsonRPC"');
header('Content-Type: application/json');
header('HTTP/1.0 401 Unauthorized');
echo '{"error": "Authentication failed"}';
exit;
}
}
/**
* Register a new procedure
*
* #access public
* #param string $procedure Procedure name
* #param closure $callback Callback
*/
public function register($name, Closure $callback)
{
$this->callbacks[$name] = $callback;
}
/**
* Bind a procedure to a class
*
* #access public
* #param string $procedure Procedure name
* #param mixed $class Class name or instance
* #param string $method Procedure name
*/
public function bind($procedure, $class, $method)
{
$this->classes[$procedure] = array($class, $method);
}
/**
* Return the response to the client
*
* #access public
* #param array $data Data to send to the client
* #param array $payload Incoming data
* #return string
*/
public function getResponse(array $data, array $payload = array())
{
if (! array_key_exists('id', $payload)) {
return '';
}
$response = array(
'jsonrpc' => '2.0',
'id' => $payload['id']
);
$response = array_merge($response, $data);
#header('Content-Type: application/json');
return json_encode($response);
}
/**
* Parse the payload and test if the parsed JSON is ok
*
* #access public
*/
public function checkJsonFormat()
{
if (empty($this->payload)) {
$this->payload = file_get_contents('php://input');
}
if (is_string($this->payload)) {
$this->payload = json_decode($this->payload, true);
}
if (! is_array($this->payload)) {
throw new InvalidJsonFormat('Malformed payload');
}
}
/**
* Test if all required JSON-RPC parameters are here
*
* #access public
*/
public function checkRpcFormat()
{
if (! isset($this->payload['jsonrpc']) ||
! isset($this->payload['method']) ||
! is_string($this->payload['method']) ||
$this->payload['jsonrpc'] !== '2.0' ||
(isset($this->payload['params']) && ! is_array($this->payload['params']))) {
throw new InvalidJsonRpcFormat('Invalid JSON RPC payload');
}
}
/**
* Return true if we have a batch request
*
* #access public
* #return boolean
*/
private function isBatchRequest()
{
return array_keys($this->payload) === range(0, count($this->payload) - 1);
}
/**
* Handle batch request
*
* #access private
* #return string
*/
private function handleBatchRequest()
{
$responses = array();
foreach ($this->payload as $payload) {
if (! is_array($payload)) {
$responses[] = $this->getResponse(array(
'error' => array(
'code' => -32600,
'message' => 'Invalid Request'
)),
array('id' => null)
);
}
else {
$server = new Server($payload, $this->callbacks, $this->classes);
$response = $server->execute();
if ($response) {
$responses[] = $response;
}
}
}
return empty($responses) ? '' : '['.implode(',', $responses).']';
}
/**
* Parse incoming requests
*
* #access public
* #return string
*/
public function execute()
{
try {
$this->checkJsonFormat();
if ($this->isBatchRequest()){
return $this->handleBatchRequest();
}
$this->checkRpcFormat();
$result = $this->executeProcedure(
$this->payload['method'],
empty($this->payload['params']) ? array() : $this->payload['params']
);
return $this->getResponse(array('result' => $result), $this->payload);
}
catch (InvalidJsonFormat $e) {
return $this->getResponse(array(
'error' => array(
'code' => -32700,
'message' => 'Parse error'
)),
array('id' => null)
);
}
catch (InvalidJsonRpcFormat $e) {
return $this->getResponse(array(
'error' => array(
'code' => -32600,
'message' => 'Invalid Request'
)),
array('id' => null)
);
}
catch (BadFunctionCallException $e) {
return $this->getResponse(array(
'error' => array(
'code' => -32601,
'message' => 'Method not found'
)),
$this->payload
);
}
catch (InvalidArgumentException $e) {
return $this->getResponse(array(
'error' => array(
'code' => -32602,
'message' => 'Invalid params'
)),
$this->payload
);
}
}
/**
* Execute the procedure
*
* #access public
* #param string $procedure Procedure name
* #param array $params Procedure params
* #return mixed
*/
public function executeProcedure($procedure, array $params = array())
{
if (isset($this->callbacks[$procedure])) {
return $this->executeCallback($this->callbacks[$procedure], $params);
}
else if (isset($this->classes[$procedure])) {
return $this->executeMethod($this->classes[$procedure][0], $this->classes[$procedure][1], $params);
}
throw new BadFunctionCallException('Unable to find the procedure');
}
/**
* Execute a callback
*
* #access public
* #param Closure $callback Callback
* #param array $params Procedure params
* #return mixed
*/
public function executeCallback(Closure $callback, $params)
{
$reflection = new ReflectionFunction($callback);
$arguments = $this->getArguments(
$params,
$reflection->getParameters(),
$reflection->getNumberOfRequiredParameters(),
$reflection->getNumberOfParameters()
);
return $reflection->invokeArgs($arguments);
}
/**
* Execute a method
*
* #access public
* #param mixed $class Class name or instance
* #param string $method Method name
* #param array $params Procedure params
* #return mixed
*/
public function executeMethod($class, $method, $params)
{
$reflection = new ReflectionMethod($class, $method);
$arguments = $this->getArguments(
$params,
$reflection->getParameters(),
$reflection->getNumberOfRequiredParameters(),
$reflection->getNumberOfParameters()
);
return $reflection->invokeArgs(
is_string($class) ? new $class : $class,
$arguments
);
}
/**
* Get procedure arguments
*
* #access public
* #param array $request_params Incoming arguments
* #param array $method_params Procedure arguments
* #param integer $nb_required_params Number of required parameters
* #param integer $nb_max_params Maximum number of parameters
* #return array
*/
public function getArguments(array $request_params, array $method_params, $nb_required_params, $nb_max_params)
{
$nb_params = count($request_params);
if ($nb_params < $nb_required_params) {
throw new InvalidArgumentException('Wrong number of arguments');
}
if ($nb_params > $nb_max_params) {
throw new InvalidArgumentException('Too many arguments');
}
if ($this->isPositionalArguments($request_params, $method_params)) {
return $request_params;
}
return $this->getNamedArguments($request_params, $method_params);
}
/**
* Return true if we have positional parametes
*
* #access public
* #param array $request_params Incoming arguments
* #param array $method_params Procedure arguments
* #return bool
*/
public function isPositionalArguments(array $request_params, array $method_params)
{
return array_keys($request_params) === range(0, count($request_params) - 1);
}
/**
* Get named arguments
*
* #access public
* #param array $request_params Incoming arguments
* #param array $method_params Procedure arguments
* #return array
*/
public function getNamedArguments(array $request_params, array $method_params)
{
$params = array();
foreach ($method_params as $p) {
$name = $p->getName();
if (isset($request_params[$name])) {
$params[$name] = $request_params[$name];
}
else if ($p->isDefaultValueAvailable()) {
$params[$name] = $p->getDefaultValue();
}
else {
throw new InvalidArgumentException('Missing argument: '.$name);
}
}
return $params;
}
}
Commmand Line (I use macOS)
curl --data-binary '{"jsonrpc": "2.0","id":1, "method":"addition","params":[100,200] }' -H 'content-type: text/plain;' http://127.0.0.1/jsonrpcphp3/example.php
Return Value
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>403 Forbidden</title>
</head><body>
<h1>Forbidden</h1>
<p>You don't have permission to access /jsonrpcphp3/example.php
on this server.</p>
</body></html>

Categories