Garethp / php-ews

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

Access other users calendar #183

Closed Traxxas10 closed 4 years ago

Traxxas10 commented 4 years ago

Hello, I have the same problem like https://github.com/Garethp/php-ews/issues/156 (already closed), and used the code from there. Problem: the folderID is empty?

$api = API::withUsernameAndPassword(
    $server,$username ,$password,
    [
        'primarySmtpEmailAddress' => $email
    ]
);

$folderId = $api->getDistinguishedFolderId('calendar');

echo 'folderId: '.$folderId;

and now, If I say: $calendar = $api->getCalendar();

I still got my own calender. How can I join the calendar of $email?

best regards

Garethp commented 4 years ago

$folderId should be an object, not a string, so trying to echo it might not work. What do you get when you do a var_dump($folderId); instead?

Traxxas10 commented 4 years ago

omg, thank you very much. such a simple thing!!

$folder = $api->getFolderByDistinguishedId('calendar');
$calendar = $api->getCalendar();
$calendar->setFolderId($folder->getFolderId());
$items = $calendar->getCalendarItems($startdate, $enddate);

works like a charm, if a checked all rights for the user. But now I just want to show him Time, Free/Busy

so I think I have to change the following code in the getCalendarItems function : $request = [ 'Traversal' => 'Shallow', 'ItemShape' => [ 'BaseShape' => 'AllProperties' ], 'CalendarView' => [ 'MaxEntriesReturned' => 100, 'StartDate' => $start->format('c'), 'EndDate' => $end->format('c') ], 'ParentFolderIds' => $this->getFolderId()->toArray(true) ];

BaseShape "AllProperties" to something like Free/Busy/Time? I just found the Shapenames "Allproperties", "Default"?? and "IdOnly"

hope you can help me again :-)

Traxxas10 commented 4 years ago

"push :-) " image here you can see the rights of the user. (just free/busy time) and thats all what I need

I hope you can give me a hint or a solution :-)

best regards

Traxxas10 commented 4 years ago

sorry for doublepost, but I think I'm just about to finish it.

here is my new request in the "getCalendarItems" function:

$request = [
            'Traversal' => 'Shallow',
            'ItemShape' => [
                'BaseShape' => 'IdOnly',
                'AdditionalProperties' => [
                    'FieldURI' => [
                        ['FieldURI' => 'calendar:Start'],
                        ['FieldURI' => 'calendar:End'],
                        ['FieldURI' => 'calendar:LegacyFreeBusyStatus']
                    ],
                ]
            ],
            'CalendarView' => [
                'MaxEntriesReturned' => 100,
                'StartDate' => $start->format('c'),
                'EndDate' => $end->format('c')
            ],
            'ParentFolderIds' => $this->getFolderId()->toArray(true)
        ];

but I still received the access denied message - I think on "IdOnly" BaseShape?

best regards

Garethp commented 4 years ago

Can you post the full exception that you're getting, as well as the var_dump of the $this->getFolderId()->toArray(true)?

Traxxas10 commented 4 years ago

Full Error Message:

Fatal error: Uncaught garethp\ews\API\Exception\ExchangeException: Der Zugriff wird verweigert. Überprüfen Sie die Anmeldeinformationen, und versuchen Sie es dann erneut. in /home/.sites/208/site1554/web/ews/vendor/garethp/php-ews/src/API/ExchangeWebServices.php:418 Stack trace: #0 /home/.sites/208/site1554/web/ews/vendor/garethp/php-ews/src/API/ExchangeWebServices.php(380): garethp\ews\API\ExchangeWebServices::getItemsFromResponse(Object(garethp\ews\API\Message\FindItemResponseMessageType)) #1 /home/.sites/208/site1554/web/ews/vendor/garethp/php-ews/src/API/ExchangeWebServices.php(388): garethp\ews\API\ExchangeWebServices::drillDownResponseLevels(Object(garethp\ews\API\Message\FindItemResponseMessageType)) #2 /home/.sites/208/site1554/web/ews/vendor/garethp/php-ews/src/API/ExchangeWebServices.php(368): garethp\ews\API\ExchangeWebServices::drillDownResponseLevels(Object(garethp\ews\API\Message\FindItemResponseMessageType)) #3 /home/.sites/208/site1554/web/ews/vendor/garethp/php-ews/src/API/ExchangeWebServices/Middleware in /home/.sites/208/site1554/web/ews/vendor/garethp/php-ews/src/API/ExchangeWebServices.php on line 418

