Garethp / php-ews

PHP Exchange Web Services
BSD 3-Clause "New" or "Revised" License
112 stars 45 forks source link

Updating event attendees... #74

Open c4ncel opened 8 years ago

c4ncel commented 8 years ago

This is similiar to issue #55

I can create a meeting with required attendees

    $requiredAttendees = array();
    foreach($users as $user) { 
        $requiredAttendees[] = array('Mailbox' => array('EmailAddress' => $user));
    }
    $request['RequiredAttendees'] = $requiredAttendees;
    $invites = 'SendToAllAndSaveCopy';

. . $createdItemIds = $calendar->createCalendarItems($request, array('SendMeetingInvitations' => $invites));

Invites go to attendees and and the event is added to their calendars.

But passing an array like this with an updated list of attendees (removing one) to updateCalendarItem fails with :

Uncaught SoapFault exception: [Client] SOAP-ERROR: Encoding: object has no 'Attendee' property in /srv/www/htdocs/exchange/vendor/garethp/php-ews/src/API/NTLMSoapClient.php:122

But if I change the array structure to this,

$requiredAttendees[] = array('Attendee' => array('Mailbox' => array('EmailAddress' => $email)));

the update call generates no error, but the (removed) attendees don't get an updated event email even if 'SendMeetingInvitationsOrCancellations' => 'SendOnlyToAll' and their copy of the event is out of sync.

This array structure, with 'Attendee' defined in the create call fails with :

Uncaught SoapFault exception: [Client] SOAP-ERROR: Encoding: object has no 'Mailbox' property in /srv/www/htdocs/exchange/vendor/garethp/php-ews/src/API/NTLMSoapClient.php:122

So there are 2 problems here really...

ghost commented 7 years ago

You are not handling a correct structure. Check the changes in the code below.

$attendees = array();
foreach($users as $user) { 
   $attendees [] = array('mailbox' => array('emailAddress' => $user));
}
$request['RequiredAttendees'] = $attendees ;
$invites = 'SendToAllAndSaveCopy';

regards

c4ncel commented 7 years ago

I was getting my definition from

https://msdn.microsoft.com/en-us/library/office/dd633661(v=exchg.80).aspx and

https://msdn.microsoft.com/en-us/library/office/dn495610(v=exchg.150).aspx#Anchor_3

           <t:RequiredAttendees>
              <t:Attendee>
                 <t:Mailbox>
                    <t:EmailAddress>user1@contoso.com</t:EmailAddress>
                 </t:Mailbox>
              </t:Attendee>
              <t:Attendee>
                 <t:Mailbox>
                    <t:EmailAddress>user2@contoso.com</t:EmailAddress>
                 </t:Mailbox>
              </t:Attendee>
           </t:RequiredAttendees>

specifically the XML (SOAP) which has Mailbox and EmailAddress. I think it should look like :

foreach($users as $user) { $attendees[] = array('Attendee' => array('Mailbox' => array('EmailAddress' => $user))); } $request['RequiredAttendees'] = $attendees; but that throws an error when using it to create a meeting and has no effect when using it to update a meeting.

ghost commented 7 years ago

change this $attendees[] = array('Attendee' => array('Mailbox' => array('EmailAddress' => $user))); for this $attendees [] = array('mailbox' => array('emailAddress' => $user));

ghost commented 7 years ago

Hope this help.

/** creating a meeting with attendees */

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

$calendar = $api->getCalendar();

$start = \DateTime::createFromFormat("Y-m-d H:i:s", "2017-02-03 14:00:00");
$end = \DateTime::createFromFormat("Y-m-d H:i:s", "2017-02-03 16:00:00");

$attendees[] = array("mailbox" => array( "emailAddress" => "email@domain.com"));
$attendees[] = array("mailbox" => array( "emailAddress" => "email2@domain.com"));

$event = array(
            'Subject' => "Joker Says",
            'Start' => $start->format('c'),
            'End' => $end->format('c'),
            'Body' => array(
                'BodyType' => Enumeration\BodyTypeType::HTML,
                '_value' => "<b>Joker says:</b>: Why so serious? ... let's put a smile on that face. Ha Ha Ha..."
            ),
            'ItemClass' => Enumeration\ItemClassType::APPOINTMENT,
            'Importance' => Enumeration\ImportanceChoicesType::NORMAL,
            'RequiredAttendees' => $attendees
        );

$options = array('SendMeetingInvitations' => Enumeration\CalendarItemCreateOrDeleteOperationType::SEND_TO_ALL_AND_SAVE_COPY);
$createdItemIds = $calendar->createCalendarItems($event,$options);
dump(createdItemIds);
die;

# ------------ updating a meeting with attendees -------- 

/**
* add or remove attendees from the $attendees array as convenience.
*/

$changes = array(
            'Subject' => "Joker Says Updated",
            'Start' => $start->format('c'),
            'End' => $end->format('c'),
            'Body' => array(
                'BodyType' => Enumeration\BodyTypeType::HTML,
                '_value' => "<b>Joker says:</b>: Why so serious? ... let's put a smile on that face. Ha Ha Ha..."
            ),
            'ItemClass' => Enumeration\ItemClassType::APPOINTMENT,
            'Importance' => Enumeration\ImportanceChoicesType::NORMAL,
            'RequiredAttendees' => ["Attendee" => $attendees]
        );

/**  $itemId :: you get this from $createdItemIds */

$request = array(
            'ItemChange' => array(
                'ItemId' => $itemId->toArray(),
                'Updates' => API\ItemUpdateBuilder::buildUpdateItemChanges('CalendarItem', 'calendar', $changes)
            )
        );

$options = array(
            'SendMeetingInvitationsOrCancellations' => Enumeration\CalendarItemUpdateOperationType::SEND_TO_ALL_AND_SAVE_COPY
        );

$items = $api->updateItems($request, $options)->getCalendarItem();

dump($items);
die;

regards