【问题标题】:PHP-EWS: Set IsRead Flag for a MessagePHP-EWS:为消息设置 IsRead 标志
【发布时间】:2019-01-30 21:08:38
【问题描述】:

我正在编写一个 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 嵌套都是正确的,因为我一直在为 UpdateItem 函数引用 Microsoft's EWS SOAP reference。这是我用来将消息标记为已读的脚本代码。

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

【问题讨论】:

    标签: php soap exchangewebservices


    【解决方案1】:

    经过一番研究,我发现了一条评论,该评论在 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"/>
    

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

    【讨论】:

      【解决方案2】:

      可能首先要做的两件事是您应该将 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 中通常可以清楚地看出您做错了什么。

      【讨论】:

      • 我尝试使用 SoapClient 的 __getLastRequest()__getLastResponse() 函数转储从服务器发送和接收的 XML。但是,我的代码在请求发送之前就失败了。我将使用显示我最初遗漏的堆栈跟踪来更新我的问题。
      猜你喜欢
      • 1970-01-01
      • 2011-10-08
      • 2015-06-28
      • 1970-01-01
      • 2010-09-28
      • 1970-01-01
      • 1970-01-01
      • 2013-04-10
      • 2018-12-13
      相关资源
      最近更新 更多