Error on trying to connect to SOAP service - php

I'm trying to consume the "search" function of the Brazilian CADSUS service, but I get the following error:
"Forced circuit exception";
Right below, I have the following code, which uses Laravel 5.6 and PHP 7.1
Route::get('/ws/teste', function () {
try {
$opts = array(
'http' => array(
'user_agent' => 'PHPSoapClient'
)
);
$context = stream_context_create($opts);
$wsdlUrl = 'https://servicoshm.saude.gov.br/cadsus/CadsusService/v5r0?wsdl';
$soapClientOptions = array(
'trace' => 1,
'stream_context' => $context,
'cache_wsdl' => WSDL_CACHE_NONE,
'Username' => '*****',
'Password' => '*****'
);
$client = new SoapClient($wsdlUrl, $soapClientOptions);
$parameters = array(
'CNESUsuario' => array(
'CNES' => '6963447',
'Usuario' => 'LEONARDO',
'Senha' => ''
),
'FiltroPesquisa' => array(
'nomeCompleto' => 'SERGIO ARAUJO CORREIA LIMA',
'tipoPesquisa' => 'IDENTICA'
),
'higienizar' => 0
);
$result = $client->pesquisar($parameters);
print_r($result);
}
catch(\Exception $e) {
echo $e->getMessage();
} });
I would appreciate any help. Thanks in advance

