PHP-EWS:为消息设置IsRead标志

时间:2016-06-21 19:26:18

标签: php soap exchangewebservices

我正在编写一个PHP脚本来读取来自Exchange Server 2010的电子邮件。目前,我能够检索所有未读的电子邮件,但我想将我检索到的电子邮件标记为已读,因此我无法检索我已经检索过的消息了。我正在使用github中的php-ews。我创建了一个脚本来执行此操作,但每次运行时,我都会在调用UpdateItem时出现此错误。

    PHP Fatal error:  SOAP-ERROR: Encoding: object has no 'Path' property
    Stack Trace:
    #0 ExchangeClient.php(355): SoapClient->__call('UpdateItem', Array)
    #1 ExchangeClient.php(355): NTLMSoapClient->UpdateItem(Object(UpdateItemType))
    #2 markReadTest.php(20): ExchangeClient->mark_as_read(Object(stdClass))
    #3 ExchangeClient.php on line 355

我注意到是什么导致了这个错误,因为我认为我的所有SOAP嵌套都是正确的,因为我一直在指代Microsoft's EWS SOAP reference的UpdateItem函数。以下是我用来将消息标记为已读的脚本的代码。

   public function mark_as_read($ReadMessage)
   {
      $request = new EWSType_UpdateItemType();
      $request->MessageDisposition = 'SaveOnly';
      $request->ConflictResolution = 'AlwaysOverwrite';
      $request->ItemChanges = array();

      $change = new EWSType_ItemChangeType();
      $change->ItemId = new EWSType_ItemIdType();
      $change->ItemId->Id = $ReadMessage->ItemId->Id;
      $change->ItemId->ChangeKey = $ReadMessage->ItemId->ChangeKey;

      $field = new EWSType_SetItemFieldType();
      $field->FieldURI = new EWSType_PathToUnindexedFieldType();
      $field->FieldURI->FieldURI = 'message:IsRead';
      $field->Message = new EWSType_MessageType();
      $field->Message->IsRead = True;

      $change->Updates->SetItemField[] = $field;

      $request->ItemChanges[] = $change;

      $response = $this->client->UpdateItem($request);
      return $response;
   }

2 个答案:

答案 0 :(得分:0)

首先可能要做的两件事就是将IsReadSpecified属性设置为true,例如

$request = new EWSType_UpdateItemType();
$request->MessageDisposition = 'SaveOnly';
$request->ConflictResolution = 'AlwaysOverwrite';
$request->ItemChanges = array();

$change = new EWSType_ItemChangeType();
$change->ItemId = new EWSType_ItemIdType();
$change->ItemId->Id = $ReadMessage->ItemId->Id;
$change->ItemId->ChangeKey = $ReadMessage->ItemId->ChangeKey;

$field = new EWSType_SetItemFieldType();
$field->FieldURI = new EWSType_PathToUnindexedFieldType();
$field->FieldURI->FieldURI = 'message:IsRead';
$field->Message = new EWSType_MessageType();
$field->Message->IsReadSpecified = true;
$field->Message->IsRead = true;

$change->Updates->SetItemField[] = $field;

$request->ItemChanges[] = $change;

$response = $this->client->UpdateItem($request);
return $response; 

另外,您可能希望查看代码提交给服务器的SOAP请求并发布。它通常从SOAP中清楚地看出你做错了什么。

答案 1 :(得分:0)

经过一些研究后,我发现了一条评论,提供了howtoforge post关于通过PHP SOAPclient连接到EWS的解决方案。解决方案是使用 types.xsd 文件中的FieldURI元素替换path元素。

原始XML标记:

<xs:element ref="t:Path"/>

替换为:

<xs:element ref="t:FieldURI"/>
<xs:element ref="t:IndexedFieldURI"/>
<xs:element ref="t:ExtendedFieldURI"/>

此路径元素在我的types.xsd版本中出现了8次,这是我从Exchange-2013 SP1服务器获得的,并且我用FieldURI元素替换了它的所有实例。之后,我这样做了,我能够将电子邮件标记为已读,而无需修改我在我的问题中使用的代码