Giter Site home page Giter Site logo

php-ews's Introduction

PHP Exchange Web Services

Build Status Scrutinizer Code Quality Code Coverage

The PHP Exchange Web Services library (php-ews) is intended to make communication with Microsoft Exchange servers using Exchange Web Services easier. It handles the NTLM authentication required to use the SOAP services and provides an object-oriented interface to the complex types required to form a request.

Dependencies

  • PHP 5.5+
  • cURL with NTLM support (7.23.0+ recommended)
  • Composer
  • Exchange 2007 or 2010*

*Note: Not all operations or request elements are supported on Exchange 2007.

Installation

Require the composer package and use away

composer require garethp/php-ews

Usage

The library can be used to make several different request types. In order to make a request, you need to instantiate a new API object:

$ews = API::fromUsernameAndPassword($server, $username, $password, $options = array());

The API::fromUsernameAndPassword static constructor takes four parameters:

  • $server: The url to the exchange server you wish to connect to, without the protocol. Example: mail.example.com.
  • $username: The user to connect to the server with. This is usually the local portion of the users email address. Example: "user" if the email address is "[email protected]".
  • $password: The user's plain-text password.
  • $options: (optional): A group of options to be passed in
  • $options['version']: The version of the Exchange sever to connect to. Valid values can be found at ExchangeWebServices::VERSION_*. Defaults to Exchange 2010.
  • $options['timezone']: A timezone to use for operations. This isn't a PHP Timezone, but a Timezone ID as defined by Exchange. See https://github.com/Garethp/php-ews/wiki/Exchange-Timezones
  • $options['httpClient']: If you want to inject your own GuzzleClient for the requests
  • $options['httpPlayback']: See the Testing Section

Once you have your API object, you need to build your request object. The type of object depends on the operation you are calling. If you are using an IDE with code completion it should be able to help you determine the correct classes to use using the provided docblocks.

The request objects are build similar to the XML body of the request. See the resources section below for more information on building the requests.

Simple Library Usage

There's work in progress to simplify some operations so that you don't have to create the requests yourself. Examples are located here to browse in small snippets. If you have more examples you want to add, just make a PR for it. If you would like to request an example, file a Github issue, and I'll try to create it if I know how

Manual Usage

While simple library usage is the way to go for what it covers, it doesn't cover everything, in fact it covers rather little. If you want to do anything outside of it's scope, go ahead and use API::getClient() as a generic SOAP client, and refer to the Microsoft documentation on how to build your requests. Here's an example

$api = API::withUsernameAndPassword($server, $username, $password);

$start = new DateTime('8:00 AM');
$end = new DateTime('9:00 AM');

$request = array(
    'Items' => array(
        'CalendarItem' => array(
            'Start' => $start->format('c'),
            'End' => $end->format('c'),
            'Body' => array(
                'BodyType' => Enumeration\BodyTypeType::HTML,
                '_value' => 'This is <b>the</b> body'
            ),
            'ItemClass' => Enumeration\ItemClassType::APPOINTMENT,
            'Sensitivity' => Enumeration\SensitivityChoicesType::NORMAL,
            'Categories' => array('Testing', 'php-ews'),
            'Importance' => Enumeration\ImportanceChoicesType::NORMAL
        )
    ),
    'SendMeetingInvitations' => Enumeration\CalendarItemCreateOrDeleteOperationType::SEND_TO_NONE
);

$request = Type::buildFromArray($request);
$response = $api->getClient()->CreateItem($request);

Testing

Testing is done simply, and easy, wit the use of my own HttpPlayback functionality. The HttpPlayback functionality is basically a built in History and MockResponses Middleware for Guzzle. With a flick of an option, you can either run all API calls "live" (Without interference), "record" (Live, but saves all the responses in a file) or "playback" (Use the record file for responses, never hitting the exchange server). This way you can write your tests with the intention to hit live, record the responses, then use those easily. You can even have different phpunit.xml files to switch between them, like this library does. Here's some examples of running the different modes:

$client = API::withUsernameAndPassword(
    'server',
    'user',
    'password',
    [
        'httpPlayback' => [
            'mode' => 'record',
            'recordLocation' => __ROOT__ . DS . '/recordings.json'
        ]
    ]
);

//Do some API calls here

That will then record al lthe responses to the recordings.json file. Likewise, to play back

$client = API::withUsernameAndPassword(
    'server',
    'user',
    'password',
    [
        'httpPlayback' => [
            'mode' => 'playback',
            'recordLocation' => __ROOT__ . DS . '/recordings.json'
        ]
    ]
);

//Do some API calls here

And then those calls will play back from the recorded files, allowing you to continuously test all of your logic fully without touching the live server, while still allowing you to double check that it really works before release by changing the mode option.

Versioning

The versioning of this component is done to comply with semver standards. This means that any BC breaks that are made will result in an increasing Major Version number (IE: 1.x -> 2.x), and new features that do not result in BC breaks will result in Minor version increases (IE: 1.1.x -> 1.2.0) and bug fixes that do not result in new features or BC breaks will result in the Patch number increasing (IE: 1.0.0 -> 1.0.1). The exception is development pre-1.0 release, where the Minor number is treated as a Major and the patch number is treated as both Patch and Minor numbers. That means that you can pin your composer to, say, 0.6.* and you will not receive any BC breaks, as BC breaks will result in the Minor version changing.

Resources

Support

All questions should use the issue queue. This allows the community to contribute to and benefit from questions or issues you may have. Any support requests sent to my email address will be directed here.

Contributions

Contributions are always welcome!

Contributing Code

If you would like to contribute code please fork the repository on github and issue a pull request against the master branch. It is recommended that you make any changes to your fork in a separate branch that you would then use for the pull request. If you would like to receive credit for your contribution outside of git, please add your name and email address (optional) to the CONTRIBUTORS.txt file. All contributions should follow the PSR-1 and PSR-2 coding standards. If you're interested in a list of things that still needs to be done, check out the TODO.md file

Contributing Documentation

If you would like to contribute to the documentation, make a PR against this repository with documentation as examples in the examples/ folder. I request that you do not make changes to the home page but other pages (including new ones) are fair game. Please leave a descriptive log message for any changes that you make.

php-ews's People

Contributors

cby016 avatar commifreak avatar daareiza avatar deyv avatar didilem avatar eldiddio avatar errakhaoui avatar exussum12 avatar fglueck avatar garethp avatar jamesiarmes avatar koab avatar luthordevelopment avatar mot3rror avatar nvanheuverzwijn avatar scrutinizer-auto-fixer avatar tekuonline avatar thisispiers avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

php-ews's Issues

Accessing the raw message or saving a message to a file

I'm looking for a way to get a message representation that's suitable for saving to a .eml or .msg file. In the jamesiarmes version there is a function to return the MIME content which can then be decoded and saved into a .eml file. Is there a way to do the same in php-ews?

Thanks for the updates to the project! We moved to hosted exchange on o365 and found that our old codebase didn't work with the new server! I'm glad someone has moved the project on for compatibility.

error with composer

[ErrorException]
ZipArchive::extractTo(C:\xampp\htdocs\devintranet\protected/vendor/compose
/8cb5d89c/Garethp-php-ews-1aeace8\Resources\recordings\jamesiarmes\PEWS\Te
t/APITest::testCreateItems.json): failed to open stream: Invalid argument

Paging

I'm trying to read contacts from a public folder on Exchange 2013. I managed to read from public folders on my server successfully using the ContactsAPI. But the getContacts() methods throws an exception if the folder contains more than 1000 elements.

I'm new to EWS, so I searched a bit and found out that I have to use paging to avoid hitting the 1000 elements per request limit on the server. How do I do that with the ContactsAPI or php-ews in general? All of the examples that I found don't seem to work with this version of php-ews.

Error for exchange 2010 login it works for 2007

I am using old version and contact sync was working very fine but for exchange 2010 contact sync is giving error

Fatal error: Uncaught exception 'EWS_Exception' with message 'SOAP client returned status of 401' in C:\wamp\www\exchange\php-ews-master\ExchangeWebServices.php:1221 Stack trace: #0 C:\wamp\www\exchange\php-ews-master\ExchangeWebServices.php(1064): ExchangeWebServices->processResponse(NULL) #1 C:\wamp\www\exchange\contact_sync.php(63): ExchangeWebServices->SyncFolderItems(Object(EWSType_SyncFolderItemsType)) #2 {main} thrown in C:\wamp\www\exchange\php-ews-master\ExchangeWebServices.php on line 1221

The localhost page isn’t working - ERR_EMPTY_RESPONSE

I've used Composer to install your library but I'm getting this error

The localhost page isn’t working

localhost didn’t send any data.
ERR_EMPTY_RESPONSE

I'm working locally and this is the code I'm using...

<?php
require_once "vendor/autoload.php";
use jamesiarmes\PEWS\API\Type;
use jamesiarmes\PEWS\Mail\MailAPI;

$api = MailAPI::withUsernameAndPassword('webmail.forest.wokingham.sch.uk', 'redacted', 'redacted');
$mail = $api->getMailItems();

echo $this->server_address;
echo $mail;

Any ideas?

Versioning confusion

Hi Garethp,

what is the intent to generate tags for v0.7.9 and v0.8.3? to be specific what is the difference between this two?

The request failed schema validation: The element 'From' in namespace

When set 'setFrom' occurs the error

SoapFault in NTLMSoapClient.php line 122:
The request failed schema validation: The element 'From' in namespace 'http://schemas.microsoft.com/exchange/services/2006/types' has incomplete content. List of possible elements expected: 'Mailbox' in namespace 'http://schemas.microsoft.com/exchange/services/2006/types'.