From SOAP response:
[cvc-minLength-valid: Value '' with length = '0' is not facet-valid with
respect to minLength '1' for type '#AnonType_SenhaCNESUsuarioType'.,
cvc-type.3.1.3: The value '' of element 'ns1:Senha' is not valid
So, Senha can't be empty string.

Related

PHP/Laravel looks like we got no XML document when making soapcall

I am trying to do a soap call and I keep getting the following error:
looks like we got no XML document
EDIT error message
here's an example that works fine in my SOAP UI
Here's my array that I send to my soapCall:
$params = [
'id' => '0000002721',
'options' => [
'returnAttachments' => 'false',
'returnPictures' => 'false',
'returnContract' => 'false'
]
];
Here is the code how I make the soap call
try {
$options = array(
'ssl' => array(
'verify_peer' => false,
'verify_peer_name' => false,
'allow_self_signed' => true
)
);
$context = stream_context_create($options);
$soapClient = new SoapClient(__DIR__ . '/Soap.wsdl', [
'stream_context' => $context,
'login' => 'login',
'password' => 'password',
'trace' => 1,
'exceptions' => true,
]);
$soapClient->__setLocation('url');
$this->soapClient = $soapClient;
} catch (\SoapFault $e) {
var_dump($e); exit;
}
try {
$result = $this->soapClient->__soapCall('getMaintenanceObject', $params);
} catch (\SoapFault $e) {
var_dump($e); exit;
}
SoapClient can be not very expressive when it comes to displaying the errors, add this:
var_dump($this->soapClient->__getLastRequestHeaders());
var_dump($this->soapClient->__getLastResponseHeaders());

How Do I Prevent Duplicates When Adding Leads to SuiteCRM?

The developer guide for SuiteCRM is kind of incomplete (at least here in Q4 2017) compared to the old SugarCRM one that it was based on before the software fork. So, by downloading the WordPress Plugin for SugarCRM, I was able to figure out the REST API and JSON for adding a sales lead into SuiteCRM with the following code.
Now how do I prevent duplicates by home phone, mobile phone, or email address?
<?php
error_reporting(E_ALL);
ini_set('display_errors','On');
header('Content-Type: text/plain');
CRM::loginCRM('admin','xxxxPASSWORDxxxxxx');
$aResult = CRM::addLead(array(
'name' => 'John Doe',
'description' => 'sample description',
'salutation' => 'Mr.',
'first_name' => 'John',
'last_name' => 'Doe',
'do_not_call' => 'No',
'phone_home' => '202-111-2222',
'phone_mobile' => '202-111-2222',
'email1' => 'test#example.com',
'primary_address_street' => '123 Main Street',
'primary_address_street2' => '',
'primary_address_street3' => '',
'primary_address_city' => 'New York',
'primary_address_state' => 'NY'
));
print_r($aResult);
CRM::logoutCRM();
die('OK');
/////////////////////////
class CRM {
private static $SessionID = '';
private static $URL = 'https://mycrmserver-example.com/service/v4_1/rest.php';
private static $User = '';
private static $Shadow = '';
public static function sendJSON($a) {
$s = file_get_contents(
self::$URL,
false,
stream_context_create(
array(
'http' => array (
'method' => 'POST',
'header' => 'Content-Type: application/x-www-form-urlencoded',
'content' => http_build_query($a)
)
)
)
);
$a2 = json_decode($s);
return $a2;
}
public static function loginCRM($sUser,$sPass) {
$sShadow = md5($sPass);
self::$User = $sUser;
self::$Shadow = $sShadow;
$asLogin = array (
'method' => 'login',
'input_type' => 'JSON',
'response_type' => 'JSON',
'rest_data' => json_encode(array(
'user_auth' => array(
'user_name' => $sUser,
'password' => $sShadow,
'version' => 1
),
'application_name' => 'RestTest',
'name_value_list' => array()
))
);
$a = self::sendJSON($asLogin);
self::$SessionID = $a->id;
}
public static function logoutCRM() {
$asLogin = array (
'method' => 'logout',
'input_type' => 'JSON',
'response_type' => 'JSON',
'rest_data' => json_encode(array(
'user_auth' => array(
'user_name' => self::$User,
'password' => self::$Shadow,
'version' => 1
),
'application_name' => 'RestTest',
'name_value_list' => array()
))
);
self::sendJSON($asLogin);
}
public static function addLead($a) {
$asNameValueList = array();
foreach($a as $sKey => $sVal) {
$asNameValueList[] = array('name'=>$sKey,'value'=>$sVal);
}
$asAddEntry = array (
'method' => 'set_entry',
'input_type' => 'JSON',
'response_type' => 'JSON',
'rest_data' => json_encode(array(
'session' => self::$SessionID,
'module_name' => 'Leads',
'name_value_list' => $asNameValueList
))
);
$a = self::sendJSON($asAddEntry);
return $a;
}
} // end CRM
Add these functions into your CRM class and check them before adding a lead. I had a little help from this answer that incidentally gave me some insights. Also, I recommend you do things to tighten down your security such as add an .htaccess or NGINX rule that only allows certain IP addresses or require certain headers to reach anything in your /service folder, and /service/* subfolders either over HTTP or HTTPS.
public static function leadExistsByPhone($sHomePhone,$sMobilePhone) {
$sHomePhone = (empty($sHomePhone)) ? 'xxxxxinvalid' : $sHomePhone;
$sMobilePhone = (empty($sMobilePhone)) ? 'xxxxxinvalid' : $sMobilePhone;
$asCheck = array (
'method' => 'get_entry_list',
'input_type' => 'JSON',
'response_type' => 'JSON',
'rest_data' => json_encode(array(
'session' => self::$SessionID,
'module_name' => 'Leads',
'query' => "
leads.phone_home = '$sHomePhone'
OR leads.phone_mobile = '$sMobilePhone'
",
'order_by' => 'leads.date_entered DESC',
'offset' => '0',
'select_fields' => array(),
'link_name_to_fields_array' => array(),
'max_results' => 999999,
'deleted' => false
))
);
$a = self::sendJSON($asCheck);
$nCount = # $a->result_count;
$nCount = intval($nCount);
return ($nCount > 0);
}
public static function leadExistsByEmail($sEmail) {
if (!filter_var($sEmail, FILTER_VALIDATE_EMAIL)) {
die('DENIED: invalid email address format');
}
$asCheck = array (
'method' => 'get_entry_list',
'input_type' => 'JSON',
'response_type' => 'JSON',
'rest_data' => json_encode(array(
'session' => self::$SessionID,
'module_name' => 'Leads',
'query' => "
leads.id IN
(
SELECT email_addr_bean_rel.bean_id
FROM email_addr_bean_rel
JOIN email_addresses
ON email_addr_bean_rel.email_address_id = email_addresses.id
WHERE
email_addresses.email_address = '$sEmail'
)
",
'order_by' => 'leads.date_entered DESC',
'offset' => '0',
'select_fields' => array(),
'link_name_to_fields_array' => array(),
'max_results' => 999999,
'deleted' => false
))
);
$a = self::sendJSON($asCheck);
$nCount = # $a->result_count;
$nCount = intval($nCount);
return ($nCount > 0);
}

PHP SOAP call content type

I'm attempting to connect with a WS via Soap and struggling with a content type error when I call the method: content type 'text/xml; charset=utf-8' was not the expected type 'application/soap+xml; charset=utf-8'
Below is my code, reducing number of params and hiding url, user and password.
The error happens when I call the ClientRegist() function. I'm convinced I have to pass $params in a different way, but can't find an example anywhere.
$url = 'http://---';
$ctx_opts = array(
'http' => array(
'header' => 'Content-Type: application/soap+xml'
),
'username' => '---',
'password' => '---',
'trace' => true,
'exceptions' => true
);
$ctx = stream_context_create($ctx_opts);
$client = new SoapClient($url, array('stream_context' => $ctx));
$params = array(
'Cardnumber' => $number,
'Name' => $name
);
try {
$client = new SoapClient($url, array('trace' => $trace, 'exceptions' => $exceptions));
$response = $client->ClientRegist($params);
}
catch (Exception $e) {
echo "Error!<br>";
echo $e -> getMessage ().'<br>';
echo 'Last response: '. $client->__getLastResponse();
}
var_dump($response);
Try SOAP version 1.2. Its default Content-Type is application/soap+xml
<?php
// ...
$client = new SoapClient(
$url,
array(
'soap_version' => SOAP_1_2, // !!!!!!!
'stream_context' => $ctx
)
);

SSL error in CURL call to Twitter API

Below is some code of my controller (dont worry, de keys are fake). Im using the ZendService\Twitter\Twitter module. Almost everything is working only the last error is a bit strange and i can not figure it out:
Unable to enable crypto on TCP connection api.twitter.com: make sure the "sslcafile" or "sslcapath" option are properly set for the environment.
As you can see i the code below of my controller, you can see that both the Verify of Peer and Host are set to false. The adapter is already set to Curl instead of HTTP.
<?php
namespace Twitter\Controller;
use QDCore\Controller\AbstractController;
use Zend\Mvc\MvcEvent;
use Zend\View\Model\JsonModel;
use ZendService\Twitter\Twitter;
class GetController extends AbstractController
{
protected $instance;
public function onDispatch(MvcEvent $e)
{
$config = array(
'access_token' => array(
'token' => '1024003resagsDQGyVC5YZ23423PpBNOwefS',
'secret' => 'oES8Jergewagewahsh2hTqrYGDJo',
),
'oauth_options' => array(
'consumerKey' => 'QY360Nersehr234gg4aV2pw',
'consumerSecret' => 'eEfgdagewa0Hkt4z6nCqHPY1M4wwuubY',
),
'username' => 'myusername',
'http_client_options' => array(
'adapter' => 'Zend\Http\Client\Adapter\Curl',
'curloptions' => array(
CURLOPT_SSL_VERIFYHOST => false,
CURLOPT_SSL_VERIFYPEER => false,
),
),
);
$this->instance = new Twitter($config);
return parent::onDispatch($e);
}
public function indexAction()
{
$result = new JsonModel(array('message' => 'No valid function call made'));
return $result;
}
public function usertimelineAction()
{
$options = array(
'user_id' => 'myaccountname',
'count' => 30,
);
$twitter = new Twitter($options);
$response = $twitter->statuses->userTimeline();
var_dump($response);
die;
return new JsonModel($response);
}
}
Hope that someone has an idea on how to fix it. My main domain is not running on SSL and is not going to be.
Thanks
NEVER set verify host or peer verification to false, unless you know what you are doing!
You have to point curl to your certification bundle. For Linux (Debian based systems) that is etc/ssl/certs. You could set that as "sslcapath" variable:
'http_client_options' => array(
'adapter' => 'Zend\Http\Client\Adapter\Curl',
'curloptions' => array(
'sslcapath' => '/etc/ssl/certs',
),
),
Because the path varies between systems, it's good to have it as an option set in your config/autoload/global.php file which users could change with a local.php configuration. In your config:
'http_client' => array(
'options' => array(
'sslcapath' => '/etc/ssl/certs',
),
),
Then your code becomes:
public function onDispatch(MvcEvent $e)
{
$app = $e->getApplication();
$sm = $app->getServiceManager();
$cnf = $sm->get('Config');
$config = array(
'access_token' => array(
'token' => '1024003resagsDQGyVC5YZ23423PpBNOwefS',
'secret' => 'oES8Jergewagewahsh2hTqrYGDJo',
),
'oauth_options' => array(
'consumerKey' => 'QY360Nersehr234gg4aV2pw',
'consumerSecret' => 'eEfgdagewa0Hkt4z6nCqHPY1M4wwuubY',
),
'username' => 'myusername',
'http_client_options' => array(
'adapter' => 'Zend\Http\Client\Adapter\Curl',
'curloptions' => $cnf['http_client']['options'],
),
);
$this->instance = new Twitter($config);
return parent::onDispatch($e);
}
I had the same exact problem and found this on Google. I understood I should either disable CURLOPT_SSL_VERIFYHOST and CURLOPT_SSL_VERIFYPEER or specify the correct path to the local certificates, but didn't know how to do that.
This answer has helped me a lot:
$config = array(
'callbackUrl' => 'http://example.com/callback.php',
'siteUrl' => 'http://twitter.com/oauth',
'consumerKey' => 'myConsumerKey',
'consumerSecret' => 'myConsumerSecret'
);
$consumer = new ZendOAuth\Consumer($config);
// this is the key:
$adapter = new \Zend\Http\Client\Adapter\Curl();
$adapter = $adapter->setCurlOption(CURLOPT_SSL_VERIFYHOST, false);
$adapter = $adapter->setCurlOption(CURLOPT_SSL_VERIFYPEER, false);
$httpClient = $consumer->getHttpClient();
$httpClient->setAdapter($adapter);
// now finally fetch a request token
$token = $consumer->getRequestToken();

PHP GetResponse API and CF7 connection

Im trying to take data from Contact Form 7 WordPress plugin and pass it with json to GetResponse API
I have a php file that pull the data and send it, and its looks like this
I'm getting the CF7 email of confirmation but im not getting GetResponse Email confirmation for newsletter, i don't understand why, i tried to do some debugging and there was no errors
add_action('wpcf7_before_send_mail', 'mytheme_save_to_getresponse', 10, 1);
function mytheme_save_to_getresponse($form)
{
include 'ChromePhp.php';
require_once 'jsonRPCClient.php';
$api_key = 'some_api_key';
$api_url = 'http://api2.getresponse.com';
$client = new jsonRPCClient($api_url);
$result = NULL;
try {
$result = $client->get_campaigns(
$api_key,
array (
# find by name literally
'name' => array ( 'EQUALS' => 'testcase_001' )
)
);
}
catch (Exception $e) {
# check for communication and response errors
# implement handling if needed
die($e->getMessage());
}
$campaigns = array_keys($result);
$CAMPAIGN_ID = array_pop($campaigns);
$subscriberName = $_POST['name'];
$subscriberEmail = $_POST['email'];
$subscriberPhone = $_POST['c_phone'];
$subscriberCellphone = $_POST['c_cellphone'];
$subscriberArea = $_POST['c_area'];
$subscriberInsuranceType = $_POST['c_type'];
$subscriberCarType = $_POST['c_cartype'];
$subscriberManifacture = $_POST['c_manifacture'];
$subscriberManifacturemodel = $_POST['c_manifacturemodel'];
$subscriberManifactureYear = $_POST['c_manifactureyear'];
$subscriberDriverAge = $_POST['c_driversage'];
$subscriberPrevent = $_POST['c_prevent'];
$subscriberClaim = $_POST['c_claim'];
try {
$result = $client->add_contact(
$api_key,
array (
'campaign' => $CAMPAIGN_ID,
'name' => $subscriberName,
'email' => $subscriberEmail,
'cycle_day' => '0',
'customs' => array(
array(
'name' => 'home_phone',
'content' => $subscriberPhone
),
array(
'name' => 'cell_phone',
'content' => $subscriberCellphone
),
array(
'name' => 'living_area',
'content' => $subscriberArea
),
array(
'name' => 'drivers_age',
'content' => $subscriberDriverAge
),
array(
'name' => 'insurance_type',
'content' => $subscriberInsuranceType
),
array(
'name' => 'car_type',
'content' => $subscriberCarType
),
array(
'name' => 'manifacture_type',
'content' => $subscriberManifacture
),
array(
'name' => 'manifacture_model',
'content' => $subscriberManifacturemodel
),
array(
'name' => 'manifacture_year',
'content' => $subscriberManifactureYear
),
array(
'name' => 'license_loss',
'content' => $subscriberPrevent
),
array(
'name' => 'claims_number',
'content' => $subscriberClaim
)
)
)
);
}
catch (Exception $e) {
# check for communication and response errors
# implement handling if needed
die($e->getMessage());
}
}
Thanks in advance
everything was OK with this code, i GetResponse don't send confirmation requests more than once on the same email..

Categories