guzzle: TooManyRedirectsException after downgrading - php

The code worked correctly on version 7+, however, when the version is downgraded to 6, the function falls with an error.
Code:
<?
define(ZIP_TO_LOCATION_APP, "https://tools.usps.com/tools/app/ziplookup/cityByZip");
function get_location_from_zip($zip_code) {
$client = new GuzzleHttp\Client();
$response = $client->request("POST", ZIP_TO_LOCATION_APP, [
'form_params' => [
'zip' => $zip_code
]
]);
if ($response->getStatusCode() == 200) {
$contents = $response->getBody()->getContents();
$contents = json_decode($contents, true);
$contents["error"] = false;
return $contents;
} else {
return array(
"error" => true
);
}
}
Output:
Fatal error: Uncaught GuzzleHttp\Exception\TooManyRedirectsException: Will not follow more than 5 redirects in C:\OpenServer\domains\job-board.loc\api\classes\composer\vendor\guzzlehttp\guzzle\src\RedirectMiddleware.php:159 Stack trace: #0 C:\OpenServer\domains\job-board.loc\api\classes\composer\vendor\guzzlehttp\guzzle\src\RedirectMiddleware.php(94): GuzzleHttp\RedirectMiddleware->guardMax(Object(GuzzleHttp\Psr7\Request), Array) #1 C:\OpenServer\domains\job-board.loc\api\classes\composer\vendor\guzzlehttp\guzzle\src\RedirectMiddleware.php(72): GuzzleHttp\RedirectMiddleware->checkRedirect(Object(GuzzleHttp\Psr7\Request), Array, Object(GuzzleHttp\Psr7\Response)) #2 C:\OpenServer\domains\job-board.loc\api\classes\composer\vendor\guzzlehttp\promises\src\FulfilledPromise.php(41): GuzzleHttp\RedirectMiddleware->GuzzleHttp\{closure}(Object(GuzzleHttp\Psr7\Response)) #3 C:\OpenServer\domains\job-board.loc\api\classes\composer\vendor\guzzlehttp\promises\src\TaskQueue.php(48): GuzzleHttp\Promise\FulfilledPromise::GuzzleHttp\Promis in C:\OpenServer\domains\job-board.loc\api\classes\composer\vendor\guzzlehttp\guzzle\src\RedirectMiddleware.php on line 159
I tried playing around with the allow_redirects option, this can hide the exception, but it still doesn't return a response.

Related

How to use editMessageCaption correctly in php Telegram Bot?

I want to edit caption of photo, but Im getting error Bad Request: message to edit not found
Code :
<?php
require_once 'Telegram.php';
$telegram = new Telegram('bot:TOken');
$result = $telegram->getData();
$text = $result['message'] ['text'];
$chat_id = $result['message'] ['chat']['id'];
$messageID = $result['message']['message_id'];
$content = array('chat_id' => $chat_id, 'message_id' => $messageID, 'caption' => "wadawd");
// $content = array('chat_id' => $chat_id, 'text' => $messageID);
$telegram->editMessageCaption($content);
Error Log :
============[Date]============
[ 2022-02-28 12:36:58 UTC ]
==========[Response]==========
ok: False
error_code: 400
description: Bad Request: message to edit not found
=========[Sent Data]==========
[ref]
ref.update_id= 3618619
ref.message.message_id= 42
ref.message.from.id= 52868936
ref.message.from.is_bot= false
ref.message.from.first_name= Ramana
ref.message.from.last_name= Owner
ref.message.from.language_code= en
ref.message.chat.id= 52868936
ref.message.chat.first_name= Ramana
ref.message.chat.last_name= Owner
ref.message.chat.type= private
ref.message.date= 1646051816
ref.message.text= esfsef
[ref]
ref.message_id=
ref.caption= wadawd
============[Trace]===========
#0 /home/onbvbrh08q4z/public_html/captionbot/Telegram.php(3228): TelegramErrorLogger::log()
#1 /home/onbvbrh08q4z/public_html/captionbot/Telegram.php(111): Telegram->sendAPIRequest()
#2 /home/onbvbrh08q4z/public_html/captionbot/Telegram.php(1633): Telegram->endpoint()
#3 /home/onbvbrh08q4z/public_html/captionbot/test.php(15): Telegram->editMessageCaption()
#4 {main}
I'm using this github repo https://github.com/Eleirbag89/TelegramBotPHP
Bots (using api.telegram.org) cannot edit messages of posts made before the bot was added to the channel.
Hence, Telegram Bot Api shows you the error "message to edit not found"