in NTLMSoapClient.php line 122
at SoapClient->__call('CreateItem', array(object(Type))) in NTLMSoapClient.php line 122
at NTLMSoapClient->__call('CreateItem', array(object(Type))) in MiddlewareFactory.php line 18
at ExchangeWebServices->garethp\ews\API\ExchangeWebServices{closure}(object(MiddlewareRequest), object(Closure)) in ExchangeWebServices.php line 498
at ExchangeWebServices->garethp\ews\API{closure}(object(MiddlewareRequest)) in MiddlewareFactory.php line 32
at ExchangeWebServices->garethp\ews\API\ExchangeWebServices{closure}(object(MiddlewareRequest), object(Closure)) in ExchangeWebServices.php line 498
at ExchangeWebServices->garethp\ews\API{closure}(object(MiddlewareRequest)) in MiddlewareFactory.php line 48
at ExchangeWebServices->garethp\ews\API\ExchangeWebServices{closure}(object(MiddlewareRequest), object(Closure)) in ExchangeWebServices.php line 498
at ExchangeWebServices->garethp\ews\API{closure}(object(MiddlewareRequest)) in MiddlewareFactory.php line 55
at ExchangeWebServices->garethp\ews\API\ExchangeWebServices{closure}(object(MiddlewareRequest), object(Closure)) in ExchangeWebServices.php line 498
at ExchangeWebServices->garethp\ews\API{closure}(object(MiddlewareRequest)) in MiddlewareFactory.php line 66
at ExchangeWebServices->garethp\ews\API\ExchangeWebServices{closure}(object(MiddlewareRequest), object(Closure)) in ExchangeWebServices.php line 498

FindItem and Restrictions with multiple IsEqualTo

Hi,

when running this request I get the error that the 'Or' element is not valid. When using only one 'IsEqualTo' everything is working fine. But i want to filter by multiple custom ids. Any idas?

EXTENDED_PROPERTY_ID = array(
    'PropertySetId' => 'c11ff723g-af43-4555-9952-8f4248a11c3e',
    'PropertyName' => 'customproperty',
    'PropertyType' => 'Integer',
);
 $request = [
            'ItemShape' => array(
                'BaseShape' => 'IdOnly',
                'AdditionalProperties' => [
                    'ExtendedFieldURI' => ExchangeContactService::EXTENDED_PROPERTY_ID,
            ]),
            'Traversal' => 'Shallow',
            'ParentFolderIds' => array(
                'FolderId' => $folderId->toXmlObject()
            ),
            'Restriction' => array(
                    array('Exists' => array(
                        'ExtendedFieldURI' => EXTENDED_PROPERTY_ID,
                    )),
                    'Or' => array(
                        array('And' => array(
                            'IsEqualTo' => array(
                                'ExtendedFieldURI' => EXTENDED_PROPERTY_ID,
                                'FieldURIOrConstant' => array(
                                    'Constant' => array(
                                        'Value' => 7)
                                ),
                            ),
                        )),
                        array('And' => array(
                            'IsEqualTo' => array(
                                'ExtendedFieldURI' => EXTENDED_PROPERTY_ID,
                                'FieldURIOrConstant' => array(
                                    'Constant' => array(
                                        'Value' => 8)
                                ),
                            ),
                        )),
                    )
                ),
            ]
$request = array_replace_recursive($request, $options);
$request = API\Type::buildFromArray($request);

return $this->api->getClient()->FindItem($request);

Get user profile information

Hi everyone,

I am looking for a way to get basic user information like profile image, email etc.
Is there any way to achieve that?

Thank you very much in advance!

php ews Copy Message from inbox to other user's inbox

With php-ews is there a possibility to copy a message from an inbox to other user's inbox?

The goal is that a message is created by php-ews in a web interface, saved to a shared inbox and after this save a copy of the message to user's inbox.

The problem is in converting message-ID from Exchange 2013 in function convert_id()

My code so far:

function getEmailsBWOtoPublicFolder($db, $link){
    //user with full access to exchange-server
    $host = "xxx.xxx.xxx.xxx";
    $username = "xxx";
    $password = "xxxxxxx";

        $ews = new ExchangeWebServices($host, $username, $password, ExchangeWebServices::VERSION_2007_SP1);

    //get folders in SENT_ITEMS
    $request = new EWSType_FindItemType();
    $request->ItemShape = new EWSType_ItemResponseShapeType();
    $request->ItemShape->BaseShape = EWSType_DefaultShapeNamesType::ALL_PROPERTIES;

    $request->Traversal = EWSType_ItemQueryTraversalType::SHALLOW;

    // Limits the number of items retrieved
    $request->IndexedPageItemView = new EWSType_IndexedPageViewType();
    $request->IndexedPageItemView->BasePoint = "Beginning";
    $request->IndexedPageItemView->Offset = 0; // Item number you want to start at
    $request->IndexedPageItemView->MaxEntriesReturned = 1000; // Numer of items to return in total

    // Point to the attendee (shared) outbox.
    $request->ParentFolderIds = new EWSType_NonEmptyArrayOfBaseFolderIdsType();
    $request->ParentFolderIds->DistinguishedFolderId = new EWSType_DistinguishedFolderIdType();
    $request->ParentFolderIds->DistinguishedFolderId->Id = EWSType_DistinguishedFolderIdNameType::INBOX;

    // sort order
    $request->SortOrder = new EWSType_NonEmptyArrayOfFieldOrdersType();
    $request->SortOrder->FieldOrder = array();
    $order = new EWSType_FieldOrderType();

    // sorts mails so that oldest appear first
    // more field uri definitions can be found from types.xsd (look for UnindexedFieldURIType)

    $order->FieldURI = '';
    @$order->FieldURI->FieldURI = 'item:DateTimeReceived'; // @ symbol stops the creating default object from empty value error
    $order->Order = 'Ascending';
    $request->SortOrder->FieldOrder[] = $order;

    $response = $ews->FindItem($request);

    // Loop through each item if event(s) were found in the timeframe specified
    $mail_items = array();
    if ($response->ResponseMessages->FindItemResponseMessage->ResponseCode == "NoError") {
        $count=$response->ResponseMessages->FindItemResponseMessage->RootFolder->TotalItemsInView;
        if ($count>0){
            if (!is_array($response->ResponseMessages->FindItemResponseMessage->RootFolder->Items->Message)) {
                $mail_items[] = $response->ResponseMessages->FindItemResponseMessage->RootFolder->Items->Message;
            } else {
                $mail_items = $response->ResponseMessages->FindItemResponseMessage->RootFolder->Items->Message;
            }
        }
    }

    for ($i=0;$i<count($mail_items);$i++){
        $id = $mail_items[$i]->ItemId->Id;
        $change_key = $mail_items[$i]->ItemId->ChangeKey;
        $subject = $mail_items[$i]->Subject;
        $usermail = $mail_items[$i]->From;
             if (stristr($subject,$num_project)!==false){         
                //create folder in user outbox
                create_folder_user_outbox($usermail, $num_project);

               //save Email to User Folder
          $arr_user=find_folder_user_outbox($usermail, $num_project);
              $user_folder_id=$arr_user[0];
              $user_folder_ckey=$arr_user[1];

              //there is my problem: i get 'id is missing' error message
              saveEmailUserFolder($id, $change_key, $user_folder_id, $user_folder_ckey, $usermail);
         }
     }
}
//******************************************
//create folder in user sent items
//******************************************
function create_folder_user_outbox($email_search, $num_project){
    //user with full access to exchange-server
    $host = "xxx.xxx.xxx.xxx";
    $username = "xxx";
    $password = "xxxxxxxxx";

    //write in this calendar    
    $email_of_attendee=$email_search;

    date_default_timezone_set('Europe/Berlin');

    // Create the service object            
    $ews = new ExchangeWebServices($host, $username, $password);

    //create folder in user outbox
    $request = new EWSType_CreateFolderType();
    $request->Folders = new EWSType_NonEmptyArrayOfBaseFolderIdsType();
    $request->Folders->Folder = new EWSType_FolderType();
    $request->Folders->Folder->DisplayName = $num_project;
    $request->Folders->Folder->FolderClass = 'IPF.Note';

    $request->ParentFolderId = new EWSType_NonEmptyArrayOfBaseFolderIdsType();
    $request->ParentFolderId->DistinguishedFolderId = new EWSType_DistinguishedFolderIdType();
    $request->ParentFolderId->DistinguishedFolderId->Id = EWSType_DistinguishedFolderIdNameType::SENT;
    $request->ParentFolderId->DistinguishedFolderId->Mailbox = new StdClass;
    $request->ParentFolderId->DistinguishedFolderId->Mailbox->EmailAddress = $email_of_attendee;
    $response = $ews->CreateFolder($request);
}
//******************************************
//create folder in user sent items
//******************************************
function find_folder_user_outbox($email_search, $num_project){
    //user with full access to exchange-server
    $host = "xxx.xxx.xxx.xxx";
    $username = "xxx";
    $password = "xxxxxxxx";

    // Create the service object            
    $ews = new ExchangeWebServices($host, $username, $password);    

    //write in this calendar    
    $email_of_attendee=$email_search;

    date_default_timezone_set('Europe/Berlin');

    //get folders in SENT_ITEMS
    $request = new EWSType_FindFolderType();
    $request->Traversal = EWSType_FolderQueryTraversalType::DEEP; 
    $request->FolderShape = new EWSType_FolderResponseShapeType();
    $request->FolderShape->BaseShape = EWSType_DefaultShapeNamesType::ALL_PROPERTIES;

    // configure the view
    $request->IndexedPageFolderView = new EWSType_IndexedPageViewType();
    $request->IndexedPageFolderView->BasePoint = 'Beginning';
    $request->IndexedPageFolderView->Offset = 0;

    $request->ParentFolderIds = new EWSType_NonEmptyArrayOfBaseFolderIdsType();
    $request->ParentFolderIds->DistinguishedFolderId = new EWSType_DistinguishedFolderIdType();
    $request->ParentFolderIds->DistinguishedFolderId->Id = EWSType_DistinguishedFolderIdNameType::SENT;
    $request->ParentFolderIds->DistinguishedFolderId->Mailbox = new StdClass;
    $request->ParentFolderIds->DistinguishedFolderId->Mailbox->EmailAddress = $email_of_attendee;
    // make the actual call
    $response = $ews->FindFolder($request);

    // Loop through each item if event(s) were found in the timeframe specified
    $folder_items = array();
    if ($response->ResponseMessages->FindFolderResponseMessage->ResponseCode == "NoError") {
        $count=$response->ResponseMessages->FindFolderResponseMessage->RootFolder->TotalItemsInView;
        if ($count>0){
            if (!is_array($response->ResponseMessages->FindFolderResponseMessage->RootFolder->Folders->Folder)) {
                $folder_items[] = $response->ResponseMessages->FindFolderResponseMessage->RootFolder->Folders->Folder;
            } else {
                $folder_items = $response->ResponseMessages->FindFolderResponseMessage->RootFolder->Folders->Folder;
            }
        }
    }

    for ($i=0;$i<count($folder_items);$i++){
        $project_folder_id = $folder_items[$i]->FolderId->Id;
        $project_folder_ckey = $folder_items[$i]->FolderId->ChangeKey;
        $displayname=$folder_items[$i]->DisplayName;

        if (stristr($displayname,$num_project)!==false){
            return array($project_folder_id, $project_folder_ckey);
            //echo $project_folder_id.' ';
            break;
        }
    }
}
//***************************************************
//save message to given folder (user folder)
//***************************************************
function saveEmailUserFolder($message_id, $msg_ckey, $project_folder_id, $project_folder_ckey, $usermail){
    require_once('convert_id.php');
    // Define EWS
    //user with full access to exchange-server
    $host = "xxx.xxx.xxx.xxx";
    $username = "xxx";
    $password = "xxxxxxxxx";

    $ews = new ExchangeWebServices($host, $username, $password, ExchangeWebServices::VERSION_2007_SP1);

     //there is my problem: i get 'id is missing' error message with convertID
    echo "message_id=".$message_id.'<br>';
    $message_id_converted=convert_id($message_id, $msg_ckey, $usermail);
    //echo "$message_id_converted=".$message_id_converted.'<br>';
    $message_id=$message_id_converted;
    /*
    echo "folder_id=".$project_folder_id.'<br>';
    $project_folder_id_converted=convert_id($project_folder_id, $project_folder_ckey, $usermail);
    //echo "$message_id_converted=".$message_id_converted.'<br>';
    $project_folder_id=$project_folder_id_converted;
    */
    $request = new EWSType_CopyItemType();  
    $request->ToFolderId = new EWSType_NonEmptyArrayOfBaseFolderIdsType();
    $request->ToFolderId->FolderId = new EWSType_FolderIdType();
    $request->ToFolderId->FolderId->Id = $project_folder_id;
    $request->ToFolderId->FolderId->ChangeKey = $project_folder_ckey;

    $request->ItemIds = new EWSType_NonEmptyArrayOfBaseItemIdsType();
    $request->ItemIds->ItemId = new EWSType_ItemIdType();
    $request->ItemIds->ItemId->Id = $message_id;
    $request->ItemIds->ItemId->ChangeKey = $msg_ckey;

    // Generic execution sample code
    $response = $ews->CopyItem($request);
    //echo '<pre>'.print_r($response,1).'</pre>';
}

