php-ews icon indicating copy to clipboard operation
php-ews copied to clipboard

SOAP Server response requires implicit call to toXmlObject

Open ajefferiss opened this issue 7 years ago • 4 comments
trafficstars

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.

ajefferiss avatar Feb 01 '18 08:02 ajefferiss

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

Garethp avatar Feb 01 '18 15:02 Garethp

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

Garethp avatar Feb 01 '18 16:02 Garethp

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.

ajefferiss avatar Feb 07 '18 11:02 ajefferiss

Hello,

I try to test @Garethp example.

Can someone explain what the $uri should hold ? I didn't found help about this.

Thanks

kl3sk avatar Mar 18 '22 13:03 kl3sk