Uncaught exception 'PDOException' with message 'SQLSTATE[22007] on MS Server PHP

Hi im getting the following error, when making a post request i am using a MS Server, MSSQL database and php for a Oauth2 Solution.
Fatal error: Uncaught exception 'PDOException' with message 'SQLSTATE[22007]: [Microsoft][ODBC Driver 11 for SQL Server][SQL Server]The conversion of a nvarchar data type to a datetime data type resulted in an out-of-range value.' in C:\xampp\htdocs\api\OAuth2\Storage\Pdo.php:156 Stack trace: #0 C:\xampp\htdocs\api\OAuth2\Storage\Pdo.php(156): PDOStatement->execute(Array) #1 C:\xampp\htdocs\api\OAuth2\ResponseType\AccessToken.php(84): OAuth2\Storage\Pdo->setAccessToken('02742b6cd16424e...', 'testclient', NULL, 1465910857, NULL) #2 C:\xampp\htdocs\api\OAuth2\GrantType\ClientCredentials.php(58): OAuth2\ResponseType\AccessToken->createAccessToken('testclient', NULL, NULL, false) #3 C:\xampp\htdocs\api\OAuth2\Controller\TokenController.php(205): OAuth2\GrantType\ClientCredentials->createAccessToken(Object(OAuth2\ResponseType\AccessToken), 'testclient', NULL, NULL) #4 C:\xampp\htdocs\api\OAuth2\Controller\TokenController.php(49): OAuth2\Controller\TokenController->grantAccessToken(Object(OAuth2\Request), Object(OAuth2\Response in C:\xampp\htdocs\api\OAuth2\Storage\Pdo.php on line 156
After doing some research i understand the 22007 is related to a date problem, i have changed the formatting of the date.
Here is the code block from the Pdo.php the server is complaining about
public function setAccessToken($access_token, $client_id, $user_id, $expires, $scope = null)
{
//convert expires to datestring
//$expires = date('Y-m-d H:i:s', $expires);
$expires = date("Ymd H:i:s", $expires);
//echo $expires . "-------------------";
// if it exists, update it.
if ($this->getAccessToken($access_token)) {
$stmt = $this->db->prepare(sprintf('UPDATE %s SET client_id=:client_id, expires=:expires, user_id=:user_id, scope=:scope where access_token=:access_token', $this->config['access_token_table']));
} else {
$stmt = $this->db->prepare(sprintf('INSERT INTO %s (access_token, client_id, expires, user_id, scope) VALUES (:access_token, :client_id, :expires, :user_id, :scope)', $this->config['access_token_table']));
}
return $stmt->execute(compact('access_token', 'client_id', 'user_id', 'expires', 'scope'));
}
The strange thing is in the terminal and postman when i run a curl post, i get the correct response when i run the request on token.php.
There is a problem with the php_curl.dll on our server which has meant i have to use file_get_contents post request to get the data.
public function getAccess() {
$postdata = http_build_query ( array (
'client_id' => 'testclient',
'client_secret' => 'testpass',
'grant_type' => 'client_credentials'
)
);
$opts = array (
'http' => array (
'method' => 'POST',
'header' => 'Content-type: application/x-www-form-urlencoded',
'content' => $postdata
)
);
$context = stream_context_create ( $opts );
$result = file_get_contents ( 'http://IPADDRESS/api/token.php', false, $context );
// var_dump($result);
echo $result;
return $result;
}
Im guessing the problem is related to using file_get_contents, as the access token is created from terminal and postman.
Any suggestions would be gratefully appreciated.
Thank you.

How to swap SOAP calls to cURL, to work within allow_url_fopen limitation?