file convert_id.php contains the converter function:

require_once "vendor/autoload.php";
use garethp\ews\API\Type;
use garethp\ews\API\Enumeration;
use garethp\ews\Mail\MailAPI as API;

function convert_id($ews2007Id, $changeKey, $usermail){
    $host = "xxx.xxx.xxx.xxx";
    $username = "xxx";
    $password = "xxxxxxxxx";

    //Create and build the client
    $api = API::withUsernameAndPassword($host, $username, $password);

    $ews2007ItemId = new Type\ItemIdType($ews2007Id, $changeKey);
    $ews2010ItemId = $api->convertIdFormat(
        $ews2007ItemId,
        Enumeration\IdFormatType::EWS_LEGACY_ID,
        Enumeration\IdFormatType::EWS_ID,
        $usermail
    );

    return $ews2010ItemId;
}

reading calendar

I have two issues:

I need to read calendar items of other people, eg userid: joe. They have granted me full access. I'm stuck on how to do that with garethp. I had it working with jamesiarmes, but am trying to move forward.

Also, all the examples return a structure filled with private data I'm not allowed to read. How do I enumerate through the list of events, and extract the date/time/topic of meetings?

So I'm hopefully asking for a simple example.

Thanks
Erick

Property Body returning null

Hello guys..

The field Body is returning null.

Is there any way to achieve that?

Thank you very much!

$api = MailAPI::withUsernameAndPassword('', '', '', ['version' => ExchangeWebServices::VERSION_2010, 'primarySmtpEmailAddress' => '...']);

$mailItem = $api->getMailItems()[0];

$mailItem->getBody();
    #sender: SingleRecipientType {#435 ▶}
    #toRecipients: null
    #ccRecipients: null
    #bccRecipients: null
    #isReadReceiptRequested: false
    #isDeliveryReceiptRequested: false
    #conversationIndex: b"\x01Ò\x08LJ¹X¦°é,áKª¿,¸\x7Fk\x7Fýt\x00\x00\x11•à"
    #conversationTopic: "04/09 3012-CWB-CGH"
    #from: SingleRecipientType {#437 ▶}
    #internetMessageId: "<[email protected].**.com.br>"
    #isRead: true
    #isResponseRequested: null
    #references: "<2EAB1DE9CCE38F4887B379CAA3C49A5212FEC5@WPRPBRMBX02.**.**.com.br>"
    #replyTo: null
    #receivedBy: SingleRecipientType {#439 ▶}
    #receivedRepresenting: SingleRecipientType {#441 ▶}
    #mimeContent: null
    #itemId: ItemIdType {#431 ▶}
    #parentFolderId: FolderIdType {#432 ▶}
    #itemClass: "IPM.Note"
    #subject: "RES: 04/09 3012-CWB-CGH"
    #sensitivity: "Normal"
    #body: null
    #attachments: null
    #dateTimeReceived: "2016-09-06T14:43:34Z"
    #_typeMap: array:5 [▶]
    #size: 19298
    #categories: null
    #importance: "Normal"
    #inReplyTo: "<2EAB1DE9CCE38F4887B379CAA3C49A5212FEC5@WPRPBRMBX02.**.**.com.br>"
    #isSubmitted: false
    #isDraft: false
    #isFromMe: false
    #isResend: false
    #isUnmodified: false
    #internetMessageHeaders: null
    #dateTimeSent: "2016-09-06T14:39:30Z"
    #dateTimeCreated: "2016-09-06T14:43:34Z"
    #responseObjects: null
    #reminderDueBy: null
    #reminderIsSet: false
    #reminderMinutesBeforeStart: "0"
    #displayCc: ""
    #displayTo: "Co***tação A***sos - E***cução de Escala"
    #hasAttachments: false
    #extendedProperty: null
    #culture: "pt-BR"
    #effectiveRights: EffectiveRightsType {#433 ▶}
    #lastModifiedName: "Contestação Atrasos - Execução de Escala"
    #lastModifiedTime: "2016-09-06T14:46:55Z"
    #isAssociated: false
    #webClientReadFormQueryString: "****@***.com/?ae=Item&a=Open&t=IPM.Note&id=****&exvsurl=1"
    #webClientEditFormQueryString: null
    #conversationId: ItemIdType

HttpPlayback dependency

The dependency on HttpPlayback forces you to set minimum stability to dev, while this is not the end of the world I would like to ask you to create a release for the HttpPlayback package.

Calendar Event "Body" is always blank when doing getCalendarItems()

When I fetch a user's calendar items, the Body is ALWAYS blank.

Here is some output from print_r:

[itemClass:protected] => IPM.Appointment
[subject:protected] => Test 2
[sensitivity:protected] => Normal
[body:protected] =>
[attachments:protected] =>
[dateTimeReceived:protected] => 2016-08-26T13:33:25Z

