Im trying to do some mobile detection and this module is giving me problems.
$config = array('storage' => array('adapter' => 'Zend_Http_UserAgent_Storage_Session'));
try
{
//$bootstrap = $this->getInvokeArg('bootstrap');
//$userAgent = $bootstrap->getResource('useragent');
//Bootstrap::pr($userAgent);
//echo $userAgent->getUserAgent();
$ua = new Zend_Http_UserAgent($config);
Bootstrap::pr($ua);
Bootstrap::pr($ua->getDevice());
}catch(Exception $e)
{
Bootstrap::pr($e);
}
This is within the index action of my index controller.
Bootstrap::pr is basically a print_r wrapped with <pre>'s
when i open the page, the print_r for $ua works, but then it just dies and the page is blank. Can anyone help me out here?
Zend_Http_UserAgent depends on WURFL library, you have to configure it as described in the manual.
Check out WURFL - it may be just what you are looking for.
Related
I'm trying to create a rental module for my work's website. When I use the same parameters in SmartBear's SOAP UI, it works. So, I'm assuming that it's something to do with my code, but I cannot find the error.
<?php //Submit Reservation
require("connect.php");
$sessionId = $_SESSION['sessionId'];
$moveInDate = date("yy-m-d", strtotime($_POST['moveIn']));
$billDate = date("d", strtotime($_POST['moveIn']));
$rentalOptions = array(
"customer.company" =>$company,
"account.startDate"=> $moveInDate,
"contact.firstName"=>$_POST['fname'],
"contact.lastName"=>$_POST['lname'],
"contact.companyName"=>$_POST['companyName'],
"contact.street1"=>$_POST['street'],
"contact.street2"=>"",
"contact.city"=>$_POST['city'],
"contact.state"=>$_POST['state'],
"contact.zip"=>$_POST['zip'],
"contact.country"=>"US",
"phone.1" => $_POST['mobile'],
"contact.email"=>$_POST['email'],
"account.currency"=>"1",
"account.billDay"=> $billDate,
"user.paymentMethod"=>"1",
"user.draftDay"=>"",
"unit.id"=>$_POST['unit-name'],
"postAccount"=>"Y",
"promotionId"=>$_POST['promo'],
"insuranceId"=>$_POST['insurance']
);
var_dump($rentalOptions);
echo "<br/>". $sessionId ."<br/>Return";
$client = new SoapClient("https://api.doorswap.com/service/system.wsdl");
// Make API Call
$dsReceiver = "customer";
$dsAction = "saveNewCustomer";
$result = $client->makeReceiverCall($sessionId, $dsReceiver, $dsAction, $rentalOptions);
//if($result["success"] == "true") {
//}
?>
The var_dump() and print_r() displays correct variables from the previous form. In fact, ALL variables are correctly output. I just do not understand WHY it isn't working. It's not giving me an error, it's just not POSTING.
FYI: I have tried using javascript SOAP and I run into similar issues. The code is right, the variables are correct, but the addition to the system is not going through.
I'm open to trying anything.
Initialization of the SoapClient class
First of all inialize your soap client the right way. The soap client class takes several options to debug your application. In the following example a soap client is initalized with some options, that will make your life more easy when testing.
try {
$client = new SoapClient('https://api.doorswap.com/service/system.wsdl', [
'exceptions' => true,
'trace' => true,
]);
} catch (SoapFault $fault) {
var_dump($fault->getMessage());
if ($client instanceof SoapClient) {
var_dump(
$client->__getLastRequest(),
$client->__getLastResponse()
);
}
}
As you can see the soap client class is initialized with different option parameters. The exception option is set to true so that the soap client class throws exceptions, when an error occurs. That 's why the code is wrapped in a try and catch block. The trace option allows us to see, what the last request and response looks like. If the soap client was initialized you can use the build in methods __getLastRequest() and __getLastResponse() to see what the sent and received xml looks like. Keep in mind, that these can be empty if the xml wasn 't compiled by the client.
The makeReceiverCall method was a "name"/"value" system. So the above array of $rentalOptions SHOULD have been done as such. This is currently working, and has been flawless in execution.
$rentalOptions = array(
array("name"=> "customer.company","value"=> $company),
array("name"=> "account.startDate", "value"=> $moveInDate),
...
);
This was the error that I had run into and finally figured out. Thank you to all those who tried to help.
I can't seem to get tracking options created, the Category itself is creating fine.
However firstly - I should point out I believe there is a bug in the Xero-API for PHP, when debugging adding an option according to the documentation here the PUT should be
https://api.xero.com/api.xro/2.0/TrackingCategories/{TrackingCategoryID}/Options
However in the php lib it is
https://api.xero.com/api.xro/2.0/TrackingCategories/{TrackingCategoryID}/TrackingOptions
Even when that is resolved, I get no error however not tracking Option is created, any ideas?
$options = ['US', 'UK'];
$title = 'Region';
$trackingCategory = null;
if(!$trackingCategory) {
$trackingCategory = new \XeroPHP\Models\Accounting\TrackingCategory($xero);
$trackingCategory->setName($title);
$trackingCategory->save();
}
try {
foreach($options as $option) {
$to = new \XeroPHP\Models\Accounting\TrackingCategory\TrackingOption($xero);
$to->setName($option);
$trackingCategory->setOption($option);
$trackingCategory->save();
}
} catch(\Exception $e) {
$this->logger()->info($e->getTraceAsString());
$this->logger()->info("TRACKING: ". $e->getMessage());
return false;
}
So this would appear it is a bug as reported here
The source has not been fixed, however the above link resolves the problem for anyone else searching.
Changing TrackingOptions to Options in XeroPHP worked soughta... but I was still getting a different error. Ended up creating the Option manually
Note: $this->_xero_oauth_object is my \XeroPHP\Application\PublicApplication from authentication
// Create the URL object based on an absolute URL
$url = new \XeroPHP\Remote\URL($this->_xero_oauth_object, "https://api.xero.com/api.xro/2.0/TrackingCategories/{TrackCategoryGuid}/Options");
// Pass this to the request as a PUT request
$request = new \XeroPHP\Remote\Request($this->_xero_oauth_object, $url, \XeroPHP\Remote\Request::METHOD_PUT);
// Probably a better way but I just copied and paste the XML from the Xero API docs.
$request->setBody("<Options><Option><Name>My New Option Name</Name></Option></Options>");
// I wrapped this in a try - if it exists, there will be an error as you cant have duplicates.
try {
$request->send();
} catch (Exception $e) {
\Log::warn("Xero error: " . print_r($request->getResponse(), true));
}
// now option is created, new add the option to the tracking category
$tracking = new \XeroPHP\Models\Accounting\TrackingCategory($this->_xero_oauth_object);
$tracking->setTrackingCategoryID('3fceedc7-764e-490a-ac27-25684473af78');
// tracking category name - not sure if I need this
$tracking->setName('Contractor');
// match the option name above
$tracking->setOption('My New Option Name');
am setting up a sand box for a T-Hub Integration with Magento and quickbooks. I've set my life site up locally using WAMP server, and now Its on to trying to tie that local Magento site into T-hub.
The first error that I received stated the
"Connection to Magento store failed. Service authentication failure - Notice: Undefined index: httponly in c:\wamp\www\testsite\appcode\core\mage\Core\Model\Session\Abtract\Varien.php on line 98."
After some searching I found the the general consensus on that one was I had to put an ssl on my local server, done, that problem's gone. Now I'm get a general error message that simply says "Connection to Magento Failed"
I used the test page that atandra included with their files which returned this:
<RESPONSE Version="4.1">
<Envelope>
<Command>GETORDERS</Command>
<StatusCode>9001</StatusCode>
<StatusMessage>
Service authentication failure - Warning: array_key_exists() expects parameter 2 to be array, string given in C:\wamp\www\adamsarms\app\code\core\Mage\Captcha\Model\Observer.php on line 166
</StatusMessage>
<Provider>Magento</Provider>
</Envelope>
</RESPONSE>
Which kicks back to this is the php file:
public function checkUserLoginBackend($observer)
{
$formId = 'backend_login';
$captchaModel = Mage::helper('captcha')->getCaptcha($formId);
$loginParams = Mage::app()->getRequest()->getPost('login', array());
$login = array_key_exists('username', $loginParams) ? $loginParams['username'] : null;
if ($captchaModel->isRequired($login)) {
if (!$captchaModel->isCorrect($this->_getCaptchaString(Mage::app()->getRequest(), $formId))) {
$captchaModel->logAttempt($login);
Mage::throwException(Mage::helper('captcha')->__('Incorrect CAPTCHA.'));
}
}
$captchaModel->logAttempt($login);
return $this;
}
This line is the one it directly points to:
$login = array_key_exists('username', $loginParams) ? $loginParams['username'] : null;
I'm not sure which direction I need to go to fix this error to make t-hub start talking to magento proper, I've included everything that I've got, if someone needs more information please let me know, I just need a better understanding of what might be causing this error to possibly find a path to fixing it.
This is an issue with a Legacy codebase with the T-Hub extension. It was created for PHP 5.3 & Magento versions 1.4 & below. They really should update this thing since people are using it.
The companies official response is this: http://support4.atandra.com/index.php?/Knowledgebase/Article/View/92/4/magento-array_key_exists-error
Which is horrible because it relies on overriding core files.
What's going on is Mage_Captcha_Model_Observer has an event checkUserLoginBackend() that gets fired. This expects the POST info for 'login' to be a certain format. This is something that has changed over the years since legacy code does not have it in this format.
This is a really hacky fix. But it's better than overriding core magento files.
Change the CheckUser() function of Mage/Thub/Model/Run/Run.php to this (I've removed some of their comments):
public function CheckUser()
{
try {
$username = $this->RequestParams['USERID'];
$password = $this->RequestParams['PASSWORD'];
//here we just set the POST to our specified format..
//which is what the observer model thinks it should be
Mage::app()->getRequest()->setPost('login', array(
'username' => $username,
'password' => $password
));
$user = Mage::getSingleton('admin/user');
$userRole = Mage::getSingleton('admin/role');
if ($user->authenticate($username, $password)) {
$loadRole = $userRole->load($user->getRoles($user));
} else {
print($this->xmlErrorResponse($this->RequestParams['COMMAND'], '9000',
'Order download service authentication failure - Login/Password supplied did not match', $this->STORE_NAME, ''));
exit;
}
} catch (Exception $e) {
$this->Msg[] = "Critical Error CheckUser (Exception e)=" . $e->getMessage(); //BB 11Nov2014
print($this->xmlErrorResponse($this->RequestParams['COMMAND'], '9001',
'Service authentication failure - ' . " " . $e->getMessage(), $this->STORE_NAME, ''));
// End - <TIBB> 13Dec2011
exit;
}
}
Another alternative is to extend the Mage_Captcha_Model_Observer class with your own version that removes those array checks in checkUserLoginBackend().
I have a working soap service with several methods available. I am wondering if it is possible to get the name of the method that the user contacting the service is requesting; for example:
try{
$soapServer = new Zend_Soap_Server('http://path-to-service/wsdl');
$soapServer->setClass('My\Soap\Server\Class');
$soapServer->handle();
// is something like this available? :
// $callName = $soapServer->getLastRequestedMethod();
// or
// $callName = $soapServer->getMethod();
}catch(SoapFault $e){
echo $e->getMessage();
}
I didn't see anything like this in the docs # zend or php.net, but just thought I would check to see if anyone knows a way to do this; would be useful for logging purposes. Thanks!
Zend_Soap_Server supports a getLastRequest() method. Example usage would be:
$soapServer = new Zend_Soap_Server('http://path-to-service/wsdl');
$soapServer->setClass('My\Soap\Server\Class');
$soapServer->handle();
$lastRequestXML = $soapServer->getlastRequest()`;
Been having major issues trying to solve this issue, I'll be happy to give a +500 bounty to someone who can help me get this work.
Basically, I'm trying to call this web service using Nusoap:
https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?op=QueryCustomer
This is what I've got so far:
class Eway
{
var $username = 'test#eway.com.au';
var $pw = 'test123';
var $customerId = '87654321';
private function setHeaders($client)
{
$headers = <<<EOT
<eWAYHeader xmlns="http://www.eway.com.au/gateway/managedPayment">
<eWAYCustomerID>$this->customerId</eWAYCustomerID>
<Username>$this->username</Username>
<Password>$this->pw</Password>
</eWAYHeader>
EOT;
$client->setHeaders($headers);
return $client;
}
function getCustomer($ewayId = 9876543211000)
{
$url = 'https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?WSDL';
$client = new Nusoap_client($url, true);
$this->setHeaders($client);
$args['QueryCustomer'] = array('managedCustomerID'=>$ewayId);
$result = $client->call('QueryCustomer', $args);
print_r($result);
}
}
When I run this code and do $eway->getCustomer() I get the following error:
Array
(
[faultcode] => soap:Client
[faultstring] => eWayCustomerID, Username and Password needs to be specified in the soap header.
)
What am I doing wrong?
If you could fix my class and give me working code which is able to do the QueryCustomer method using the test customer id and return its info, I'll be glad to give you +500 rep and my eternal gratitude. Obviously it'll be 48 hours before I can start the bounty, but I promise that I will do it.
I could be missing the point, but you never actually assign the returned object to $client:
function getCustomer($ewayId = 9876543211000)
{
$url = 'https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?WSDL';
$client = new Nusoap_client($url, true);
$client = $this->setHeaders($client);
$args['QueryCustomer'] = array('managedCustomerID'=>$ewayId);
$result = $client->call('QueryCustomer', $args);
print_r($result);
}
You could also set $client as a class variable if desired or by sending the parameter as a reference.
Looking at the data, I do not know if this matters, but you are using var for your class variable declarations and then using private for the function. If you are using php5 I would stay away from the var:
private $username = 'test#eway.com.au';
private $pw = 'test123';
private $customerId = '87654321';
Use the private or public or protected (whichever your class requires) instead to keep consistency. I doubt this will solve your problem, just something to be conscious about.
Possible Solution
Ok, doing some digging of my own, figured this out, you need to encase the actual header you add in a SOAP:Header deal. I tested the below and it was working for me, so give it a try:
private function setHeaders($client)
{
$headers = <<<EOT
<SOAP:Envelope xmlns:SOAP="http://schemas.xmlsoap.org/soap/envelope/" >
<SOAP:Header>
<eWAYHeader xmlns="http://www.eway.com.au/gateway/managedPayment">
<eWAYCustomerID>$this->customerId</eWAYCustomerID>
<Username>$this->username</Username>
<Password>$this->pw</Password>
</eWAYHeader>
</SOAP:Header>
EOT;
$client->setHeaders($headers);
return $client;
}
It did not return any errors. So yea, it seems that is the likely culprit. (Note I also implemented the $client = $this->setHeaders($client); I mentioned above as well.
And my Final Answer is:
Alright did a bit of digging and found something that works. Not saying it is right, but yea it works.
private function setHeaders($client)
{
$headers = <<<EOT
<eWAYHeader xmlns="https://www.eway.com.au/gateway/managedpayment">
<eWAYCustomerID>$this->customerId</eWAYCustomerID>
<Username>$this->username</Username>
<Password>$this->pw</Password>
</eWAYHeader>
EOT;
$client->setHeaders($headers);
return $client;
}
function getCustomer($ewayId = 123456789012)
{
$url = 'https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?WSDL';
$client = new nusoap_client($url);
$client = $this->setHeaders($client);
$args['QueryCustomer'] = array('managedCustomerID'=>$ewayId);
$result = $client->call('QueryCustomer', $args, $namespace='https://www.eway.com.au/gateway/managedpayment', $soapAction='https://www.eway.com.au/gateway/managedpayment/QueryCustomer');
print_r($result);
//echo "\n{$client->request}\n"; // This echos out the response you are sending for debugging.
}
It seems the namespace and soapAction were the key ingredients. I found these using the link you originally posted: https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?op=QueryCustomer
Basically, I just looked at that response, and then did some searching to figure out the soapAction, and then just messed with it until the request being sent matched the page you posted. It returns a failed login, but yea. That generally means something is working, and is probably due to the test data. But that gives you a baseline to go off of.
And the $client->request is a handy debugging tool for the future.
Update 5:
nusoap actually wraps the request with SOAP-ENV, like:
<SOAP-ENV:Header><eWAYHeader xmlns="https://www.eway.com.au/gateway/managedpayment">
<eWayCustomerID>87654321</eWayCustomerID>
<Username>test#eway.com.au</Username>
<Password>test123</Password>
</eWAYHeader></SOAP-ENV:Header>
While in the docs for EWay soap:Header must be used. I couldn't find a mention of the latter in nusoap headers.
Update 4:
This link has a good tip:
Got it. It was a case issue but not
there, and their PDF is incorrect.
For anyone that gets this in the
future, the PDF says:
<eWAYHeader
xmlns="http://www.eway.com.au/gateway/managedPayment">
It should be:
<eWAYHeader
xmlns="https://www.eway.com.au/gateway/managedpayment">
So this right here:
$client->setHeaders($headers);
The SoapClient class doesn't have that method. Instead, you can create a new SoapHeader.
private function setHeaders($client)
{
$headers = new stdClass;
$headers->eWAYCustomerID = $this->customerId;
$headers->Username = $this->username;
$headers->Password = $this->pw;
$ewayHeader = new SoapHeader(
"http://www.eway.com.au/gateway/managedPayment",
"eWAYHeader",
$headers
);
$client->__setSoapHeaders(array($ewayHeader));
return $client;
}
Edit: Alright, digging deeper:
private function prepHeaders()
{
return array(
'eWAYHeader' => array(
'eWAYCustomerID' => $this->customerId,
'Username' => $this->username,
'Password' => $this->pw
)
);
}
function getCustomer($ewayId = 9876543211000)
{
$url = 'https://www.eway.com.au/gateway/ManagedPaymentService/managedCreditCardPayment.asmx?WSDL';
$client = new nusoap_client($url);
$args['QueryCustomer'] = array('managedCustomerID'=>$ewayId);
$result = $client->call('QueryCustomer', $args, null, null, $this->prepHeaders());
print_r($result);
}
What happens if you do that?
I know this is not a full solution to the issue, but although this question is quite old, my findings may help lead to a concrete resolution.
I've been experiencing a similar error in relation to your mention of the HTTP "SOAPAction" header. (I am, however, dealing with a different eWay API than you. I'm dealing with the "Rapid API", which last week was renamed to from "Merchant Hosted Payments", which was part of the reason why my script wasn't working).
To return to the point, I found that if you don't specify the HTTP "SOAPAction" header, eWay returns a SoapFault with the following error message.
"System.Web.Services.Protocols.SoapException: Unable to handle request without a valid action parameter. Please supply a valid soap action."
If you add the HTTP "SOAPAction" header, you get an error no matter what you set it to.
"System.Web.Services.Protocols.SoapException: Server did not recognize the value of HTTP Header SOAPAction: XXX"
I'm also told by a member of eWay's support staff that they have an issues with an internal redirect, which they are now looking into resolving.
<ME> (2012-05-25 02:50:18)
I had an idea of what it could be. What is the "SOAPAction" HTTP header supposed to be set to?
<ME> (2012-05-25 02:52:05)
I couldn't find it in the documentation.
<EWAY_SUPPORT_STAFF> (2012-05-25 02:53:38)
The only thing that is required typically is the endpoint which is https://au.ewaypayments.com/hotpotato/soap.asmx and the <CreateAccessCode xmlns="https://au.ewaypayments.com/hotpotato/">
<EWAY_SUPPORT_STAFF> (2012-05-25 02:54:10)
In my tests it is working but what is happening is that requests are being redirected to the old URL which does not accept the CreateAccessCode method
<ME> (2012-05-25 02:56:58)
You did say that.
<ME> (2012-05-25 02:57:13)
So is this bug happening in the production environment?
<EWAY_SUPPORT_STAFF> (2012-05-25 02:57:57)
Yes it appears so. I have escalated this to Development and attached our last chat transcript and my own test results. They are looking at it now.