var_dump($this->getFolderId()->toArray(true));

array(1) { ["FolderId"]=> array(2) { ["Id"]=> string(120) "AAMkADMzMWZkMTFjLTBkYTctNGJmMC1iODg0LTExxOTk0NTM3Y2I4ZQAuAAAAAABAyAKOEDiPRpOeiSGN0VlwAQDe1gyd4vgrQ4FWtII9+se7AAAAAAEOAAA=" ["ChangeKey"]=> string(40) "AgAAABYAAADe1gyd4vgrQ4FWtwII9+se7AAAFL+WU" } }

Garethp commented 4 years ago

Can you post your full code again? You're trying to get the calendar through Impersonation, right?

Traxxas10 commented 4 years ago

Yes, through Impersonation with limited rights (just free/busy time)

`$api = API::withUsernameAndPassword(
    $server,$username ,$password,
    [
        'primarySmtpEmailAddress' => $email
    ]
); 
$folder = $api->getFolderByDistinguishedId('calendar');
$calendar = $api->getCalendar();
$calendar->setFolderId($folder->getFolderId());
$items = $calendar->getCalendarItems($startdate, $enddate);`
 public function getCalendarItems($start = '12:00 AM', $end = '11:59 PM', $options = array())
    {
        $start = Utilities\ensureIsDateTime($start);
        $end = Utilities\ensureIsDateTime($end);

        $request = [
            'Traversal' => 'Shallow',
            'ItemShape' => [
                'BaseShape' => 'IdOnly',
                'AdditionalProperties' => [
                    'FieldURI' => [
                        ['FieldURI' => 'calendar:Start'],
                        ['FieldURI' => 'calendar:End'],
                        ['FieldURI' => 'calendar:LegacyFreeBusyStatus']
                    ],
                ]
            ],
            'CalendarView' => [
                'MaxEntriesReturned' => 100,
                'StartDate' => $start->format('c'),
                'EndDate' => $end->format('c')
            ],
            'ParentFolderIds' => $this->getFolderId()->toArray(true) 
        ];

        $request = array_replace_recursive($request, $options);

        $request = Type::buildFromArray($request);

        $response = $this->getClient()->FindItem($request);
        $items = $response;

        return $items;
    }
Garethp commented 4 years ago

First of all, I don't think you actually need the

$folder = $api->getFolderByDistinguishedId('calendar');
$calendar = $api->getCalendar();
$calendar->setFolderId($folder->getFolderId());

It should be automatic. Secondly, if you only have permission to view the Free/Busy time, you won't be able to use getCalendarItems, since that actually gets you a list of calendar items, which would require more permissions. It sounds like you want to use the API for getting FreeBusy status. I've got an example that you can take a look at. You either want to take a look at areAvailable or if you want a more detailed response take a look at getAvailabilityFor which uses the EWS GetUserAvailability function if you want to take a look at all of the options available to you

Traxxas10 commented 4 years ago

:-) thank you very much for this hint. I works!

$api = API::withUsernameAndPassword($server,$username ,$password, ['timezone' => 'W. Europe Standard Time']);
$calendar = $api->getCalendar();

$availability = $calendar->getAvailabilityFor($startdate, $enddate, [$email]);

$items = $availability->getFreeBusyResponseArray()->FreeBusyResponse->getFreeBusyView()->getCalendarEventArray()->CalendarEvent;