I seem to get all other data points just fine (at least the ones I'm looking for are all there except Body)

Any help is greatly appreciated!

How to convert legacy contact ID?

When I try the following:

        $api = $this->makeImpersonatedAPIRequest();

        $contactId = new ItemIdType($contact->contact_id, $contact->change_key);

        $api->updateContactItem($contactId, array(
            'GivenName' => 'Jane',
            'EmailAddress:EmailAddress1' => array (
                'EmailAddresses' => array (
                    'Entry' => array('Key' => 'EmailAddress1', '_value' => '[email protected]')
                )
            )
        ));

I'm getting this error:

The EWS Id is in EwsLegacyId format which is not supported by the Exchange version specified by your request. Please use the ConvertId method to convert from EwsLegacyId to EwsId format.

How do I convert this? Also on a side note, how do you update a phone number? Thank you very much!

Reading Office365 Calendar events

I'm not sure what's wrong here, but the following code is throwing an exception SOAP client returned status of 403. Any help would be greatly appreciated. Before diving in, is there some sort of debug flag for the API to get some more details about the requests/responses going on behind the scenes?

The following code correctly directs me to Office365 to authorize my application with scope https://outlook.office.com/Calendars.ReadWrite and redirects me back with an authorization-code.

The autorization-code allows me to get a seemingly correct access-token with ExchangeWebServicesAuth::getTokenFromAuthorizationCode. So all is looking good up until that point.

However, when calling $api->getCalendar() the exception SOAP client returned status of 403 is thrown.

use jamesiarmes\PEWS\API;
use jamesiarmes\PEWS\API\ExchangeWebServicesAuth;

$app->get('/oauth', function() use ($app) {
    $redir = 'http://localhost:8080/oauth';

    if (!isset($_GET['code'])) {
        $oAuth = new oAuthService();
        header("Location: ".$oAuth->getLoginUrl($redir), 301);
        exit;
    }

    $token = ExchangeWebServicesAuth::getTokenFromAuthorizationCode(
        getenv('OFFICE365_CLIENT_ID'),
        getenv('OFFICE365_CLIENT_SECRET'),
        $_GET['code'],
        $redir
    );

    $api      = API::withCallbackToken('outlook.office.com', $token);
    $calendar = $api->getCalendar();
    $items    = $calendar->getCalendarItems('01-03-2016 00:00:00', '01-04-2016 00:00:00');

    var_dump($items);
});

As said, any help is greatly appreciated. This is probably not a true issue with the library, but some help in the right direction would be awesome.

calendar event 'body'

I can create calendar events for myself and others, but I'd like to put a message body/description in the event telling people what it's about. I've searched through the schema but don't see how to do this. I need to send about 5 lines of text.

Erick

Shared Calendar, get / create Items

Hi, i try to get and create items from a shared calender.

the Calendar(DisplayName = mako) is shared from a User to the API Connection user (All Rights)
my Code so far

public function getCalendar() {
        $this->connect();
        $calendar = $this->api->getCalendar();
        $folderId = $this->api->getFolderByDisplayName('MaKo', Enumeration\DistinguishedFolderIdNameType::ROOT);
        $folderId->getFolderId();
        $calendar->setFolderId($folderId);

        $start = new DateTime('8:00 AM');
        $end = new DateTime('8:00 PM');
        $items = $calendar->getCalendarItems($start, $end);

        return $items;

    }

i think the enumeration is wrong, i already tried PUBLICFOLDERSROOT and CALENDAR but i guess i have some logical issue here

thanks for your help

Examples working with Contact records

Hello,

Thanks for making all the changes to the library, in particular the simple function calls.

Would you be able to provide any examples of accessing/updating contact records?

ExchangeWebServices::Exchange2010_SP3 constant missing

Is the missing ExchangeWebServices::Exchange2010_SP3 constant intentional?

Using ExchangeAutodiscover with an Exchange 2010 SP3 server discovers correctly, but the call to garethp\ews\API\ExchangeAutodiscover->parseServerVersion('7383807B'), fails after interpreting (correctly) that the majorVersion = 14 and minorVersion = 3, because it's looking for the class constant ExchangeWebServices::class::VERSION_2010_SP3", which isn't defined as a constant in garethp\ews\API\ExchangeWebServices.

Error

exception 'ErrorException' with message 'constant(): Couldn't find constant garethp\ews\API\ExchangeWebServices::VERSION_2010_SP3' in /www/htdocs/vendor/garethp/php-ews/src/API/ExchangeAutodiscover.php:68

Stack trace:

#0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'constant(): Cou...', '/www/htdocs/v...', 68, Array)
#1 /www/htdocs/vendor/garethp/php-ews/src/API/ExchangeAutodiscover.php(68): constant('garethp\\ews\\API...')
#2 /www/htdocs/vendor/garethp/php-ews/src/API/ExchangeAutodiscover.php(117): garethp\ews\API\ExchangeAutodiscover->parseServerVersion('7383807B')
#3 /www/htdocs/vendor/garethp/php-ews/src/API/ExchangeAutodiscover.php(96): garethp\ews\API\ExchangeAutodiscover->getServerVersionFromResponse(Array)
#4 /www/htdocs/vendor/garethp/php-ews/src/API/ExchangeAutodiscover.php(149): garethp\ews\API\ExchangeAutodiscover->newAPI('test@excha...', 'REDACTED_PASSWORD

Autodiscover response

<?xml version="1.0" encoding="utf-8"?> <Autodiscover xmlns="http://schemas.microsoft.com/exchange/autodiscover/responseschema/2006"> <Response xmlns="http://schemas.microsoft.com/exchange/autodiscover/outlook/responseschema/2006a"> <User> <DisplayName>Tester Account 12</DisplayName> <LegacyDN>/o=Domain Exchange/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Recipients/cn=Test Account 12779</LegacyDN> <AutoDiscoverSMTPAddress>[email protected]</AutoDiscoverSMTPAddress> <DeploymentId>aad7b86e-fda6-49b3-a843-66945100def5</DeploymentId> </User> <Account> <AccountType>email</AccountType> <Action>settings</Action> <Protocol> <Type>EXCH</Type> <Server>VM546658.exchange.domain.com</Server> <ServerDN>/o=Domain Exchange/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Configuration/cn=Servers/cn=VM546658</ServerDN> <ServerVersion>7383807B</ServerVersion> <MdbDN>/o=Contoso Exchange/ou=Exchange Administrative Group (FYDIBOHF23SPDLT)/cn=Configuration/cn=Servers/cn=VM546658/cn=Microsoft Private MDB</MdbDN> <AD>VM546658.exchange.domain.com</AD> <ASUrl>https://VM546658.exchange.domain.com/EWS/Exchange.asmx</ASUrl> <EwsUrl>https://VM546658.exchange.domain.com/EWS/Exchange.asmx</EwsUrl> <EcpUrl>https://VM546658.exchange.domain.com/ecp/</EcpUrl> <EcpUrl-um>?p=customize/voicemail.aspx&amp;exsvurl=1</EcpUrl-um> <EcpUrl-aggr>?p=personalsettings/EmailSubscriptions.slab&amp;exsvurl=1</EcpUrl-aggr> <EcpUrl-mt>PersonalSettings/DeliveryReport.aspx?exsvurl=1&amp;IsOWA=&lt;IsOWA&gt;&amp;MsgID=&lt;MsgID&gt;&amp;Mbx=&lt;Mbx&gt;</EcpUrl-mt> <EcpUrl-ret>?p=organize/retentionpolicytags.slab&amp;exsvurl=1</EcpUrl-ret> <EcpUrl-sms>?p=sms/textmessaging.slab&amp;exsvurl=1</EcpUrl-sms> <OOFUrl>https://VM546658.exchange.domain.com/EWS/Exchange.asmx</OOFUrl> <UMUrl>https://VM546658.exchange.domain.com/EWS/UM2007Legacy.asmx</UMUrl> </Protocol> <Protocol> <Type>EXPR</Type> <Server>exchange.domain.com</Server> <SSL>On</SSL> <AuthPackage>Basic</AuthPackage> <ASUrl>https://exchange.domain.com/ews/exchange.asmx</ASUrl> <EwsUrl>https://exchange.domain.com/ews/exchange.asmx</EwsUrl> <EcpUrl>https://exchange.domain.com/ecp/</EcpUrl> <EcpUrl-um>?p=customize/voicemail.aspx&amp;exsvurl=1</EcpUrl-um> <EcpUrl-aggr>?p=personalsettings/EmailSubscriptions.slab&amp;exsvurl=1</EcpUrl-aggr> <EcpUrl-mt>PersonalSettings/DeliveryReport.aspx?exsvurl=1&amp;IsOWA=&lt;IsOWA&gt;&amp;MsgID=&lt;MsgID&gt;&amp;Mbx=&lt;Mbx&gt;</EcpUrl-mt> <EcpUrl-ret>?p=organize/retentionpolicytags.slab&amp;exsvurl=1</EcpUrl-ret> <EcpUrl-sms>?p=sms/textmessaging.slab&amp;exsvurl=1</EcpUrl-sms> <OOFUrl>https://exchange.domain.com/ews/exchange.asmx</OOFUrl> <UMUrl>https://exchange.domain.com/ews/UM2007Legacy.asmx</UMUrl> <OABUrl>https://skype.exchange.domain.com/OAB/f698d4d6-2cc7-4d69-a38e-c7c8fd7dacf4/</OABUrl> </Protocol> <Protocol> <Type>WEB</Type> <Internal> <OWAUrl AuthenticationMethod="Basic, Fba">https://VM546658.exchange.domain.com/owa/</OWAUrl> <Protocol> <Type>EXCH</Type> <ASUrl>https://VM546658.exchange.domain.com/EWS/Exchange.asmx</ASUrl> </Protocol> </Internal> </Protocol> </Account> </Response> </Autodiscover>

DTD are not supported by SOAP

Hi Devs,

I'ts really great library and too easy to play with it. I have configured my 365 account couple of days ago, and it was working fine to create events, But I'm facing error from yesterday.

Fatal error: Uncaught SoapFault exception: [Client] DTD are not supported by SOAP in /opt/lampp/htdocs/PPH/ics/src/API/NTLMSoapClient.php:128 Stack trace: #0 /opt/lampp/htdocs/PPH/ics/src/API/NTLMSoapClient.php(128): SoapClient->__call('GetFolder', Array) #1 /opt/lampp/htdocs/PPH/ics/src/API/ExchangeWebServices.php(220): garethp\ews\API\NTLMSoapClient->__call('GetFolder', Array) #2 /opt/lampp/htdocs/PPH/ics/src/API.php(434): garethp\ews\API\ExchangeWebServices->__call('GetFolder', Array) #3 /opt/lampp/htdocs/PPH/ics/src/API.php(434): garethp\ews\API\ExchangeWebServices->GetFolder(Object(garethp\ews\API\Type)) #4 /opt/lampp/htdocs/PPH/ics/src/API.php(451): garethp\ews\API->getFolder(Array) #5 /opt/lampp/htdocs/PPH/ics/src/Calendar/CalendarAPI.php(33): garethp\ews\API->getFolderByDistinguishedId('calendar') #6 /opt/lampp/htdocs/PPH/ics/src/API.php(148): garethp\ews\Calendar\CalendarAPI->pickCalendar(NULL) #7 /opt/lampp/htdocs/PPH/ics/index.php(20): garethp\ews\API->getCalendar() #8 {main} thrown in /opt/lampp/htdocs/PPH/ics/src/API/NTLMSoapClient.php on line 128

I have googled and found that here is end point problem. But i don't have clue :(

When i see at line no 128 in NTLMSoapClient.php

// If a version was set then add it to the headers. if (!empty($options['version'])) { $this->ewsHeaders['version'] = new SoapHeader( 'http://schemas.microsoft.com/exchange/services/2006/types', 'RequestServerVersion Version="' . $options['version'] . '"' ); }
When we access schema link : http://schemas.microsoft.com/exchange/services/2006/types'

then its shows

The resource you are looking for has been removed, had its name changed, or is temporarily unavailable.

Is this a problem? I'll be thankful for your guidance or help.
Again Thanks for great library.

api->getItem runs into Soap error

I get a list of E-Mails out of a public Folder

$mail = $api->getMailItems($subFolder2->getFolderId());
foreach($mail->items as $message) {
    $mailItem = $api->getItem($message->getItemId());

the Code ( $api->getItem ) Triggers on some Mails the following error:

PHP Fatal error: Uncaught SoapFault exception: [Client] looks like we got no XML document in /var/www/html/php-ews/src/API/NTLMSoapClient.php:127\nStack trace:\n#0 /var/www/html/php-ews/src/API/NTLMSoapClient.php(127): SoapClient->__call('GetItem', Array)\n#1 /var/www/html/php-ews/src/API/ExchangeWebServices.php(294): garethp\ews\API\NTLMSoapClient->__call('GetItem', Array)\n#2 /var/www/html/php-ews/src/API.php(395): garethp\ews\API\ExchangeWebServices->__call('GetItem', Array)\n#3 /var/www/html/php-ews/src/API.php(395): garethp\ews\API\ExchangeWebServices->GetItem(Array)\n#4 /var/www/html/php-ews/index.php(40): garethp\ews\API->getItem(Object(garethp\ews\API\Type\ItemIdType))\n#5 {main}\n thrown in /var/www/html/php-ews/src/API/NTLMSoapClient.php on line 127

I have an Mail->item object where the error gets triggered but
ItemID is accessable and it looks the same as on working E-Mails.

I'm new to this API (And EWS) so i don't know which information you need to help me.

Thanks for your help.

All examples render an error "The specified server version is invalid"

After some struggle and online research I managed to get the autoloading correct by using Composer, so no more "Class not found" errors.

After this first success, I wanted to try some of the examples (examples/basic/quickstart.php seemed like a good starting point), so I add this at the top to make the autoloading happen:

require_once "../../vendor/autoload.php";

after which my browser takes quite a long time to reload the page (so I guess something is happening in communicating to the Exchange server?) only to give me a 500 Error.

/var/log/apache2/error.log tells me that SOAP thinks "The specified server version is invalid":

PHP Fatal error:  Uncaught SoapFault exception: [soap:Client] The specified server version is invalid. in /var/www/html/php-ews-master/src/API/NTLMSoapClient.php:127
Stack trace:

#0 /var/www/html/php-ews-master/src/API/NTLMSoapClient.php(127): SoapClient->__call('GetFolder', Array)

#1 /var/www/html/php-ews-master/src/API/ExchangeWebServices.php(294): garethp\\ews\\API\\NTLMSoapClient->__call('GetFolder', Array)

#2 /var/www/html/php-ews-master/src/API.php(295): garethp\\ews\\API\\ExchangeWebServices->__call('GetFolder', Array)

#3 /var/www/html/php-ews-master/src/API.php(295): garethp\\ews\\API\\ExchangeWebServices->GetFolder(Object(garethp\\ews\\API\\Type))

#4 /var/www/html/php-ews-master/src/API.php(313): garethp\\ews\\API->getFolder(Array)

#5 /var/www/html/php-ews-master/examples/basic/quickstart.php(20): garethp\\ews\\API->getFolderByDistinguishedId('calendar')

#6 {main}


thrown in /var/www/html/php-ews-master/src/API/NTLMSoapClient.php on line 127

I altered the call to API::withUsernameAndPassword() with my domain credentials of course.

When I google "The specified server version is invalid" I get quite a few results that all have to do with Windows development (.NET, C#, VBA, PowerShell) failing to connect to an Exchange environment.

The documentation states under "Usage" that the server version "Defaults to Exchange 2007".

However if I do this:

require_once "../../vendor/autoload.php";

/**
 * Quick Start
 *
 * This file is an example of how to quickly create a Calendar Item without going through the CalendarAPI, to show
 * that you can create items directly
 */

//Include the API
use garethp\ews\API;
use garethp\ews\API\Enumeration;

//Create and build the client
$api = API::withUsernameAndPassword('EXCHANGESERVER', 'DOMAIN\\MYUSERNAME', 'PASSWORDIMNOTTELLINGYOU');
print_r($api);
die();

I get a mapping of an object of type "garethp\ews\API". In that text dump, when I do a find on the string "version", I find the following 2 properties set to "Exchange2010":

[ewsHeaders:protected] => Array
                        (
                            [version] => SoapHeader Object
                                (
                                    [namespace] => http://schemas.microsoft.com/exchange/services/2006/types
                                    [name] => RequestServerVersion Version="Exchange2010"
                                    [mustUnderstand] => 
                                )

                            [impersonation] => 
                            [timezone] => 
                        )

...

            [username:protected] => 
            [primarySmtpMailbox:protected] => 
            [drillDownResponses:protected] => 1
            [version:protected] => Exchange2010
            [options:protected] => 
            [timezone:protected] => 

I added a 4th parameter to API::withUsernameAndPassword() to look like this:

$api = API::withUsernameAndPassword('EXCHANGESERVER', 'DOMAIN\MYUSERNAME', 'PASSWORDIMNOTTELLINGYOU', Array("version" => 'Exchange2007_SP3' ));

Which corrects the information in the garethp\ews\API object, but when I let the script load entirely, I still get

PHP Fatal error: Uncaught SoapFault exception: [soap:Client] The specified server version is invalid. in /var/www/html/php-ews-master/src/API/NTLMSoapClient.php:127

At this point I'm kinda stuck, because I cannot get any of the examples to work. I double-checked my version number on the exchange server, which is 08.03.0379.002 ( = RU14 for Exchange 2007 SP3 accoording to Microsoft TechNet ) , So I'm pretty sure that I DO have the valid server version, opposite to what the SoapClient->__call() method in NTLMSoapClient.php tells me.

Any suggestions are more than welcome.

Best regards,
JB

SOAP Error: violation of encoding rules

Hello

I've been able to set up a sync with ews without any problem but only when I browse to it.
If I set the script up via cron I get the error below.
This happens with list changes / get item ... for now
I don't know if this is my fault, it probably is, but I can't find anything about how to solve it when I search for it. (not for php-ews anyway)

List changes:

SoapFault exception: [Client] SOAP-ERROR: Encoding: Violation of encoding rules in vendor/garethp/php-ews/src/API/NTLMSoapClient.php:122
Stack trace:

0 vendor/garethp/php-ews/src/API/NTLMSoapClient.php(122): SoapClient->__call('SyncFolderItems', Array)

1 vendor/garethp/php-ews/src/API/ExchangeWebServices/MiddlewareFactory.php(18): garethp\ews\API\NTLMSoapClient->__call('SyncFolderItems', Array)

2 vendor/garethp/php-ews/src/API/ExchangeWebServices.php(498): garethp\ews\API\ExchangeWebServices->garethp\ews\API\ExchangeWebServices{closure}(Object(garethp\ews\API\MiddlewareRequest), Object(Closure))

3 vendor/garethp/php-ews/src/API/ExchangeWebServices/MiddlewareFactory.php(32): garethp\ews\API\ExchangeWebServices->garethp\ews\API{closure}(Object(garethp\ews\API\MiddlewareRequest))

4 vendor/garethp/php-ews/src/API/ExchangeWebServices.php(498): garethp\ews\API\ExchangeWebServices->garethp\ews\API\ExchangeWebServices{closure}(Object(garethp\ews\API\MiddlewareRequest), Object(Closure))

5 vendor/garethp/php-ews/src/API/ExchangeWebServices/MiddlewareFactory.php(48): garethp\ews\API\ExchangeWebServices->garethp\ews\API{closure}(Object(garethp\ews\API\MiddlewareRequest))

6 vendor/garethp/php-ews/src/API/ExchangeWebServices.php(498): garethp\ews\API\ExchangeWebServices->garethp\ews\API\ExchangeWebServices{closure}(Object(garethp\ews\API\MiddlewareRequest), Object(Closure))

7 vendor/garethp/php-ews/src/API/ExchangeWebServices/MiddlewareFactory.php(55): garethp\ews\API\ExchangeWebServices->garethp\ews\API{closure}(Object(garethp\ews\API\MiddlewareRequest))

8 vendor/garethp/php-ews/src/API/ExchangeWebServices.php(498): garethp\ews\API\ExchangeWebServices->garethp\ews\API\ExchangeWebServices{closure}(Object(garethp\ews\API\MiddlewareRequest), Object(Closure))

9 vendor/garethp/php-ews/src/API/ExchangeWebServices/MiddlewareFactory.php(66): garethp\ews\API\ExchangeWebServices->garethp\ews\API{closure}(Object(garethp\ews\API\MiddlewareRequest))

10 vendor/garethp/php-ews/src/API/ExchangeWebServices.php(498): garethp\ews\API\ExchangeWebServices->garethp\ews\API\ExchangeWebServices{closure}(Object(garethp\ews\API\MiddlewareRequest), Object(Closure))

11 vendor/garethp/php-ews/src/API/ExchangeWebServices.php(508): garethp\ews\API\ExchangeWebServices->garethp\ews\API{closure}(Object(garethp\ews\API\MiddlewareRequest))

12 vendor/garethp/php-ews/src/API/ExchangeWebServices.php(298): garethp\ews\API\ExchangeWebServices->executeMiddlewareStack(Array, Object(garethp\ews\API\MiddlewareRequest))

13 vendor/garethp/php-ews/src/API.php(447): garethp\ews\API\ExchangeWebServices->__call('SyncFolderItems', Array)

14 vendor/garethp/php-ews/src/API.php(447): garethp\ews\API\ExchangeWebServices->SyncFolderItems(Object(garethp\ews\API\Type))

15 vendor/garethp/php-ews/src/CalendarAPI.php(220): garethp\ews\API->listItemChanges(Object(garethp\ews\API\Type\FolderIdType), 'H4sIAAAAAAAEAGN...', Array)

16 sync_ews_calendar.php(110): garethp\ews\CalendarAPI->listChanges('H4sIAAAAAAAEAGN...')

17 {main}

Get item:

SoapFault exception: [Client] SOAP-ERROR: Encoding: Violation of encoding rules in vendor/garethp/php-ews/src/API/NTLMSoapClient.php:122
Stack trace:

0 vendor/garethp/php-ews/src/API/NTLMSoapClient.php(122): SoapClient->__call('GetItem', Array)

1 vendor/garethp/php-ews/src/API/ExchangeWebServices/MiddlewareFactory.php(18): garethp\ews\API\NTLMSoapClient->__call('GetItem', Array)

2 vendor/garethp/php-ews/src/API/ExchangeWebServices.php(498): garethp\ews\API\ExchangeWebServices->garethp\ews\API\ExchangeWebServices{closure}(Object(garethp\ews\API\MiddlewareRequest), Object(Closure))

3 vendor/garethp/php-ews/src/API/ExchangeWebServices/MiddlewareFactory.php(32): garethp\ews\API\ExchangeWebServices->garethp\ews\API{closure}(Object(garethp\ews\API\MiddlewareRequest))

4 vendor/garethp/php-ews/src/API/ExchangeWebServices.php(498): garethp\ews\API\ExchangeWebServices->garethp\ews\API\ExchangeWebServices{closure}(Object(garethp\ews\API\MiddlewareRequest), Object(Closure))

5 vendor/garethp/php-ews/src/API/ExchangeWebServices/MiddlewareFactory.php(48): garethp\ews\API\ExchangeWebServices->garethp\ews\API{closure}(Object(garethp\ews\API\MiddlewareRequest))

6 vendor/garethp/php-ews/src/API/ExchangeWebServices.php(498): garethp\ews\API\ExchangeWebServices->garethp\ews\API\ExchangeWebServices{closure}(Object(garethp\ews\API\MiddlewareRequest), Object(Closure))

7 vendor/garethp/php-ews/src/API/ExchangeWebServices/MiddlewareFactory.php(55): garethp\ews\API\ExchangeWebServices->garethp\ews\API{closure}(Object(garethp\ews\API\MiddlewareRequest))

8 vendor/garethp/php-ews/src/API/ExchangeWebServices.php(498): garethp\ews\API\ExchangeWebServices->garethp\ews\API\ExchangeWebServices{closure}(Object(garethp\ews\API\MiddlewareRequest), Object(Closure))

9 vendor/garethp/php-ews/src/API/ExchangeWebServices/MiddlewareFactory.php(66): garethp\ews\API\ExchangeWebServices->garethp\ews\API{closure}(Object(garethp\ews\API\MiddlewareRequest))

10 vendor/garethp/php-ews/src/API/ExchangeWebServices.php(498): garethp\ews\API\ExchangeWebServices->garethp\ews\API\ExchangeWebServices{closure}(Object(garethp\ews\API\MiddlewareRequest), Object(Closure))

11 vendor/garethp/php-ews/src/API/ExchangeWebServices.php(508): garethp\ews\API\ExchangeWebServices->garethp\ews\API{closure}(Object(garethp\ews\API\MiddlewareRequest))

12 vendor/garethp/php-ews/src/API/ExchangeWebServices.php(298): garethp\ews\API\ExchangeWebServices->executeMiddlewareStack(Array, Object(garethp\ews\API\MiddlewareRequest))

13 vendor/garethp/php-ews/src/API.php(419): garethp\ews\API\ExchangeWebServices->__call('GetItem', Array)

14 vendor/garethp/php-ews/src/API.php(419): garethp\ews\API\ExchangeWebServices->GetItem(Array)

15 vendor/garethp/php-ews/src/CalendarAPI.php(150): garethp\ews\API->getItem(Array)

16 sync_ews_calendar.php(203): garethp\ews\CalendarAPI->getCalendarItem('AQMkADI5NTFiYTE...', 'DwAAABYAAACHxmQ...')

17 {main}

Create an all-day event, Eastern Standard Time?

I am trying to create an all-day event in my timezone. I am not sure how to pass timezone data.

date_default_timezone_set('America/New_York');
$start = new DateTime('06/23/2016');
$end = new DateTime('06/23/2016');

$createdItemIds = $calendar->createCalendarItems(array(
    'Subject' => 'allday',
    'Start' => $start->format('c'),
    'End' => $end->format('c'),
    'isAllDayEvent' => true,
    //'timeZone' => 'EST',
    'legacyFreeBusyStatus' => 'Free',
    'Body' => array ('BodyType' => 'HTML', '_value' => 'This is just a test event!'),
    'RequiredAttendees' => array(
        array(
            'Mailbox' => array(
                'Name' => 'Test',
                'EmailAddress' => '[email protected]',
            )
        ),
        array (
            'Mailbox' => array(
                'Name' => 'Test',
                'EmailAddress' => '[email protected]'
            )
        )
    )
), array('SendMeetingInvitations' => 'SendOnlyToAll'));
echo "Created Event";

This is not working, it will create an event with 1day offset.

Working period / Get user availablity request

I am trying to get working period (days) for a specific account. The only method I found which returns it is GetUserAvailability. I tried to building a request from an array for that. However error message says:
'Property ResponseMessages does not exist' (Line 64 in MagicMethodsTrait.php). Printing out the response before the exception gets thrown showed that xml response is correct.
As I was looking for a solution I found here that the xml response for GetUerAvailability method does not contain "ResponseMessages" (other xml responses do).

Any suggestions to fix this?

Here is how I built the request from an array:

$request = new GetUserAvailabilityRequestType();

$request = array(
    "TimeZone" => array(
        "Bias" => '480',
        "StandardTime" => array(
            "Bias" => 0,
            "Time" => '02:00:00',
            "DayOrder" => 5,
            "Month" => 10,
            "DayOfWeek" => "Sunday"
        ),
        "DaylightTime" => array(
            "Bias" => 0,
            "Time" => '02:00:00',
            "DayOrder" => 1,
            "Month" => 4,
            "DayOfWeek" => "Sunday"
        )
    ),
    "MailboxDataArray" => array(
        "MailboxData" => array(
            "Email"=> array(
                "Address" => $requestor_email
            ),
            "AttendeeType" => 'Required',
            "ExcludeConflicts" => false
        )
    ),
    "FreeBusyViewOptions" => array(
        "TimeWindow" => array(
            "StartTime" => $start,
            "EndTime" => $end
        ),
        "MergedFreBusyIntervalInMinutes" => 30,
        "RequestedView" => 'DetailedMerged'
    )
);

$request = Type::buildFromArray($request);
$response = $api->getClient()->GetUserAvailability($request);

var_dump($response);

Updating contacts physical address

Hi,

how can i update the address of a contact? Because it consists of multiple properties and soap only allows to update one i am not sure how to continue.

This does not work:

array('PhysicalAddress:Home' => array(
 'PhysicalAddresses' => array(
 'Entry' => array(
    'Key' => 'Home',
    'street' => '123 Street', 
    'city' => '123 City',
))));

Get the ID of a calendar's item

Hi !
I though it could be better to open a new issue, I'm trying to get an item ID but the function getItem() doesn't return the ID, but an object containing an ID and a changekey...
What is the changekey ? And how can I have the real ID please ?

DeleteItemField Support

Hi,

it would be great to be able to delete items. As there is no API with the current implementation is it possible to add the field 'DeleteItemField' manually? I want to delete email addresses so it is not enough to just fill in the 'DeleteItemField' as linked properties also have to be deleted. Any ideas how to approach an implementation?

Retrieving attachments from forwarded message with embedded attachment

When an e-mail with an attached (e.g. Excel file), is attached to a new e-mail (e.g. dragged into a new message), unable to extract the elements from the attached message.

I am using this code from examples page with 1 line modified (var dump). The error log and dump are included. The mailbox in question only has 1 e-mail in it.

php code:
$username = 'user@company';
$password = '************';
$server = 'internalEXServer.company.com';

require_once "vendor/autoload.php";
use jamesiarmes\PEWS\API\Type;
use jamesiarmes\PEWS\Mail\MailAPI;
$api = MailAPI::withUsernameAndPassword($server, $username, $password);

$mail = $api->getMailItems();
var_dump($mail);

$mailItem = $mail[1];
//When the item is first returned from getMailItems(), it doesn't have attachment information filled out. You need to
//get that mail item again directly
$mailItem = $api->getItem($mailItem->getItemId());
//getFileAttachment() always returns an array of file attachments, or null
$fileAttachment = $mailItem->getAttachments()->getFileAttachment()[0];
//Without this the content of the attachment is not returned, so we need to do another fetch to make sure we get the
//content
$attachment = $api->getAttachment($fileAttachment->getAttachmentId());
$name = $attachment->getName();
$contentType = $attachment->getContentType();
$content = $attachment->getContent();

var_dump($content);

php_errorr log:
[20-Nov-2015 10:52:22 America/Chicago] PHP Notice: Undefined offset: 1 in /var/www/html/php-ews2/check_phish.php on line 19
[20-Nov-2015 10:52:22 America/Chicago] PHP Fatal error: Call to a member function getItemId() on a non-object in /var/www/html/php-ews2/check_phish.php on line 22
[20-Nov-2015 10:52:42 America/Chicago] PHP Notice: Undefined offset: 1 in /var/www/html/php-ews2/check_phish.php on line 19
[20-Nov-2015 10:52:42 America/Chicago] PHP Fatal error: Call to a member function getItemId() on a non-object in /var/www/html/php-ews2/check_phish.php on line 22

var_dump output:
array(1) {
[0]=>
object(jamesiarmes\PEWS\API\Type\MessageType)#37 (57) {
["sender":protected]=>
object(jamesiarmes\PEWS\API\Type\SingleRecipientType)#44 (3) {
["mailbox":protected]=>
object(jamesiarmes\PEWS\API\Type\EmailAddressType)#38 (7) {
["name":protected]=>
string(14) "Lastname, Firstname"
["emailAddress":protected]=>
string(85) "/O=companyname/OU=EXCHANGE ADMINISTRATIVE GROUP (FYDIBOHF23SPDLT)/CN=RECIPIENTS/CN=FLASTNAME"
["routingType":protected]=>
string(2) "EX"
["mailboxType":protected]=>
string(6) "OneOff"
["itemId":protected]=>
NULL
["_"]=>
string(0) ""
["typeMap":protected]=>
array(0) {
}
}
["
"]=>
string(0) ""
["typeMap":protected]=>
array(0) {
}
}
["toRecipients":protected]=>
NULL
["ccRecipients":protected]=>
NULL
["bccRecipients":protected]=>
NULL
["isReadReceiptRequested":protected]=>
bool(false)
["isDeliveryReceiptRequested":protected]=>
bool(false)
["conversationIndex":protected]=>
string(22) "�Ñ#®èK;>ëd��D�®‚š�=�u{"
["conversationTopic":protected]=>
string(72) "Subject_of_original_email"
["from":protected]=>
object(jamesiarmes\PEWS\API\Type\SingleRecipientType)#16 (3) {
["mailbox":protected]=>
object(jamesiarmes\PEWS\API\Type\EmailAddressType)#15 (7) {
["name":protected]=>
string(14) "Lastname, Firstname"
["emailAddress":protected]=>
string(85) "/O=companyname/OU=EXCHANGE ADMINISTRATIVE GROUP (FYDIBOHF23SPDLT)/CN=RECIPIENTS/CN=FLASTNAME"
["routingType":protected]=>
string(2) "EX"
["mailboxType":protected]=>
string(6) "OneOff"
["itemId":protected]=>
NULL
["
"]=>
string(0) ""
["typeMap":protected]=>
array(0) {
}
}
["
"]=>
string(0) ""
["typeMap":protected]=>
array(0) {
}
}
["internetMessageId":protected]=>
string(60) "[email protected]"
["isRead":protected]=>
bool(true)
["isResponseRequested":protected]=>
NULL
["references":protected]=>
NULL
["replyTo":protected]=>
NULL
["receivedBy":protected]=>
object(jamesiarmes\PEWS\API\Type\SingleRecipientType)#49 (3) {
["mailbox":protected]=>
object(jamesiarmes\PEWS\API\Type\EmailAddressType)#48 (7) {
["name":protected]=>
string(19) "Destination User"
["emailAddress":protected]=>
NULL
["routingType":protected]=>
string(2) "EX"
["mailboxType":protected]=>
string(6) "OneOff"
["itemId":protected]=>
NULL
["
"]=>
string(0) ""
["typeMap":protected]=>
array(0) {
}
}
["
"]=>
string(0) ""
["typeMap":protected]=>
array(0) {
}
}
["receivedRepresenting":protected]=>
object(jamesiarmes\PEWS\API\Type\SingleRecipientType)#51 (3) {
["mailbox":protected]=>
object(jamesiarmes\PEWS\API\Type\EmailAddressType)#52 (7) {
["name":protected]=>
string(19) "Destination User"
["emailAddress":protected]=>
string(85) "/O=companyname/OU=EXCHANGE ADMINISTRATIVE GROUP (FYDIBOHF23SPDLT)/CN=RECIPIENTS/CN=DUSER444"
["routingType":protected]=>
string(2) "EX"
["mailboxType":protected]=>
string(6) "OneOff"
["itemId":protected]=>
NULL
["
"]=>
string(0) ""
["typeMap":protected]=>
array(0) {
}
}
["
"]=>
string(0) ""
["typeMap":protected]=>
array(0) {
}
}
["mimeContent":protected]=>
NULL
["itemId":protected]=>
object(jamesiarmes\PEWS\API\Type\ItemIdType)#43 (4) {
["id":protected]=>
string(152) "AAMkADNmMTFkZWMzLWZmZTItNGYzZC1hMzY0LTM1ZmVlOTgyMGY3NABGAAAAAABp+AqPUrsDS5mJYBbgT8cMBwDr14N485PESKioLJfn3CaYAAAARQJbAACApJo0H5XLTphU22eP91LkAAApg+2/AAA="
["changeKey":protected]=>
string(40) "CQAAABYAAACApJo0H5XLTphU22eP91LkAAApg9VV"
["
"]=>
string(0) ""
["typeMap":protected]=>
array(0) {
}
}
["parentFolderId":protected]=>
object(jamesiarmes\PEWS\API\Type\FolderIdType)#31 (4) {
["id":protected]=>
string(120) "AAMkADNmMTFkZWMzLWZmZTItNGYzZC1hMzY0LTM1ZmVlOTgyMGY3NAAuAAAAAABp+AqPUrsDS5mJYBbgT8cMAQDr14N485PESKioLJfn3CaYAAAARQJbAAA="
["changeKey":protected]=>
string(8) "AQAAAA=="
["
"]=>
string(0) ""
["_typeMap":protected]=>
array(0) {
}
}
["itemClass":protected]=>
string(8) "IPM.Note"
["subject":protected]=>
string(72) "Subject_of_original_email"
["sensitivity":protected]=>
string(6) "Normal"
["body":protected]=>
NULL
["attachments":protected]=>
NULL
["dateTimeReceived":protected]=>
string(20) "2015-11-20T16:17:13Z"
["typeMap":protected]=>
array(5) {
["dateTimeReceived"]=>
string(8) "dateTime"
["dateTimeSent"]=>
string(8) "dateTime"
["dateTimeCreated"]=>
string(8) "dateTime"
["reminderDueBy"]=>
string(8) "dateTime"
["lastModifiedTime"]=>
string(8) "dateTime"
}
["size":protected]=>
int(41006)
["categories":protected]=>
NULL
["importance":protected]=>
string(6) "Normal"
["inReplyTo":protected]=>
NULL
["isSubmitted":protected]=>
bool(false)
["isDraft":protected]=>
bool(false)
["isFromMe":protected]=>
bool(false)
["isResend":protected]=>
bool(false)
["isUnmodified":protected]=>
bool(true)
["internetMessageHeaders":protected]=>
NULL
["dateTimeSent":protected]=>
string(20) "2015-11-20T16:17:12Z"
["dateTimeCreated":protected]=>
string(20) "2015-11-20T16:17:13Z"
["responseObjects":protected]=>
NULL
["reminderDueBy":protected]=>
NULL
["reminderIsSet":protected]=>
bool(false)
["reminderMinutesBeforeStart":protected]=>
string(1) "0"
["displayCc":protected]=>
string(0) ""
["displayTo":protected]=>
string(19) "Destination User"
["hasAttachments":protected]=>
bool(true)
["extendedProperty":protected]=>
NULL
["culture":protected]=>
string(5) "en-US"
["effectiveRights":protected]=>
object(jamesiarmes\PEWS\API\Type\EffectiveRightsType)#41 (9) {
["createAssociated":protected]=>
bool(false)
["createContents":protected]=>
bool(false)
["createHierarchy":protected]=>
bool(false)
["delete":protected]=>
bool(true)
["modify":protected]=>
bool(true)
["read":protected]=>
bool(true)
["viewPrivateItems":protected]=>
NULL
["
"]=>
string(0) ""
["typeMap":protected]=>
array(0) {
}
}
["lastModifiedName":protected]=>
string(14) "Lastname, Firstname"
["lastModifiedTime":protected]=>
string(20) "2015-11-20T16:17:13Z"
["isAssociated":protected]=>
bool(false)
["webClientReadFormQueryString":protected]=>
string(204) "?ItemID=AAMkADNmMTFkZWMzLWZmZTItNGYzZC1hMzY0LTM1ZmVlOTgyMGY3NABGAAAAAABp%2BAqPUrsDS5mJYBbgT8cMBwDr14N485PESKioLJfn3CaYAAAARQJbAACApJo0H5XLTphU22eP91LkAAApg%2B2%2FAAA%3D&exvsurl=1&viewmodel=ReadMessageItem"
["webClientEditFormQueryString":protected]=>
NULL
["conversationId":protected]=>
object(jamesiarmes\PEWS\API\Type\ItemIdType)#12 (4) {
["id":protected]=>
string(80) "AAQkADNmMTFkZWMzLWZmZTItNGYzZC1hMzY0LTM1ZmVlOTgyMGY3NAAQADs+62QDGEQRroKaDz2ddXs="
["changeKey":protected]=>
NULL
["
"]=>
string(0) ""
["typeMap":protected]=>
array(0) {
}
}
["uniqueBody":protected]=>
NULL
["storeEntryId":protected]=>
NULL
["
"]=>
string(0) ""
}
}

Make a simple method for getting a users availability request

User Availability Request

Currently this is the best way to get availability. There's more information on the raw calls found here. It includes a lot of timezone data, something I've been trying to avoid due to the difference between EWS timezones and PHP timezones, as well as recurrences in the header. The implementation of headers at the moment could really use some beefing up. Looking at the NTLMSoapClient implementation, I remove a certain header temporarily for DeleteItem and SyncFolderItems requests by a hardcoded index in the default headers. This is because you can't pass timezone data for those calls for some reason. Frankly looking at it, it should break if you're using Timezones, Impersonation and Version headers all at the same time. So that needs fixing up. The actual response doesn't look too bad, but finding a good way of crafting the request will be interesting...

$request = new GetUserAvailabilityRequestType();

$request = array(
    "TimeZone" => array(
        "Bias" => '480',
        "StandardTime" => array(
            "Bias" => 0,
            "Time" => '02:00:00',
            "DayOrder" => 5,
            "Month" => 10,
            "DayOfWeek" => "Sunday"
        ),
        "DaylightTime" => array(
            "Bias" => 0,
            "Time" => '02:00:00',
            "DayOrder" => 1,
            "Month" => 4,
            "DayOfWeek" => "Sunday"
        )
    ),
    "MailboxDataArray" => array(
        "MailboxData" => array(
            "Email"=> array(
                "Address" => $requestor_email
            ),
            "AttendeeType" => 'Required',
            "ExcludeConflicts" => false
        )
    ),
    "FreeBusyViewOptions" => array(
        "TimeWindow" => array(
            "StartTime" => $start,
            "EndTime" => $end
        ),
        "MergedFreBusyIntervalInMinutes" => 30,
        "RequestedView" => 'DetailedMerged'
    )
);

$request = Type::buildFromArray($request);
$response = $api->getClient()->GetUserAvailability($request);

var_dump($response);

Getting List of Changes of calender items

Hi,
I tried to get changed calender items using the code in the example in "getListOfChanges.php".
The response I got for the SyncFolderItems request was right at first and the SyncState Attribute was changed. However, when I tried to get further changes from the calender using the changed SyncState, I got the exact same response containing the same changes again.
Do you know of anything I need to do between to calls SyncFolderItems to not get the same changes again? Or is my understanding of syncing items with the server wrong?

(I tried syncing twice in a row with EWS Editor and it worked as I expected it, I got no changes anymore on second call.)

get contact

I acces my contact number 2 on my exchange.
I can get these data: name, surname, jobtitle, company, ...
I can't get thes data: mails,phone number and address.

here my code:

<?php
require_once 'vendor/autoload.php';
use garethp\ews\Contacts\ContactsAPI as API;
use \garethp\ews\API\Enumeration;

$api = API::withUsernameAndPassword('*****', '****', '****');
$contacts = $api->getContacts();

echo($contacts[2]->getItemId()->getId())."<br>";
echo($contacts[2]->getGivenName())."<br>";
echo($contacts[2]->getSurname())."<br>";
echo($contacts[2]->getjobTitle())."<br>";
echo($contacts[2]->getCompanyName())."<br>";
echo($contacts[2]->getLastModifiedTime())."<br>";
print_r($contacts[2]->getPhoneNumbers());
echo"<br><br>";
print_r($contacts[2]->getEmailAddresses());
echo"<br><br>";             
print_r($contacts[2]->getPhysicalAddresses());
?>

here the result:

AQMkADE4YTg2ODEyLThjZDYtNDliMi1hM2Y2LTk3NThmN2NmZGM5MABGAAAD9G1ZxG9VTU0AvTBInvWTfMMHALWulK21A0FFsvNfOaLbENAAAAIBDgAAALWulK21A0FFsvNfOaLbENAAAAIVRAAAAA==
prenomtest
nomtest
fonctiontest
societetest
2016-07-08T07:35:26Z
stdClass Object ( [Entry] => Array ( [0] => garethp\ews\API\Type\PhoneNumberDictionaryEntryType Object ( [key:protected] => BusinessFax [_] => faxtest [_value] => [_typeMap:protected] => Array ( ) ) [1] => garethp\ews\API\Type\PhoneNumberDictionaryEntryType Object ( [key:protected] => BusinessPhone [_] => teltest [_value] => [_typeMap:protected] => Array ( ) ) [2] => garethp\ews\API\Type\PhoneNumberDictionaryEntryType Object ( [key:protected] => MobilePhone [_] => porttest [_value] => [_typeMap:protected] => Array ( ) ) ) ) 

stdClass Object ( [Entry] => garethp\ews\API\Type\EmailAddressDictionaryEntryType Object ( [key:protected] => EmailAddress1 [name:protected] => [routingType:protected] => [mailboxType:protected] => [_] => [email protected] [_value] => [_typeMap:protected] => Array ( ) ) ) 

stdClass Object ( [Entry] => garethp\ews\API\Type\PhysicalAddressDictionaryEntryType Object ( [key:protected] => Business [street:protected] => ruetest [city:protected] => villetest [state:protected] => deptest [countryOrRegion:protected] => paystest [postalCode:protected] => cptest [_] => [_value] => [_typeMap:protected] => Array ( ) ) )

NTLMSoapClient Crashing

Since version 0.7.4 NTLMSoapClient ->__call is crashing php. Probably malformed soap request? PHP => 5.6.3. I may investigate further when i have some time left.

Creating a contact (example request)

Can you create an example on how to create a contact? Currently I'm trying the following, but it is returning this error:
The request failed schema validation: The element 'Items' in namespace 'http://schemas.microsoft.com/exchange/services/2006/messages' has incomplete content. List of possible elements expected: 'Item, Message, CalendarItem, Contact, DistributionList, MeetingMessage, MeetingRequest, MeetingResponse, MeetingCancellation, Task, ReplyToItem, ForwardItem, ReplyAllToItem, AcceptItem, TentativelyAcceptItem, DeclineItem, CancelCalendarItem, RemoveItem, SuppressReadReceipt' in namespace 'http://schemas.microsoft.com/exchange/services/2006/types'.

Code:

    $ews = API::withUsernameAndPassword (
        $this->server_address,
        $this->server_username,
        $this->server_password,
        [
            'impersonation' => Auth::user()->employee->email,
            'version' => "Exchange2007"
        ]
    );

    $request = new EWSType_CreateItemType();

    $contact = new EWSType_ContactItemType();
    $contact->Initials = $this->relation->initials;
    $contact->GivenName = $this->relation->first_name;
    $contact->MiddleName = $this->relation->insertion;
    $contact->Surname = $this->relation->last_name;
    $contact->CompleteName = User::findRelationFullName($this->relation);

    $emails = [];

    // relation email address
    if (!empty($this->relation->email)) {
        // create an email address
        $email = new EWSType_EmailAddressDictionaryEntryType();
        $email->Key = new EWSType_EmailAddressKeyType();
        $email->Key->_ = EWSType_EmailAddressKeyType::EMAIL_ADDRESS_1;
        $email->_ = $this->relation->email;
        $emails[] = $email;
    }

    // organization email address
    if (!empty($this->relation->organization->email)) {
        // create an email address
        $email = new EWSType_EmailAddressDictionaryEntryType();
        $email->Key = new EWSType_EmailAddressKeyType();
        $email->Key->_ = EWSType_EmailAddressKeyType::EMAIL_ADDRESS_2;
        $email->_ = $this->relation->organization->email;
        $emails[] = $email;
    }

    if (!empty($emails)) {
        // set the email
        $contact->EmailAddresses = new EWSType_EmailAddressDictionaryType();
        $contact->EmailAddresses->Entry = $emails;
    }

    // create an address
    $address = new EWSType_PhysicalAddressDictionaryEntryType();
    $address->Key = new EWSType_PhysicalAddressKeyType();
    $address->Key->_ = EWSType_PhysicalAddressKeyType::HOME;
    $address->Street = $this->relation->organization->addresses->first()->street;
    $address->City = $this->relation->organization->addresses->first()->city;
    //$address->State = 'PA';
    $address->PostalCode = $this->relation->organization->addresses->first()->zipcode;
    $address->CountryOrRegion = $this->relation->organization->addresses->first()->country;

    // set the address
    $contact->PhysicalAddresses = new EWSType_PhysicalAddressDictionaryType();
    $contact->PhysicalAddresses->Entry[] = $address;

    if (!empty($this->relation->phone_number_direct)) {
        // create a phone number
        $phone = new EWSType_PhoneNumberDictionaryEntryType();
        $phone->Key = new EWSType_PhoneNumberKeyType();
        $phone->Key->_ = EWSType_PhoneNumberKeyType::HOME_PHONE;
        $phone->_ = $this->relation->phone_number_direct_code . $this->relation->phone_number_direct;

        // set the phone number
        $contact->PhoneNumbers = new EWSType_PhoneNumberDictionaryType();
        $contact->PhoneNumbers->Entry[] = $phone;
    }

    // set the "file as" mapping to "first name last name"
    $contact->FileAsMapping = new EWSType_FileAsMappingType();
    $contact->FileAsMapping->_ = EWSType_FileAsMappingType::FIRST_SPACE_LAST;

    $request->Items->Contact[] = $contact;

    if (!empty($this->relation->function)) {
        $contact->JobTitle = $this->relation->function;
    }

    $contact->CompanyName = $this->relation->organization->name;
    $result = $ews->createItems($contact);

Event Attendees not updated

Trying to update event
getting

Error: Uncaught SoapFault exception: [Client] SOAP-ERROR: Encoding: object has no 'Attendee' property in

Code:

$updateItems = $calendar->updateCalendarItem($itemId, array(
            'Subject' => 'Update Event',
            'Start' => (new \DateTime('8:00 PM'))->format('c'),
            'End' => (new \DateTime('8:30 PM'))->format('c'),
            'Location' => "Test",   
            'RequiredAttendees' => $RECIPIENTSTR_ARR    
));

Note: if we are updating Subject, start, End , Location. then it is updation properly .

but when trying to updated "Attendees" then its giving an error.

Please help me to fix this issue.
Thanks

Number of items into an object "Calendar"

Hi !
I'm looking for a function to get the number of items returned by $calendar->getCalendarItems()
in order to do something like
(for $i=0, $i < $numberOfItems , $i = $i +1)
If it already exist, I'm sorry but I didn't find it...
And if it's a basic of php, sorry again... I'm a beginner ^^'
Anyways, thanks for you work on php-ews ! :)

Public Calendar

Hi,

could you please provide an example for the "getListOfChanges" script using a public calendar (public folder)?

Updating contact notes

I am trying to update the contact notes using the following syntax

$api->updateContactItem($contact[0]->getItemId(), [
                        'GivenName' => $customer->first_name,
                        'Notes' => $customer->notes,
                ]);

and I receive the following error:

exception 'garethp\ews\API\Exception\ExchangeException' with message 'Property is not valid for this object type.' in /var/www/vendor/garethp/php-ews/src/API/ExchangeWebServices.php:426

Without passing Notes property everything works fine. Any ideas?

Forgot to mention that I am connecting to outlook.office365.com

"This site is unavailable" when getting contact list

Apologies for asking many questions, however, I'm trying to get a list of contacts:

    $ews = API::withUsernameAndPassword(
        $this->server_address,
       "my-username",
       "my-password"
    );

    // "dd" is short for "die() & var_dump()"
    try {
        dd($ews->getContacts());
    } catch (\Exception $e) {
        dd($e->getMessage());
    }

Everything within the try block does not get called. The page just fails to load and displays: "The website is unavailable, ERR_CONNECTION_RESET."

Why using namespace jamesiarmes\PEWS

This is not really an issue.. But I wonder, why using the namespace \jamesiarmes\PEWS\ instead of simply \PEWS\ or even \ews\ ?

I see in your 0.8 version that you intend to replace jamesiarmes part with garethp. Any practical reason for doing this ? Usually, developpers don't use multiple library that does the same thing.

I honestly think that using \ews\ | \EWS\ would be a better idea. The P in pews feels redundant because this is a php lib so we already know that this is php.

Much regards,

FileAttachments

Hi

uploadContactPhoto example is not working, because client does not have a method CreateAttachment(). I wanted to attach some files to an outgoing email. I guess it works the same as for contact photos?

Set categories color of a calander item

$request = array(
    'Items' => array(
        'CalendarItem' => array(
            'Start' => $start->format('c'),
            'End' => $end->format('c'),
            'Body' => array(
                'BodyType' => Enumeration\BodyTypeType::HTML,
                '_value' => 'This is <b>the</b> body'
            ),
            'ItemClass' => Enumeration\ItemClassType::APPOINTMENT,
            'Sensitivity' => Enumeration\SensitivityChoicesType::NORMAL,
            'Categories' => array('Testing', 'php-ews'),
            'Importance' => Enumeration\ImportanceChoicesType::NORMAL
        )
    ),
    'SendMeetingInvitations' => Enumeration\CalendarItemCreateOrDeleteOperationType::SEND_TO_NONE
);

Is it possible to set a color?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.