Как получить все подпапки из "корня" рекурсивно через SOAP из Exchange?
После поиска в Интернете в течение нескольких часов вы моя последняя надежда:
Я должен построить систему, которая читает отправленные и входящие письма с сервера Microsoft Exchange. Для этого я нашел следующий скрипт: Exchange-Web-Services-for-PHP (Heartspring) https://github.com/Heartspring/Exchange-Web-Services-for-PHP
Существующая функция get_messages() возвращает все сообщения для папки, например "Входящие". Пока все ясно. Моя проблема начинается, когда я хочу получить все сообщения из "отправлено" - Папка - я перепробовал много слов, от "отправить" до "Отправленные"; безрезультатно (почтовый ящик недоступен)
Моя идея состояла в том, чтобы получить все подпапки для папки "root" и написал это:
include "init.php";
$ec = new ExchangeClient();
$ec->init("bambullis@123.de", "", NULL, "https://amxprd3610.outlook.com/EWS/Services.wsdl");
$folders = $ec->get_subfolders("root");
foreach($folders as $folder) {
print_r($folder);
}
Вот что я получаю:
stdClass Object
(
[FolderId] => stdClass Object
(
[Id] => AAAeAGJhbWJ1bGxpc0BzdHVrZSbi5kZQAuAAAAAABw352p5E4yS5voYF9ELBmiAQBXYPdO6NZAQ6T9C3xviT7xAAAAC1iXAAA=
[ChangeKey] => AQAAABYAAABXYPdO6NZAQ6T9C3xviAALNCey
)
[DisplayName] => Oberste Ebene des Informationsspeichers
[TotalCount] => 0
[ChildFolderCount] => 16
[UnreadCount] => 0
)
(Я знаю, что FolderId->Id закодирован в base64, я изменил приведенную выше строку по соображениям безопасности;o))
Теперь я попытался перечислить подпапки для этого каталога (я добавил почтовый ящик, чтобы увидеть, изменится ли значение "ChildFolderCount"):
...
print_r($folder);
print_r($ec->get_subfolders($folder->FolderId->Id));
...
Это ошибка, которую я получаю: Запрос не прошел проверку схемы: атрибут 'Id' недействителен
Что я сделал не так? Как рекурсивно получить все подпапки из "корня"? Спасибо этому прекрасному парню, который может мне помочь!
1 ответ
Метод get_subfolders EWS-PHP по умолчанию использует тип TraversalType " Shallow ", поэтому он ищет только идентифицированную папку и возвращает только идентификаторы папки для элементов, которые не были удалены.
Чтобы выполнить поиск во всех подпапках идентифицированной родительской папки и вернуть только идентификаторы папок для элементов, которые не были удалены, следует использовать " Deep " TraversalType.
Например:
<?php
include "init.php";
class myExchangeClient extends ExchangeClient {
public function get_subfolders_deep($ParentFolderId = "inbox", $Distinguished = TRUE) {
$this->setup();
$FolderItem = new stdClass();
$FolderItem->FolderShape = new stdClass();
$FolderItem->ParentFolderIds = new stdClass();
$FolderItem->FolderShape->BaseShape = "Default";
/*
** See http://msdn.microsoft.com/en-us/library/exchange/exchangewebservices.folderquerytraversaltype(v=exchg.140).aspx
** Deep Traversal: Searches in all subfolders of the identified parent folder and returns only the folder IDs for items that
** have not been deleted.
*/
$FolderItem->Traversal = "Deep";
if ($Distinguished) {
$FolderItem->ParentFolderIds->DistinguishedFolderId = new stdClass();
$FolderItem->ParentFolderIds->DistinguishedFolderId->Id = $ParentFolderId;
} else {
$FolderItem->ParentFolderIds->FolderId = new stdClass();
$FolderItem->ParentFolderIds->FolderId->Id = $ParentFolderId;
}
$response = $this->client->FindFolder($FolderItem);
if ($response->ResponseMessages->FindFolderResponseMessage->ResponseCode == "NoError") {
$folders = array();
if (!is_array($response->ResponseMessages->FindFolderResponseMessage->RootFolder->Folders->Folder)) {
$folders[] = $response->ResponseMessages->FindFolderResponseMessage->RootFolder->Folders->Folder;
} else {
$folders = $response->ResponseMessages->FindFolderResponseMessage->RootFolder->Folders->Folder;
}
return $folders;
} else {
$this->lastError = $response->ResponseMessages->FindFolderResponseMessage->ResponseCode;
}
}
}
$ec = new myExchangeClient();
$ec->init("bambullis@123.de", "", NULL, "https://amxprd3610.outlook.com/EWS/Services.wsdl");
$folders = $ec->get_subfolders_deep("root");
echo "<pre>".print_r($folders,true)."</pre>\n";
?>
В любом случае, глядя на исходный код класса ExchangeClient, FolderID для отправленных элементов должен быть " sentitems ".