php-ews
php-ews copied to clipboard
SOAP Server response requires implicit call to toXmlObject
As part of a script I'm working on, I needed to write a SOAP Server which would respond to EWS NewMail Notifications. Initially I attempted to return the SendNotificationResponseMessage like so:
<?php
require_once('vendor/autoload.php');
use garethp\ews\API\Message\SendNotificationResultType;
use garethp\ews\API\Enumeration\SubscriptionStatusType;
class EwsPushService
{
public function SendNotification($arg)
{
$responseCode = $arg->ResponseMessages->SendNotificationResponseMessage->ResponseCode;
$notification = $arg->ResponseMessages->SendNotificationResponseMessage->Notification;
if ($responseCode == "NoError") {
if (isset($notification->NewMailEvent)) {
/* Download new message... */
}
}
$result = new SendNotificationResultType();
$result->setSubscriptionStatus(SubscriptionStatusType::OK);
return $result;
}
}
$server = new SoapServer(
'php-ews/wsdl/NotificationService.wsdl',
array('uri' => $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'])
);
$server->setObject($service = new EwsPushService());
$server->handle();
This was resulting in an SOAP Error, as discussed in https://github.com/Garethp/php-ews/issues/117. To ensure that ucfirst was correctly called the SendNotification function needed to call toXmlObject first; which resulted in:
<?php
require_once('vendor/autoload.php');
use garethp\ews\API\Message\SendNotificationResultType;
use garethp\ews\API\Enumeration\SubscriptionStatusType;
class EwsPushService
{
public function SendNotification($arg)
{
$responseCode = $arg->ResponseMessages->SendNotificationResponseMessage->ResponseCode;
$notification = $arg->ResponseMessages->SendNotificationResponseMessage->Notification;
if ($responseCode == "NoError") {
if (isset($notification->NewMailEvent)) {
/* Download new message... */
}
}
$result = new SendNotificationResultType();
$result->setSubscriptionStatus(SubscriptionStatusType::OK);
return $result->toXmlObject();
}
}
$server = new SoapServer(
'php-ews/wsdl/NotificationService.wsdl',
array('uri' => $_SERVER['REQUEST_SCHEME'] . '://' . $_SERVER['HTTP_HOST'] . $_SERVER['PHP_SELF'])
);
$server->setObject($service = new EwsPushService());
$server->handle();
If possible wrapping this implict call to toXmlObject up some how would be extremely helpful.
It'll take a bit to develop this, since I'll need to do the dev work on a public API, but how does the following API sound?
use garethp\ews\NotificationAPI;
use garethp\ews\API\Message\SendNotificationResponseMessage;
use garethp\ews\API\Enumeration\SubscriptionStatusType;
NotificationAPI::handlePullNotification($uri, function (SendNotificationResponseMessage $response) {
$notification = $response->getNotification();
$newMailEvent = $notification->getNewMailEvent();
if ($newMailEvent === null) {
return SubscriptionStatusType::OK;
}
//Download new message
return SubscriptionStatusType::OK;
});
So the signature would probably be something along the lines of
handlePullNotification(string $uri, callable $handle, array $serverOptions = array()): SoapServer
And it will throw an exception if ResponseCode isn't NoError or if you return something other than SubscriptionStatusType::OK or SubscriptionStatusType::UNSUBSCRIBE
Turned out it was easier than I thought. I want to add a couple more features before I release it as a version, but I've added the NotificationAPI to master. Here's the example I wrote. Note that it passes the handler the notification directly
Apologies for the slow reply, that API looks good. When I've got a moment to pull down master I'll give it a test with my setup.
Hello,
I try to test @Garethp example.
Can someone explain what the $uri should hold ? I didn't found help about this.
Thanks