Coder Social home page Coder Social logo

php-ews's Issues

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

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

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}

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

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) ""
}
}

Public Calendar

Hi,

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

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 ( ) ) )

"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."

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',
))));

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.

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);

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.

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?

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?

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.

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?

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

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.

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?

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

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);

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 ?

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);

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

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;
}

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.

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.)

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!

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?

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 ! :)

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.

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?

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

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);

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.

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!

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,

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

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.

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

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

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>

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.