All,
I'm trying to get https://github.com/artisaninweb/laravel-soap to work, but no love. This is likely not a problem with the package, but a gap in my understanding of PHP (which I haven't used in a number of years).
The doco says:
SoapWrapper::add(function ($service) {
$service->name('currency')->wsdl('http://currencyconverter.kowabunga.net/converter.asmx?WSDL');
});
$data = [
'CurrencyFrom' => 'USD',
'CurrencyTo' => 'EUR',
'RateDate' => '2014-06-05',
'Amount' => '1000'
];
SoapWrapper::service('currency',function($service) use ($data) {
var_dump($service->getFunctions());
var_dump($service->call('GetConversionAmount',$data)->GetConversionAmountResult);
});
Now that all works great... But how on earth do I get the response from $service->call... back out into my application?
I've tried
$response = SoapWrapper::service('currency',function($service) use ($data) {
$service->call('GetConversionAmount',$data)->GetConversionAmountResult;
});
but that just returns the soap client response.
I've tried:
$response = '';
SoapWrapper::service('currency',function($service) use ($data) {
$response = $service->call('GetConversionAmount',$data)->GetConversionAmountResult;
});
but that does nothing as it seems anything inside that wrapper call only exists inside that block.
They are really the only two things I could think of doing as I'm not very familiar with all these singleton calls that seem to occur in Laravel (I was also of the opinion that they should be avoided like the plague).
Any help would be greatly appreciated.
I'm the creator of the laravel-soap package.
You can give the data back like so:
$response = '';
$data = [
'CurrencyFrom' => 'USD',
'CurrencyTo' => 'EUR',
'RateDate' => '2014-06-05',
'Amount' => '1000'
];
SoapWrapper::service('currency',function($service) use ($data,&$response) {
$response = $service->call('GetConversionAmount',$data)->GetConversionAmountResult;
});
var_dump($response);
This is called passing by reference: http://php.net/manual/en/language.references.pass.php
I've you got some issues with the laravel-soap package please create a issue on Github.
Related
I am using the GoCardless Documentation here to try list all subscriptions for a customer.
I have followed the instructions as you can see below, however nothing at all is displaying when I run this script - does anyone know what I may have done wrong?
require 'vendor/autoload.php';
$client = new \GoCardlessPro\Client(array(
'access_token' => 'XXXXXx',
'environment' => \GoCardlessPro\Environment::LIVE
));
$client->subscriptions()->list([
"params" => ["customer" => "CU000R3B8512345"]
]);
Calling a method on its own doesn’t do anything. It’ll execute the given method, but it’s not going to print anything to your browser screen on its own.
As RiggsFolly says (and is documented in GoCardless’s API documentation), calling $client->subscriptions()->list() will return a cursor-paginated response object. So you need to do something with this result. What that is, I don’t know as it’s your application’s business logic and only you know that.
<?php
use GoCardlessPro\Client;
use GoCardlessPro\Environment;
require '../vendor/autoload.php';
$client = new Client(array(
'access_token' => 'your-access-token-here',
'environment' => Environment::SANDBOX,
));
// Assign results to a $results variable
$results = $client->subscriptions()->list([
'params' => ['customer' => 'CU000R3B8512345'],
]);
foreach ($results->records as $record) {
// $record is a variable holding an individual subscription record
}
Pagination with Gocardless:
function AllCustomers($client)
{
$list = $client->customers()->list(['params'=>['limit'=>100]]);
$after = $list->after;
// DO THINGS
print_r($customers);
while ($after!="")
{
$customers = $list->records;
// DO THINGS
print_r($customers);
// NEXT
$list = $client->customers()->list(['params'=>['after'=>$after,'limit'=>100]]);
$after = $list->after;
}
}
Wow talk about a mind bender. Ok, so whenever I run this
<?php
require_once "../vendor/autoload.php";
use Minishlink\WebPush\WebPush;
use Minishlink\WebPush\Subscription;
$public_key = "PUBLIC_KEY_REDACTED";
$private_key = "PRIVATE_KEY_REDACTED";
$auth = array(
'VAPID' => array(
'subject' => 'https://github.com/Minishlink/web-push-php-example/',
'publicKey' => $public_key, // don't forget that your public key also lives in app.js
'privateKey' => $private_key, // in the real world, this would be in a secret file
)
);
$json = json_decode(file_get_contents("php://input"));
file_put_contents("notification_subscription_info.txt", file_get_contents("php://input"));
try {
$subscription = Subscription::create(json_decode(file_get_contents('php://input'), true));
$notification = [
'subscription' => Subscription::create([ // this is the structure for the working draft from october 2018 (https://www.w3.org/TR/2018/WD-push-api-20181026/)
"endpoint" => "{$json->endpoint}",
"keys" => [
'p256dh' => "{$json->keys->p256dh}",
'auth' => "{$json->keys->auth}"
],
]),
'payload' => 'Hello!',
];
$webPush = new Minishlink\WebPush\WebPush($auth);
$webPush->sendNotification(
$subscription,
$notification['payload'] // optional (defaults null)
);
//version 1 (outside the foreach)
$webPush->flush();
//version 2 (inside the foreach)
foreach($webPush->flush() as $report) { } //This can be empty
} catch (Exception $e) {
echo $e->getMessage();
}
I get very weird behavior in my debugger phpstorm. If I run it with version 1 then I get no push notification and it calls a __destruct method.
If I run version 2 however I get normal behavior and the push notification sends successfully. It appears as if by merely being inside the foreach it changes the flow of the program. I have no idea why this would be and I'm left scratching my head. Does anyone know what is happening?
Edit: I was mistaken about the __destruct method. That's being called because it's the end of the function. In the debugger it's skipping over the flush() call as though it's a literal value. So if I do $report = $webPush->flush(); it will set $report without ever even calling the flush() function (at least that's what it seems like). I even have a breakpoint at the beginning of the flush() function and it isn't hitting it.
Please note that I've also created an issue on the related repo.
In the documentation, it says that this function will return a promise which will resolved after all the promises in the array have resolved.
Here is my implementation;
private function downloadListingImages($contents)
{
$response = [];
$name = 1;
foreach ($contents['images'] as $image) {
$response[] = $this->downloadImage($image, $name);
$name++;
}
return $response;
}
private function downloadImage($link, $name)
{
$guzzle = new Client([
'handler' => HandlerStack::create(new HttpClientAdapter($this->loop)),
]);
$promise = $guzzle->getAsync($link, [
'save_to' => 'assets/' . $name . '.jpg',
]);
return $promise;
}
$promises = $this->downloadListingImages($contents);
Now, everything is fine till this point. But want I want to do is get $contents from a request to my server. So I have a server implementation;
$server = new React\Http\Server(function (Psr\Http\Message\ServerRequestInterface $request) use ($promises) {
\React\Promise\all($promises)->always(function($val) {
file_put_contents('meh.txt', "meh");
});
return new React\Http\Response(
200,
array('Content-Type' => 'text/plain'),
"Hello World!\n"
);
});
What I expect here that $server returns an immediate response (which it does) and after a while see the meh.txt in my repo. However, it never falls to always callback. And even when I don't chain any function on all method, it just resolves itself. Shouldn't it wait until then or something similar to be called to be resolved? How can run my guzzle promises async and get informed when the work is finished?
As long as the objects that passed to \React\Promise\all implement the method then, it works very well. E.g. \React\Promise\all works very fine with with \React\Promise\Promise() and also with \GuzzleHttp\Promise\Promise.
So far I'm not able to reproduce this issue.
As you can see in the documentation the always-method doesn't accept any parameter. Consider to use then instead of always if you in need of a parameter.
Also consider that file_put_contents MAY blocking the event-loop.
I hope this helps.
I modified it all now I have this file that makes my api work.
auth.php:
<?php
include 'Unirest.php';
function login()
{
$headers = array('Accept' => 'application/json');
$data = array(
"grant_type" => "password",
"client_id" => "myclientid",
"client_secret" => "myclientsecret",
"username" => "username",
"password" => "password"
);
$response = Unirest\Request::post('http://i-scent.fr/api/oauth_token', $headers, $data);
// $response->code;
// $response->headers;
return $response->body->access_token;
}
function device_info($device_id,$token){
$header = array('Accept' => 'application/json',
'Authorization' => 'Bearer '.$token );
$response = Unirest\Request::get('http://i-scent.fr/api/devices/'.$device_id,$header);
echo $response->body->name;
echo "</br>";
}
function diffuse($device_id,$token,$duration,$intensity){
$header = array('Accept' => 'application/json', 'Authorization' => 'Bearer '.$token );
$data = array('time' => 1, 'percent' => 50);
$body = Unirest\Request\Body::form($data);
$response = Unirest\Request::put('http://i-scent.fr/app_dev.php/api/device/'.$device_id.'/actions/diffusion',$header,$body);
echo $response->code;
echo "</br>";
}
When I use all the functions in a simple script it works perfectly on my website. But when I put it like this in my webhook, I have error 500 internal server error. I have all the unirest libraries.
<?php
include "auth.php";
function processMessage($update) {
if($update["result"]["action"] == "sayHello"){
$token = login();
$name = device_info("1966",$token);
diffuse("1966",$token,"0.5","50");
sendMessage(array(
"source" => $update["result"]["source"],
"speech" => "bonjour webhook",
"displayText" => "bonjour webhook",
"contextOut" => array()
));
}
}
function sendMessage($parameters) {
echo json_encode($parameters);
}
$update_response = file_get_contents("php://input");
$update = json_decode($update_response, true);
if (isset($update["result"]["action"])) {
processMessage($update);
}
Error 500 is supposed to mean that the webhokk's script crashed somewhere but I don't know where and why.
Update 2
Based on your most recent code, you're including "auth.php", which works in the original environment (which is being called as part of a web page, it sounds like).
Your code has two functions, device_info() and diffuse(), which output their results instead of returning them. This output isn't JSON, and includes HTML markup. This is being sent as part of the result of your webhook and will cause what is returned to be invalid.
Update
Based on your latest code, there are still many logical, and a few syntactical, problems.
A "500 Internal Server Error" indicates that your program didn't run correctly and crashed for some reason. As posted, it is missing a closing }, which could be the problem if that isn't in your actual code.
Even if you fix that, there are many issues with the code:
It isn't clear what you intend to do with the results of calling your "test1" script. You store them in $data and don't do anything with it.
You're calling the other website (test1) before you look at what the user has asked you to do. Which is fine, but then why do you care what the user is asking you?
Original Answer
There are a few errors here, but the underlying problem is that you're mixing up where things run and the capabilities of the caller to your webhook.
For a Dialogflow webhook, Google/Dialogflow is sending JSON (which you seem to be handling ok), and expecting back JSON. Although it looks like you send this back as part of send_message(), you're also sending something back when you call connexion(). What you're sending back in this case is not JSON, but HTML with JavaScript.
Which leads to the second problem - If this was php that was generating an HTML page that included a script, you'd be in fine shape. But it isn't. You have to send back only JSON.
You can do something like this to call the other API and get back the contents:
$body = file_get_contents("http://google-home.exhalia.fr/test1");
Which will set $body to the body of the page you've called. What you do with that, at that point, is up to you. But you need to make this call before your call to send_message() because you want to represent the contents as part of what you're saying.
(See How to send a GET request from PHP? for a discussion of other methods available to you in case you need to do a POST, use header information, etc.)
I am working on a billing plugin for oxwall. The lack of documentation is hell and I wonder why this is not a priority.
I have used the paypal and ccbill plugins as guides, and up till now things have been well, manageable.
Now, I need to submit the order to the gateway. For paypal and ccbill, they expect the details in a html POST. However, for this gateway (Paystack) the order detail has to be submitted as a JSON document, with an Authorization header...then a header redirect to the authorization_url.
I'd appreciate all the help.
Ok, I figured this out by
1. Taking advantage of a PHP library for the gateway...which supports guzzle and cURL as fallback.
2. calling the transaction initialize inside of form()
See snippet below...
if ( $billingService->prepareSale($adapter, $sale) )
{
$totalAmount = floatval($sale->totalAmount * 100); //convert to kobo
$saleHash = $sale->hash;
$userEmail = $userService->findUserById($sale->userId)->getEmail();
$metadata = array(
'itemName' => $sale->entityDescription,
'itemID' => $sale->entityKey,
);
$response = $paystack->transaction->initialize([
'reference' => $saleHash,
'amount' => $totalAmount, // in kobo
'email' => $userEmail,
'callback_url' => $fields['notify_url'],
'metadata' => json_encode($metadata),
]);
$url = $response->data->authorization_url;
$masterPageFileDir = OW::getThemeManager()->getMasterPageTemplate('blank');
OW::getDocument()->getMasterPage()->setTemplate($masterPageFileDir);
header('Location: '.$url);
$billingService->unsetSessionSale();
}