I've recently had a problem where the SOAP calls to the ID3Global/address service suddenly stopped working(they previously worked fine). I believe it has something to do with the hosting provider turning off allow_url_fopen on our server which now means the service doesn't work.
I've been told I'll need to switch to using cURL to grab the files (WSDL) as file_get_contents requires 'allow_url_fopen' to be set in the php.ini file for this to work. However I don't seem to be using file_get_contents in my file to get the WSDL file.
How can I to switch to using cURL?
Here's my PHP file making the SOAP address call:
<?php
ini_set("soap.wsdl_cache_enabled", "0");
$username = 'xxxxxxx#xxxxxxxx.com';
$password = 'xxxxxxx';
$profile_id = 'xxxxxx-xxxx-xxxx-xxxx-xxxxxxxx';
// Live WSDL
$wsdl = 'https://id3global.com/ID3gWS/ID3global.svc?wsdl';
$postcode = $_POST['ZipPostcode'];
/**
* Method to arrange the address into a sane
* order for displaying back to the user
*
* #param $item
* #param $key
* #internal param $address
*/
function sortAddress(&$item, $key)
{
// Convert the object to an array
$address = (array) $item;
// Reorder the address lines
$addressLines = array(
'Company' => $address['Company'],
'Building' => $address['Building'],
'SubBuilding' => $address['SubBuilding'],
'Premise' => $address['Premise'],
'SubStreet' => $address['SubStreet'],
'Street' => $address['Street'],
'City' => $address['City'],
'StateDistrict' => $address['StateDistrict'],
'ZipPostcode' => $address['ZipPostcode'],
'Country' => $address['Country'],
);
// Remove blank address lines
// $item = array_filter($addressLines);
$item = $addressLines;
}
class clsWSSEAuth {
private $Username;
private $Password;
function __construct($username, $password) {
$this->Username=$username;
$this->Password=$password;
}
}
class clsWSSEToken {
private $UsernameToken;
function __construct ($UsernameToken){
$this->UsernameToken = $UsernameToken;
}
}
$strWSSENS = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd";
//Auth
$objSoapVarUser = new SoapVar($username, XSD_STRING, NULL, $strWSSENS, NULL, $strWSSENS);
$objSoapVarPass = new SoapVar($password, XSD_STRING, NULL, $strWSSENS, NULL, $strWSSENS);
$objWSSEAuth = new clsWSSEAuth($objSoapVarUser, $objSoapVarPass);
//Token
$objSoapVarWSSEToken = new SoapVar($objWSSEAuth, SOAP_ENC_OBJECT, NULL, $strWSSENS, 'UsernameToken', $strWSSENS);
$objWSSEToken = new clsWSSEToken($objSoapVarWSSEToken);
//Header
$objSoapVarWSSEAuth = new SoapVar($objWSSEToken, SOAP_ENC_OBJECT, NULL, $strWSSENS, 'UsernameToken', $strWSSENS);
$objSoapVarHeaderVal = new SoapVar($objSoapVarWSSEAuth, SOAP_ENC_OBJECT, NULL, $strWSSENS, 'Security', $strWSSENS);
$objSoapVarWSSEHeader = new SoapHeader($strWSSENS, 'Security', $objSoapVarHeaderVal, true);
//Client
$client = new SoapClient($wsdl, array(
'soap_version' => SOAP_1_1,
'trace' => 1,
'exception' => true,
));
$client->__setSoapHeaders($objSoapVarWSSEHeader);
$results = $client->AddressLookup(array(
'InputData' => array('ZipPostcode' => strtoupper($postcode)),
));
$addresses = $results->AddressLookupResult->GlobalAddress;
array_walk($addresses, 'sortAddress');
//var_dump($addresses);
echo json_encode( $addresses );
This is triggered using AJAX and here's the JavaScript/jQuery file:
jQuery(document).ready(function($) {
var addresses = [];
$("body").on('click', '.find-address', function(e){
e.preventDefault();
url = '/wp-content/themes/Cornhill/gbgroup-address-lookup_2.php';
postode_id = $(this).data('postcode');
address_id = $(this).data('address');
postcode = $('#'+postode_id).val();
console.log('Stage 1');
if (postcode != '')
{
var addressList = $('#'+address_id);
addressList.find('option').remove();
opt = $('<option>').html('Loading...');
opt.val('');
addressList.append(opt);
console.log('stage 2');
$.ajax({
url: url,
dataType: 'json',
type: 'post',
data: {
'ZipPostcode': postcode
},
success: function(response){
addressList.find('option').remove();
addresses[address_id] = response;
opt = $('<option>').html('Please select');
opt.val('');
addressList.append(opt);
for(x=0; x<addresses[address_id].length; x++){
addressArray = new Array();
addressArray.push(addresses[address_id][x].Building);
addressArray.push(addresses[address_id][x].Street);
addressArray.push(addresses[address_id][x].City);
addressArray.push(addresses[address_id][x].ZipPostcode);
addressString = addressArray.join(', ');
opt = $('<option>').attr('value', x);
opt.html(addressString);
addressList.append(opt);
}
}
});
}
else
{
return;
}
});
$("body").on('change', '.select-address', function(){
address_id = $(this).attr('id');
street_id = $(this).data('street');
town_id = $(this).data('town');
postcode_id = $(this).data('postcode');
value = $(this).val();
if(value != ''){
address = addresses[address_id][value];
if (address.Building != '')
{
$('#'+street_id).val(address.Building+' '+address.Street);
}
else
{
$('#'+street_id).val(address.Street);
}
$('#'+town_id).val(address.City);
$('#'+postcode_id).val(address.ZipPostcode);
}
});
});
I've previously tried switching using the following code to grab the WSDL file but am not really sure what else I'm supposed to do with it:
$ch = curl_init('https://id3global.com/ID3gWS/ID3global.svc?wsdl');
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
$resultSuper = curl_exec($ch);
The parameter allow_url_fopen has no effect on the way that SOAP works. You can easily test this with the following script:
<?php
echo "allow_url_fopen status is: " . ini_get('allow_url_fopen') . "\n";
$wsdl = 'https://id3global.com/ID3gWS/ID3global.svc?wsdl';
file_get_contents($wsdl);
$client = new SoapClient($wsdl, array(
'soap_version' => SOAP_1_1,
'trace' => 1,
'cache_wsdl' => WSDL_CACHE_NONE, // this is important for the purpose of the test
'exception' => true,
));
print_r($client);
?>
When allow_url_fopen is enabled, you will see the following output:
allow_url_fopen status is: 1 SoapClient Object ( [trace] => 1 [_soap_version] => 1 [sdl] => Resource id #11 )
When allow_url_fopen is disabled, you will see the following output:
allow_url_fopen status is: 0
Warning: file_get_contents(): https:// wrapper is disabled in the server configuration by allow_url_fopen=0 in /var/www/test.php on line 9
Warning: file_get_contents(https://id3global.com/ID3gWS/ID3global.svc?wsdl): failed to open stream: no suitable wrapper could be found in /var/www/test.php on line 9
SoapClient Object ( [trace] => 1 [_soap_version] => 1 [sdl] => Resource id #10 )
Notice that no SOAP error is reported.
The reason for this behaviour is the following code in file ext/soap/php_xml.c in PHP's source:
old_allow_url_fopen = PG(allow_url_fopen);
PG(allow_url_fopen) = 1;
ctxt = xmlCreateFileParserCtxt(filename);
PG(allow_url_fopen) = old_allow_url_fopen;
So, allow_url_fopen is enabled for the WSDL download. If you comment the lines as follows:
/* old_allow_url_fopen = PG(allow_url_fopen);
PG(allow_url_fopen) = 1; */
ctxt = xmlCreateFileParserCtxt(filename);
/* PG(allow_url_fopen) = old_allow_url_fopen; */
And compile PHP with the changed source, you will see the following results:
Enabled allow_url_fopen:
allow_url_fopen status is: 1 SoapClient Object ( [trace] => 1 [_soap_version] => 1 [sdl] => Resource id #11 )
Disabled allow_url_fopen:
allow_url_fopen status is: 0
Warning: file_get_contents(): https:// wrapper is disabled in the server configuration by allow_url_fopen=0 in /var/www/test.php on line 9
Warning: file_get_contents(https://id3global.com/ID3gWS/ID3global.svc?wsdl): failed to open stream: no suitable wrapper could be found in /var/www/test.php on line 9
Fatal error: Uncaught SoapFault exception: [WSDL] SOAP-ERROR: Parsing WSDL: Couldn't load from 'https://id3global.com/ID3gWS/ID3global.svc?wsdl' : failed to load external entity "https://id3global.com/ID3gWS/ID3global.svc?wsdl" in /var/www/test.php:16 Stack trace: #0 /var/www/test.php(16): SoapClient->SoapClient('https://id3glob...', Array) #1 {main} thrown in /var/www/test.php on line 16
You can see that this time we have fatal SOAP error and that the WSDL cannot be loaded. I observed this behaviour with PHP 5.4.40 and PHP 5.6.8.

Context.io PHP API Giving Error

I have run into a problem with the Context.io API. I keep getting the following error message:
Warning: Invalid argument supplied for foreach() in /usr/share/nginx/html/custom-assets/includes/ContextIO/demo.php on line 11
Here is my php code:
// Require the Context.io PHP Library
require('class.contextio.php');
// See https://console.context.io/#settings to get your consumer key and consumer secret.
$contextIO = new ContextIO('consumer key','consumer secret');
$accountId = 'xxxxxxxxxx'; // Account ID of email account
$args = array('folder' => 'Inbox', 'include_flags' => 1, 'include_thread_size' => 1, 'include_body' => 1, 'limit' => 50);
echo "Getting last 50 messages...<br><br>";
$r = $contextIO->listMessages($accountId, $args);
if ($r !== false) {
foreach ($r->getData() as $message) {
echo "Subject: ".$message['subject']."<br>";
}
} else {
var_dump($r);
}
I have no clue why this is not working. Anybody have any clue why?
All of the functions in the ContextIO library return a ContextIOResponse object, or false if the API returns an http error code. If you add a check for if($r !== false) before you call getData() it should catch any errors.

SoapClient connection to SoapServer

I need to connect to a SOAP Server from php, I read a lot of documentation, examples and tutorials, but I still cannot make authentication to my server. I have done the work below:
$agencyNumber = 7818619810;
$fullTransmission = false;
//$context = array('header' => 'Content-type: application/soap+xml; charset=utf-8');
$params = array( 'agencyNumber' => 7818619810, 'fullTransmission' => 0/*,$context*/);
$client = new SoapClient("http://link/to/server?wsdl");
$test = $client->__getFunctions();
var_dump($test );// returns the functions my supplier provides, as well __getTypes() gives a bunch of variable arrays ect..
$response = $client->__soapCall('GetTransmissionTicket',array($params) );//line 16 which is mentioned on error print
var_dump($response);
Even though I set $context, when I try to run, I get the error below:
Fatal error: Uncaught SoapFault exception: [HTTP] Cannot process the
message because the content type 'text/xml; charset=utf-8' was not the
expected type 'application/soap+xml; charset=utf-8'. in
C:\xampp\htdocs\xml\inc\connection_test.php:16 Stack trace: #0
[internal function]: SoapClient->__doRequest('http://interfac...', '..//my-provider...', 1, 0) #1
C:..path..test.php(16): SoapClient->__soapCall('GetTransmission...',
Array) #2 {main} thrown in C:..path..test.php on line 16
The remote method I'm trying to call is called GetTransmissionTicket which takes two parameters, (int)agencyNumber and fullTransmission(bool)..
I want to emphasize that there are a lot of threads on this topic, some of which are really close to my question(1, 2, 3 and so on ..), but I really couldn't solve the problem. Please give a hand..
Kind Regards..
Try $params = array( 'agencyNumber' => 7818619810, 'fullTransmission' => false);
instead of $params = array( 'agencyNumber' => 7818619810, 'fullTransmission' => 0);
OR
Use $client = new SoapClient("http://link/to/server?wsdl", array('soap_version' => SOAP_1_1));
because
application/soap+xml is the content-type passed when using SOAP 1.2, text/xml is used with SOAP 1.1,
Reference : how to change content-type of request?
A simple example with soap and php can be
$url="your WSDL url";
$method = "Method you are calling";
$error=0;
$client = new SoapClient($url);
try
{
$info = $client->__call($method, array($param));
}
catch (SoapFault $fault)
{
$error = 1;
errorReport($fault->faultcode,$fault->faultstring);
die;
/*echo '<script type="text/javascript">alert("Sorry,App Returne the following ERROR:'.$fault->faultcode."-".$fault->faultstring.' We will now take you back to our homepage."); window.location = "'.$_SERVER['PHP_SELF'].'";</script> '; */
}
if($error==1)
{
$xml=$fault->faultstring;
}else{
$xml = $info;
}
return $xml;
Try implementing it and let me know. if it works for you.
Shouldn't the last line be var_dump($response); instead of var_dump($client);
Anyways, you can also try using this to get the result :
$response = $client->GetTransmissionTicket(array($params) );
var_dump($response);
I resolved this problem by switching from SOAP 1.2 to SOAP 1.1:
$this->client = new SoapClient(
$url,
array(
"trace" => TRUE,
"exception" => 0,
"soap_version" => SOAP_1_1,
"cache_wsdl" => WSDL_CACHE_MEMORY,
"local_cert" => 'mycert.pem',
)
);
I will answer my own question so that it helps someone one day. I used nusoap and changed the encoding to utf-8. The code snippet is below:
require_once "nusoap.php";
$client = new nusoap_client("http://interface.--Serivce-Supplier-Link/Service.svc?wsdl", "wsdl");
$client->soap_defencoding = 'UTF-8';
$result = $client->call("GetTransmissionTicket", array( 'agencyNumber' => 13155, 'fullTransmission' => false));
var_dump($result);
Kind Regards
may be little late but could help others. so here it goes:
$params is already an array so you don't have to use array($params) in
$response = $client->__soapCall('GetTransmissionTicket',array($params) );
instead use simple $params while calling.check it like this
$response = $client->GetTransmissionTicket($params);
also use $client->__getTypes(); to verify params to be passed.
use catch to good effect to trace faultstringand faultactor.
at the end if still not getting solution check it with soapUI(a software).

Categories