Dynamics Crm Connector  v1.0
 All Data Structures Namespaces Files Functions Variables Pages
DynamicsCrm.php
Go to the documentation of this file.
1 <?php
3 /*
4  * ! \mainpage DynamicsCrm
5  *
6  * \section Installation
7  * if by any mean you dont get the bundle from packagist add to you composer.json under require\\n
8  *
9  * "dynamicscrm/connector" : "dev-master"
10  *
11  * to you composer.json\n
12  * and then : \n
13  *
14  * composer install
15  *
16  * or
17  *
18  * composer update
19  *
20  * enjoy the bundle\n\n
21  *
22  * Example:\n\n
23  *
24  * $DynamicsCrm=new DynamicsCrm($serv_adress, $user, $password);
25  * $result=$DynamicsCrm->Retrieve($Table, $Id, $Columns);
26  *
27  */
56 /*
57  * ! \brief Connector and basic operation from PHP to CRM using NTLM and curl.
58  *
59  * This connector load from a simple login/password/url (/web) \n
60  * it has the update/create/retrieve functionnality\n
61  * AND RetrieveMultiple based on FetchXML wich allow to make some powerfull request\n
62  * without the need to make many code\n
63  * For this part better check the documentation to understand the nesting of parameters.\n
64  *
65  * @todo make a Execute function to run anything with parameter.
66  */
67 class DynamicsCrm {
68  // @formatter:off
70  var $user;
71  var $password;
72  private $StateCheck=array(
73  'account'=>array('0'=>array('1'),'1'=>array('2')),
74  'activitypointer'=>array('0'=>array('1'),'1'=>array('2'),'2'=>array('3'),'3'=>array('4')),
75  'appointment'=>array('0'=>array('1','2','3','4'),'1'=>array('1','2','3','4'),'2'=>array('1','2','3','4'),'3'=>array('1','2','3','4')),
76  'kbarticle'=>array('1'=>array('1'),'2'=>array('2'),'2'=>array('3')),
77  'campaign'=>array('0'=>array('1','2','3','4','5')),
78  'campaignactivity'=>array('0'=>array('0','0','4','5','6'),'1'=>array('2'),'2'=>array('3')),
79  'campaignresponse'=>array('0'=>array('1'),'1'=>array('2'),'2'=>array('3')),
80  'incident'=>array('0'=>array('1','2','3','4'),'1'=>array('5'),'2'=>array('6')),
81  'incidentresolution'=>array('0'=>array('1'),'1'=>array('2'),'2'=>array('3')),
82  'notcustomizable'=>array('0'=>array('1'),'1'=>array('2'),'2'=>array('3')),
83  'contact'=>array('0'=>array('1'),'1'=>array('2')),
84  'contract'=>array('0'=>array('1'),'1'=>array('2'),'2'=>array('3'),'3'=>array('4'),'4'=>array('5'),'5'=>array('6')),
85  'contractdetail'=>array('0'=>array('1'),'1'=>array('2'),'2'=>array('3'),'3'=>array('4')),
86  'transactioncurrency'=>array('0'=>array('0'),'1'=>array('1')),
87  'discounttype'=>array('0'=>array('100001'),'1'=>array('100002')),
88  'email'=>array('0'=>array('1','8'),'1'=>array('2','3','4','6','7'),'2'=>array('5')),
89  'fax'=>array('0'=>array('1'),'1'=>array('2','3','4'),'2'=>array('5')),
90  'invoice'=>array('0'=>array('1','2','4','5','6'),'1'=>array('3','7'),'2'=>array('100001','100002'),'2'=>array('100003')),
91  'lead'=>array('0'=>array('1','2'),'1'=>array('3'),'2'=>array('4','5','6','7')),
92  'letter'=>array('0'=>array('1','2'),'1'=>array('3','4'),'2'=>array('5')),
93  'list'=>array('0'=>array('0'),'1'=>array('1')),
94  'opportunity'=>array('0'=>array('1','2'),'1'=>array('3'),'2'=>array('4','5')),
95  'salesorder'=>array('0'=>array('1','2'),'1'=>array('3'),'2'=>array('4'),'3'=>array('100001','100002'),'4'=>array('100003')),
96  'phonecall'=>array('0'=>array('1'),'1'=>array('2','4'),'2'=>array('3')),
97  'pricelevel'=>array('0'=>array('100001'),'1'=>array('100002')),
98  'product'=>array('0'=>array('1'),'1'=>array('2')),
99  'quote'=>array('0'=>array('1'),'1'=>array('2','2'),'2'=>array('4','5'),'3'=>array('5','6','7')),
100  'serviceappointment'=>array('0'=>array('1','2'),'1'=>array('8'),'2'=>array('9','10'),'3'=>array('3','4','6','7')),
101  'task'=>array('0'=>array('2','3','4','7'),'1'=>array('5'),'2'=>array('6'))
102  );
103  private $Aggregate = array ('avg','max','min','sum','count','countcolumn','countdistinct');
104  private $Operator= array(
105  '0'=>array('eq-userid','ne-userid','eq-bysinessid','ne-bysinessid',
106  'eq-userteams','last-seven-days','last-fiscal-period','last-fiscal-year','last-month',
107  'last-week','last-year','next-seven-days','next-fiscal-period','next-fiscal-year','next-month','next-week',
108  'next-year','null','this-fiscal-period','this-fiscal-year','this-month','this-week','this-year','today','not-null','tomorrow','yesterday') ,
109  '1'=>array('like','not-like','eq','ge','gt','le','lt','ne','on','on-or-after','on-or-before',
110  'in-fiscal-period','in-fiscal-year','last-x-days','last-x-fiscal-periods','last-x-fiscal-years','last-x-hours',
111  'last-x-months','last-x-weeks','last-x-years','next-x-days','next-x-fiscal-periods','next-x-fiscal-years',
112  'next-x-hours','next-x-months','next-x-weeks','next-x-years','olderthan-x-months') ,
113  '2'=> array('not-in','in'),
114  '3'=> array('between','not-between','in-fiscal-period-and-year','in-or-after-fiscal-period-and-year','in-or-before-fiscal-period-and-year')
115  );
116 
128  function __construct($serv_adress, $user, $password) {
129  $this->setServAdress ( $serv_adress );
130  $this->setUser ( $user );
131  $this->setPassword ( $password );
132  }
133 
138  public function getServAdress() {
139  return $this->serv_adress;
140  }
141 
147  public function setServAdress($serv_adress) {
148  $this->serv_adress = $serv_adress;
149  return $this;
150  }
151 
156  public function getUser() {
157  return $this->user;
158  }
159 
166  public function setUser($user) {
167  $this->user = $user;
168  return $this;
169  }
170 
175  public function getPassword() {
176  return $this->password;
177  }
178 
184  public function setPassword($password) {
185  $this->password = $password;
186  return $this;
187  }
188 
207  function Retrieve($Table, $Id, $Columns) {
208 
209  // build Saop Enveloppe
210  $SoapEnvelope = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:con="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:arr="http://schemas.microsoft.com/2003/10/Serialization/Arrays">
211  <soap:Body>
212  <ser:Retrieve>
213  <ser:entityName>' . $Table . '</ser:entityName>
214  <ser:id>' . $Id . '</ser:id>';
215  $SoapEnvelope .= $this->FormatColumn ( $Columns );
216  $SoapEnvelope .= '</ser:Retrieve>
217  </soap:Body>
218  </soap:Envelope>';
219 
220  // call
221  Return $this->call ( 'Retrieve', $SoapEnvelope );
222  }
223 
249  public function RetrieveMultiple($Table, $Where, $Columns=false, $Join = false, $Order = false) {
250  // check if there is some agregate inside parameter
251  if (is_array ( $Columns )) {
252  if ($this->array_key_exists_r ( 'aggregate', $Columns ) || $this->array_key_exists_r ( 'groupby', $Columns )) {
253  $Aggregate = 'true';
254  } else
255  $Aggregate = 'false';
256  } else
257  $Aggregate = 'false';
258  // build Soap Enveloppe
259  try {
260  $Entity = $this->FormatFetchEntity ( $Table );
261  $Attributes = $this->FormatFetchAttribute ( $Columns );
262  $Order = $this->FormatFetchOrder ( $Order );
263  $Filter = $this->formatFetchFilter ( $Where );
264  if ($Join !== false){
265  $Join = $this->FormatFetchJoin ( $Join );
266  }else $Join='';
267  } catch ( Exception $e ) {
268  return $this->GetErrorObject ( $e->getMessage () );
269  }
270 
271  $SoapEnvelope = '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
272  <s:Body>
273  <RetrieveMultiple xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
274  <query i:type="a:FetchExpression" xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts">
275  <a:Query>
276  &lt;fetch version=\'1.0\' output-format=\'xml-platform\' mapping=\'logical\' aggregate=\'' . $Aggregate . '\' distinct=\'false\'&gt;';
277  $SoapEnvelope.=$Entity.$Attributes.$Order.$Filter.$Join;
278 
279  // add footer
280  $SoapEnvelope .= '&lt;/entity&gt;
281  &lt;/fetch&gt;
282  </a:Query>
283  </query>
284  </RetrieveMultiple>
285  </s:Body>
286  </s:Envelope>
287  ';
288 
289  // call
290  Return $this->call ( 'RetrieveMultiple', $SoapEnvelope );
291  }
292 
310  public function Delete($Table, $Id) {
311  // build soap Enveloppe
312  $SoapEnvelope = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ser="http://schemas.microsoft.com/xrm/2011/Contracts/Services">
313  <soap:Header/>
314  <soap:Body>
315  <ser:Delete>
316  <ser:entityName>' . $Table . '</ser:entityName>
317  <ser:id>' . $Id . '</ser:id>
318  </ser:Delete>
319  </soap:Body>
320  </soap:Envelope>';
321  // call
322  Return $this->call ( 'Delete', $SoapEnvelope );
323  }
324 
348  function Update($Table, $Params, $Id) {
349  // check the array parameter first
350  try {
351  $Param = $this->FormatAttributes ( $Params );
352  } catch ( Exception $e ) {
353  return $this->GetErrorObject ( $e->getMessage () );
354  }
355  // build soap Enveloppe
356  $SoapEnvelope = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
357  <soap:Body><Update xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services">
358  <entity xmlns:b="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
359  <b:Attributes xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
360  ' . $Param . '
361  </b:Attributes>
362  <b:EntityState i:nil="true"/>
363  <b:FormattedValues xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic"/>
364  <b:Id>' . $Id . '</b:Id>
365  <b:LogicalName>' . $Table . '</b:LogicalName>
366  <b:RelatedEntities xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic"/>
367  </entity></Update>
368  </soap:Body>
369  </soap:Envelope>';
370  // call
371  return $this->call ( 'Update', $SoapEnvelope );
372  }
373 
406  public function Create($Table, $Params) {
407  try {
408  $Param = $this->FormatAttributes ( $Params );
409  } catch ( Exception $e ) {
410  return $this->GetErrorObject ( $e->getMessage () );
411  }
412  $SoapEnvelope = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
413  <soap:Body>
414  <Create xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services">
415  <entity xmlns:b="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
416  <b:Attributes xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
417  ' . $Param . '
418  </b:Attributes>
419  <b:EntityState i:nil="true"/>
420  <b:FormattedValues />
421  <b:Id>00000000-0000-0000-0000-000000000000</b:Id>
422  <b:LogicalName>' . $Table . '</b:LogicalName>
423  <b:RelatedEntities />
424  </entity></Create></soap:Body>
425  </soap:Envelope>';
426  return $this->call ( 'Create', $SoapEnvelope );
427  }
428 
429 
443  public function SetState($Id, $Table, $StateCode, $StatusCode) {
444  if (isset ( $this->StateCheck [$Table] [$StateCode] ) && in_array ( $StatusCode, $this->StateCheck [$Table] [$StateCode] )) {
445 
446  $Request = '<request i:type="b:SetStateRequest" xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:b="http://schemas.microsoft.com/crm/2011/Contracts">
447  <a:Parameters xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
448  <a:KeyValuePairOfstringanyType>
449  <c:key>EntityMoniker</c:key>
450  <c:value i:type="a:EntityReference">
451  <a:Id>' . $Id . '</a:Id>
452  <a:LogicalName>' . $Table . '</a:LogicalName>
453  <a:Name i:nil="true" />
454  </c:value>
455  </a:KeyValuePairOfstringanyType>
456  <a:KeyValuePairOfstringanyType>
457  <c:key>State</c:key>
458  <c:value i:type="a:OptionSetValue">
459  <a:Value>' . $StateCode . '</a:Value>
460  </c:value>
461  </a:KeyValuePairOfstringanyType>
462  <a:KeyValuePairOfstringanyType>
463  <c:key>Status</c:key>
464  <c:value i:type="a:OptionSetValue">
465  <a:Value>' . $StatusCode . '</a:Value>
466  </c:value>
467  </a:KeyValuePairOfstringanyType></a:Parameters>
468  <a:RequestId i:nil="true" />
469  <a:RequestName>SetState</a:RequestName>
470  </request>';
471  return $this->ExecuteBody ( $Request );
472  } else {
473  $strPair = print_r ( $this->StateCheck [$Table], true );
474  return $this->GetErrorObject ( 'Pair State and status not avaible for ' . $Table . ' should be in State => array( avaible status) : ' . $strPair );
475  }
476  }
477 
478 
484  public function GetAllEntities() {
485  $Request = '<request i:type="a:RetrieveAllEntitiesRequest" xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts">
486  <a:Parameters xmlns:b="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
487  <a:KeyValuePairOfstringanyType>
488  <b:key>EntityFilters</b:key>
489  <b:value i:type="c:EntityFilters" xmlns:c="http://schemas.microsoft.com/xrm/2011/Metadata">Privileges</b:value>
490  </a:KeyValuePairOfstringanyType>
491  <a:KeyValuePairOfstringanyType>
492  <b:key>RetrieveAsIfPublished</b:key>
493  <b:value i:type="c:boolean" xmlns:c="http://www.w3.org/2001/XMLSchema">true</b:value>
494  </a:KeyValuePairOfstringanyType>
495  </a:Parameters>
496  <a:RequestId i:nil="true" />
497  <a:RequestName>RetrieveAllEntities</a:RequestName>
498  </request>
499  ';
500  $Return = $this->ExecuteBody ( $Request );
501  return $Return;
502  }
503 
515  public function Workflow($EntityId, $WorkflowId) {
516  $Request = '<request i:type="b:ExecuteWorkflowRequest" xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:b="http://schemas.microsoft.com/crm/2011/Contracts">
517  <a:Parameters xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
518  <a:KeyValuePairOfstringanyType>
519  <c:key>EntityId</c:key>
520  <c:value i:type="d:guid" xmlns:d="http://schemas.microsoft.com/2003/10/Serialization/">$EntityId</c:value>
521  </a:KeyValuePairOfstringanyType>
522  <a:KeyValuePairOfstringanyType>
523  <c:key>WorkflowId</c:key>
524  <c:value i:type="d:guid" xmlns:d="http://schemas.microsoft.com/2003/10/Serialization/">$WorkflowId</c:value>
525  </a:KeyValuePairOfstringanyType>
526  </a:Parameters>
527  <a:RequestId i:nil="true" />
528  <a:RequestName>ExecuteWorkflow</a:RequestName>
529  </request>';
530  $Return = $this->ExecuteBody ( $Request );
531  $Return = $this->ParseDatas ( $Return->Result->Body->ExecuteResponse->ExecuteResult->Results, $Return );
532  return $this->ExecuteBody ( $Request );
533  }
534 
539  public function Associate() {
540  $SoapEnvelope = '<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
541  <soap:Body>
542  <Associate xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services">
543  <subType>
544  </subType>
545  <objectType>
546  10069</objectType>
547  <parentObjectType>10095</parentObjectType>
548  <objectId>568B31F9-8AEE-E211-8830-005056B74E4F</objectId>
549  <parentId>A5DF8846-3BF0-E211-8830-005056B74E4F</parentId>
550  <associationName>classification_occupation</associationName>
551  </Associate></soap:Body>
552  </soap:Envelope>';
553  return $this->call ( 'Associate', $SoapEnvelope );
554  }
555 
556 
574  public function Assign($Table,$Id,$IdAssign,$TypeAssign='systemuser'){
575  $Request = '<request i:type="b:AssignRequest" xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:b="http://schemas.microsoft.com/crm/2011/Contracts">
576  <a:Parameters xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic">
577  <a:KeyValuePairOfstringanyType>
578  <c:key>Target</c:key>
579  <c:value i:type="a:EntityReference">
580  <a:Id>'.$Id.'</a:Id>
581  <a:LogicalName>'.$Table.'</a:LogicalName>
582  <a:Name i:nil="true" />
583  </c:value>
584  </a:KeyValuePairOfstringanyType>
585  <a:KeyValuePairOfstringanyType>
586  <c:key>Assignee</c:key>
587  <c:value i:type="a:EntityReference">
588  <a:Id>'.$IdAssign.'</a:Id>
589  <a:LogicalName>'.$TypeAssign.'</a:LogicalName>
590  <a:Name i:nil="true" />
591  </c:value>
592  </a:KeyValuePairOfstringanyType>
593  </a:Parameters>
594  <a:RequestId i:nil="true" />
595  <a:RequestName>Assign</a:RequestName>
596  </request>';
597 
598  $Response= $this->ExecuteBody ( $Request );
599  if(isset( $Response->Error) && $Response->Error===true){
600  return $Response;
601  }else{
602  $Return = new CrmResponse ();
603  $Return->Error = false;
604  $Return->ErrorCode = false;
605  $Return->ErrorMessage = '';
606  $Return->NbResult =1 ;
607  $Return->Result=true;
608  return $Return;
609  }
610  }
611 
616  public function GetCurrentUserInfo() {
617  $Request = '<request i:type="b:WhoAmIRequest" xmlns:a="http://schemas.microsoft.com/xrm/2011/Contracts" xmlns:b="http://schemas.microsoft.com/crm/2011/Contracts">
618  <a:Parameters xmlns:c="http://schemas.datacontract.org/2004/07/System.Collections.Generic" />
619  <a:RequestId i:nil="true" />
620  <a:RequestName>WhoAmI</a:RequestName>
621  </request>';
622 
623  $Return = $this->ExecuteBody ( $Request );
624  $Return = $this->ParseDatas ( $Return->Result->Body->ExecuteResponse->ExecuteResult->Results, $Return );
625  return $Return;
626  }
627 
635  private function ExecuteBody($Request) {
636  $SoapEnvelope = '<s:Envelope xmlns:s="http://schemas.xmlsoap.org/soap/envelope/">
637  <s:Body>
638  <Execute xmlns="http://schemas.microsoft.com/xrm/2011/Contracts/Services" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
639  ' . $Request . '
640  </Execute>
641  </s:Body>
642  </s:Envelope>';
643  return $this->call ( 'Execute', $SoapEnvelope );
644  }
645 
655  private function call($operation, $soapBody) {
656  $headers = $this->GenerateSoapHeader ( $operation );
657 
658  $ch = curl_init ();
659  curl_setopt ( $ch, CURLOPT_URL, $this->serv_adress );
660  curl_setopt ( $ch, CURLOPT_RETURNTRANSFER, true );
661  curl_setopt ( $ch, CURLOPT_HTTPHEADER, $headers );
662  curl_setopt ( $ch, CURLOPT_UNRESTRICTED_AUTH,true);
663  curl_setopt ( $ch, CURLOPT_FOLLOWLOCATION,true);
664  curl_setopt ( $ch, CURLOPT_POST, true );
665  curl_setopt ( $ch, CURLOPT_POSTFIELDS, $soapBody );
666  curl_setopt ( $ch, CURLOPT_HTTPAUTH, CURLAUTH_NTLM );
667  curl_setopt ( $ch, CURLOPT_USERPWD, $this->user . ':' . $this->password );
668  $response = curl_exec ( $ch );
669  $Return = new CrmResponse ();
670  if ($response === false) {
671  $Return->Error = True;
672  $Return->ErrorCode = 0;
673  $Return->ErrorMessage = curl_error ( $ch );
674  $Return->Result = False;
675  } else {
676 
677  $response = str_replace ( '<a:', '<', $response );
678  $response = str_replace ( '<b:', '<', $response );
679  $response = str_replace ( '<c:', '<', $response );
680  $response = str_replace ( '<s:', '<', $response );
681  $response = str_replace ( '</a:', '</', $response );
682  $response = str_replace ( '</b:', '</', $response );
683  $response = str_replace ( '</c:', '</', $response );
684  $response = str_replace ( '</s:', '</', $response );
685  $xml = simplexml_load_string ( $response );
686  if (isset ( $xml->Body->Fault )) {
687  $Return->Error = True;
688  $Return->ErrorCode = ( string ) $xml->Body->Fault->faultcode;
689  $Return->ErrorMessage = ( string ) $xml->Body->Fault->faultstring;
690  $Return->Result = False;
691  } else {
692  switch ($operation) {
693  case 'RetrieveMultiple' :
694  $Return = $this->ParseRetrieveMultiple ( $xml, $Return );
695  Break;
696  case 'Retrieve' :
697  $Return = $this->ParseRetrieve ( $xml, $Return );
698  Break;
699  case 'Create' :
700  $Return->NbResult = 1;
701  $Return->Result = ( string ) $xml->Body->CreateResponse->CreateResult;
702  Break;
703  case 'Update' :
704  if (isset ( $xml->Body->UpdateResponse )) {
705  $Return->NbResult = 1;
706  $Return->Result = true;
707  } else {
708  $Return->Error = True;
709  $Return->ErrorCode = 'Unknown Error';
710  $Return->ErrorMessage = 'Unknown Error';
711  }
712  Break;
713  case 'Execute' :
714  $Return->NbResult = 1;
715  $Return->Result = $xml;
716  break;
717  case 'Associate' :
718  die ( print_r ( $xml ) );
719  break;
720  case 'Delete' :
721  if (isset ( $xml->Body->DeleteResponse )) {
722  $Return->NbResult = 1;
723  $Return->Result = true;
724  } else {
725  $Return->Error = True;
726  $Return->ErrorCode = 'Unknown Error';
727  $Return->ErrorMessage = 'Unknown Error';
728  }
729  Break;
730  }
731  }
732  }
733 
734  return $Return;
735  }
736 
743  private function FormatFetchEntity($EntityName) {
744  return " &lt;entity name='" . $EntityName . "'&gt;";
745  }
746 
775  private function FormatFetchAttribute($Columns) {
776  $Attributes = '';
777  if (is_array ( $Columns )) {
778  foreach ( $Columns as $column ) {
779  if (is_array ( $column )) {
780  $this->TestParameter ( $column, 'name' );
781  // aggregate cases
782  if (isset ( $column ['name'] )) {
783  if (empty ( $column ['alias'] )) {
784  $column ['alias'] = $column ['name'];
785  }
786  // basic aggregate function avg , max, min, sum, count (COUNT(*)) ,countcolumn (COUNT(name)) ,countdistinct (COUNT(DISTINCT name))
787  if (! empty ( $column ['aggregate'] )) {
788  $this->TestAgreggate ( $column ['aggregate'] );
789  if ($column ['aggregate'] == 'countdistinct') {
790  $Attributes .= "&lt;attribute name='" . $column ['name'] . "' alias='" . $column ['alias'] . "' aggregate='countcolumn' distinct='true' /&gt;";
791  } else {
792  $Attributes .= "&lt;attribute name='" . $column ['name'] . "' alias='" . $column ['alias'] . "' aggregate='" . $column ['aggregate'] . "' /&gt;";
793  }
794  // so is that a groupby?
795  } else if (isset ( $column ['groupby'] )) {
796  $this->TestParameter ( $column, 'alias' );
797  if (isset ( $column ['alias'] )) {
798  if ($column ['groupby'] !== true) {
799  $Attributes .= "&lt;attribute name='" . $column ['name'] . "' alias='" . $column ['alias'] . "' dategrouping='" . $column ['groupby'] . "' groupby='true' /&gt;";
800  } else {
801  $Attributes .= "&lt;attribute name='" . $column ['name'] . "' alias='" . $column ['alias'] . "' groupby='true' /&gt;";
802  }
803  }
804  }
805  // normal cases
806  }
807  } else
808  $Attributes .= "&lt;attribute name='" . $column . "' /&gt;";
809  }
810  }
811  return $Attributes;
812  }
813 
856  private function FormatAttributes($Params) {
857  $TxtAttribute = '';
858 
859  if (is_array ( $Params )) {
860  foreach ( $Params as $Param ) {
861  $TxtAttribute .= $this->FormatAttribute ( $Param );
862  }
863  }
864  return $TxtAttribute;
865  }
866 
889  private function FormatAttribute($Param) {
890  $TxtAttribute = '';
891  $this->TestParameters ( $Param, array('field','type') );
892  if (isset ( $Param ['field'] ) && isset ( $Param ['type'] )) {
893  $TxtAttribute .= '<b:KeyValuePairOfstringanyType>
894  <c:key>' . $Param ['field'] . '</c:key>';
895  switch ($Param ['type']) {
896  case 'OptionSetValue' :
897  case 'optionsetvalue' :
898  case 'option' :
899  case 'Option' :
900  $this->TestParameter ( $Param, 'value' );
901  $TxtAttribute .= '<c:value i:type="b:OptionSetValue"><b:Value>' . $Param ['value'] . '</b:Value></c:value>';
902  break;
903  case 'Money' :
904  case 'money' :
905  $this->TestParameter ( $Param, 'value' );
906  $TxtAttribute .= '<c:value i:type="b:Money"><b:value>' . $Param ['value'] . '</b:value></c:value>';
907  break;
908  case 'Boolean' :
909  case 'boolean' :
910  case 'bool' :
911  case 'Bool' :
912  $this->TestParameter ( $Param, 'value' );
913  $TxtAttribute .= '<c:value i:type="d:boolean" xmlns:d="http://www.w3.org/2001/XMLSchema">' . $Param ['value'] . '</c:value>';
914  break;
915  case 'Integer' :
916  case 'integer' :
917  case 'Int' :
918  case 'int' :
919  $this->TestParameter ( $Param, 'value' );
920  $TxtAttribute .= '<c:value i:type="d:int" xmlns:d="http://www.w3.org/2001/XMLSchema">' . $Param ['value'] . '</c:value>';
921  break;
922  case 'DateTime' :
923  case 'datetime' :
924  $this->TestParameter ( $Param, 'value' );
925  $TxtAttribute .= '<c:value i:type="d:dateTime" xmlns:d="http://www.w3.org/2001/XMLSchema">' . $Param ['value'] . '</c:value>';
926  break;
927  case 'String' :
928  case 'string' :
929  default :
930  $this->TestParameter ( $Param, 'value' );
931  $TxtAttribute .= '<c:value i:type="d:string" xmlns:d="http://www.w3.org/2001/XMLSchema">' . $Param ['value'] . '</c:value>';
932  break;
933  case 'EntityReference' :
934  case 'entityreference' :
935  case 'Entity' :
936  case 'entity' :
937  $this->TestParameter ( $Param, 'id','name' );
938  $TxtAttribute .= '<c:value i:type="b:EntityReference">
939  <b:Id>' . $Param ['id'] . '</b:Id>
940  <b:LogicalName>' . $Param ['name'] . '</b:LogicalName>
941  <b:Name i:nil="true" />
942  </c:value>';
943  break;
944  case 'ActivityParty' :
945  case 'Activity' :
946  case 'activityparty' :
947  case 'activity' :
948  case 'ArrayOfEntity' :
949  case 'arrayofentity' :
950  case 'Array' :
951  case 'array' :
952  $TxtAttribute .= '<c:value i:type="b:ArrayOfEntity">';
953  $this->TestParameter ( $Param, 'value' );
954  foreach ( $Param ['value'] as $entity ) {
955  $TxtAttribute .= ' <b:Entity>
956  <b:Attributes>';
957  $TxtAttribute .= $this->FormatAttribute ( $entity );
958  $TxtAttribute .= '</b:Attributes><b:Entitystate i:nil="true" />
959  <b:FormattedValues />
960  <b:Id>00000000-0000-0000-0000-000000000000</b:Id>
961  <b:LogicalName>activityparty</b:LogicalName>
962  <b:RelatedEntities />
963  </b:Entity>';
964  }
965  $TxtAttribute .= '
966  </c:value>';
967 
968  break;
969  }
970  $TxtAttribute .= '</b:KeyValuePairOfstringanyType>';
971  }
972 
973  return $TxtAttribute;
974  }
979  private function TestParameters($Param, $Fields) {
980  foreach ( $Fields as $Field ) {
981  $this->TestParameter ( $Param, $Field );
982  }
983  }
984 
990  private function TestParameter($Param, $field) {
991  if (! isset ( $Param [$field] )) {
992  $strArray = print_r ( $Param, true );
993  throw new \InvalidArgumentException ( sprintf ( "Missing Parameter $field for array : $strArray" ) );
994  }
995  }
996 
1001  private function TestAgreggate($Param) {
1002  if (! in_array ( $Param, $this->Aggregate )) {
1003  $AggregateValue = print_r ( $this->Aggregate, true );
1004  throw new \InvalidArgumentException ( sprintf ( "Aggregate Invalid should be in : $AggregateValue" ) );
1005  }
1006  }
1007 
1012  private function GetErrorObject($message) {
1013  $Return = new CrmResponse ();
1014  $Return->Error = True;
1015  $Return->ErrorCode = 0;
1016  $Return->ErrorMessage = $message;
1017  $Return->Result = False;
1018  return $Return;
1019  }
1032  private function FormatColumn($Columns) {
1033  if ($Columns !== false && ! is_array ( $Columns )) {
1034  throw new \InvalidArgumentException ( sprintf ( "Column Parameter invalid : $Columns" ) );
1035  }
1036  $AllCol = ($Columns == false) ? 'true' : 'false';
1037  $TxtColumn = '<ser:columnSet><con:AllColumns>' . $AllCol . '</con:AllColumns><con:Columns>';
1038  if ($Columns != false) {
1039  foreach ( $Columns as $Column ) {
1040  $TxtColumn .= '<arr:string>' . $Column . '</arr:string>';
1041  }
1042  }
1043  $TxtColumn .= '</con:Columns></ser:columnSet>';
1044  return $TxtColumn;
1045  }
1046 
1064  private function FormatFetchOrder($Orders) {
1065  $TxtOrder = '';
1066  if (is_array ( $Orders )) {
1067  foreach ( $Orders as $Order ) {
1068  $this->TestParameters ( $Order, array('Column','Order'));
1069  if (isset ( $Order ['Column'] ) && isset ( $Order ['Order'] )) {
1070  $TxtOrder .= "&lt;order attribute='" . $Order ['Column'] . "' descending='";
1071  $TxtOrder .= ($Order ['Order'] == 'Asc') ? 'false' : 'true';
1072  $TxtOrder .= "' /&gt;";
1073  }
1074  }
1075  }
1076  return $TxtOrder;
1077  }
1078 
1121  private function FormatFetchFilter($Filters) {
1122  $TxtFilter = '';
1123  if (is_array ( $Filters )) {
1124  if (isset ( $Filters ['Type'] )) {
1125  $TxtHead = "&lt;filter type='" . $Filters ['Type'] . "' &gt;";
1126  } else {
1127  $TxtHead = '&lt;filter &gt;';
1128  }
1129  foreach ( $Filters as $Filter ) {
1130  if (isset ( $Filter ['Type'] )) {
1131  $TxtFilter .= $this->FormatFetchFilter ( $Filter );
1132  } else {
1133  if (isset ( $Filter ['Op'] )) {
1134  $TxtFilter .= $this->FormatCondition ( $Filter );
1135  }
1136  }
1137  }
1138  if($TxtFilter!=''){
1139  $TxtFilter=$TxtHead.$TxtFilter.'&lt;/filter &gt;';
1140  return $TxtFilter;
1141  }else return '';
1142  } else return '';
1143 
1144 
1145  }
1146 
1171  private function FormatFetchJoin($Joins) {
1172  // so we dont have to make a special statement for only 1 join
1173  $TxtJoin = '';
1174  if (isset ( $Joins ['name'] )) {
1175  $Joins = array (
1176  '1' => $Joins
1177  );
1178  }
1179  foreach ( $Joins as $Join ) {
1180  $this->TestParameters($Join,array('name','from','to','type','columns','where'));
1181  $TxtJoin .= "&lt;link-entity name='" . $Join ['name'] . "' from='" . $Join ['from'] . "' to='" . $Join ['to'] . "' ";
1182  if (! empty ( $Join ['alias'] )){
1183  $TxtJoin .= " alias='" . $Join ['alias'] . "' ";
1184  }
1185  $TxtJoin .= " link-type='" . $Join ['type'] . "' &gt;";
1186  $TxtJoin .= $this->FormatFetchAttribute ( $Join ['columns'] );
1187  if (! empty ( $Join ['nested'] ))
1188  $TxtJoin .= FormatFetchJoin ( $Join );
1189  $TxtJoin .= $this->formatFetchFilter ( $Join ['where'] );
1190  $TxtJoin .= "&lt;/link-entity&gt;";
1191  }
1192  return $TxtJoin;
1193  }
1194 
1208  private function FormatCondition($Filter) {
1209 
1210  /*
1211  * The operators wich dont need a value
1212  * so no need for value here
1213  */
1214  if (in_array ( $Filter ['Op'], $this->Operator ['0'] )) {
1215  $Condition = "&lt;condition attribute='" . $Filter ['Column'] . "' operator='" . $Filter ['Op'] . "' /&gt;";
1216  /*
1217  * The basic operators
1218  * Value to be set, nothing much
1219  */
1220  } else if (in_array ( $Filter ['Op'], $this->Operator ['1'] )) {
1221  $this->TestParameters ( $Filter, array (
1222  'Column',
1223  'Value'
1224  ) );
1225  $Condition = "&lt;condition attribute='" . $Filter ['Column'] . "' operator='" . $Filter ['Op'] . "' value='" . $Filter ['Value'] . "' /&gt;";
1226  /*
1227  * The in operators
1228  * Value is now an array with data to be tested array('1','2',...)
1229  */
1230  } else if (in_array ( $Filter ['Op'], $this->Operator ['2'] )) {
1231  $this->TestParameters ( $Filter, array (
1232  'Column',
1233  'Value'
1234  ) );
1235  $Condition = "&lt;condition attribute='" . $Filter ['Column'] . "' operator='" . $Filter ['Op'] . "' &gt;";
1236  if (! is_array ( $Filter ['Value'] )) {
1237  $TxtFilter = print_r ( $Filter, true );
1238  throw new \InvalidArgumentException ( sprintf ( "Filter Incorrect [Value] for this kind of operator should be an array : $TxtFilter" ) );
1239  }
1240  foreach ( $Filter ['Value'] as $Value ) {
1241  $Condition .= '&lt;value&gt;' . $Value . '&lt;/value&gt;';
1242  }
1243  $Condition .= '&lt;/condition &gt;';
1244  /*
1245  * The 2 values operator
1246  * Value and Value2 in array
1247  */
1248  } else if (in_array ( $Filter ['Op'], $this->Operator ['3'] )) {
1249  $this->TestParameters ( $Filter, array (
1250  'Column',
1251  'Value','Value2'
1252  ) );
1253  $Condition = "&lt;condition attribute='" . $Filter ['Column'] . "' operator='" . $Filter ['Op'] . "' &gt;";
1254  $Condition .= '&lt;value&gt;' . $Filter ['Value'] . '&lt;/value&gt; &lt;value&gt;' . $Filter[
1255  'Value2'
1256  ] . '&lt;/value&gt;';
1257  $Condition .= '&lt;/condition &gt;';
1258  } else {
1259  $ListOperator = print_r ( $this->Operator, true );
1260  throw new \InvalidArgumentException ( sprintf ( "Condition '" . $Filter ['Op'] . "' Invalid should be in : $ListOperator" ) );
1261  }
1262 
1263  return $Condition;
1264  }
1265 
1275  private function ParseRetrieveMultiple($xml, $Return) {
1276  $Datas = $xml->Body->RetrieveMultipleResponse->RetrieveMultipleResult->Entities->Entity; // ->retrievemultipleresponse;//->retrievemultipleresult->entities->entity;
1277  $Return = $this->ParseDatas ( $Datas, $Return );
1278  return $Return;
1279  }
1280 
1290  private function ParseDatas($Datas, $Return) {
1291  $NbResults = 0;
1292  $Results = array ();
1293  foreach ( $Datas as $Data ) {
1294  $ResultLine = $this->ParseResultLine ( $Data );
1295  $Results [$NbResults] = $ResultLine;
1296  $NbResults ++;
1297  }
1298  $Return->NbResult = $NbResults;
1299  $Return->Result = $Results;
1300  return $Return;
1301  }
1302 
1311  private function ParseResultLine($Data) {
1312  $ResultLine = new \stdClass ();
1313  if (isset ( $Data->Attributes )) {
1314  foreach ( $Data->Attributes as $keypair ) {
1315  foreach ( $keypair->KeyValuePairOfstringanyType as $data ) {
1316  $key = str_ireplace ( '.', '_', $data->key );
1317  $ResultLine->$key = $this->ParseKeyPair ( $data );
1318  }
1319  }
1320  } else {
1321 
1322  foreach ( $Data as $data ) {
1323  if (isset ( $data->key )) {
1324  $key = str_ireplace ( '.', '_', $data->key );
1325  $ResultLine->$key = $this->ParseKeyPair ( $data );
1326  }
1327  }
1328  }
1329  return $ResultLine;
1330  }
1331 
1336  private function ParseKeyPair($data) {
1337  // liason simple
1338  if (isset ( $data->value->Value )) {
1339  $value = ( string ) $data->value->Value;
1340  // entit้ logique
1341  } else if (isset ( $data->value->LogicalName )) {
1342  $value = array (
1343  'id' => ( string ) $data->value->Id,
1344  'logicalname' => ( string ) $data->value->LogicalName,
1345  'name' => ( string ) $data->value->Name
1346  );
1347  } else if (isset ( $data->value->Entities )) {
1348  $Entities = array ();
1349  foreach ( $data->value->Entities as $entity ) {
1350  if (isset ( $entity->Entity->Attributes )) {
1351  $Entities [] = $this->ParseResultLine ( $entity->Entity );
1352  }
1353  }
1354 
1355  $value = $Entities;
1356  } else
1357  $value = ( string ) $data->value;
1358 
1359  if (! is_array ( $value )) {
1360  if (ctype_digit ( $value )) {
1361  return ( int ) $value;
1362  } else if (is_float ( $value )) {
1363  return ( float ) $value;
1364  } else if (is_bool ( $value )) {
1365  return ( bool ) $value;
1366  } else
1367  return $value;
1368  } else
1369  return $value;
1370  }
1371 
1381  private function ParseRetrieve($xml, $Return) {
1382  $Datas = $xml->Body->RetrieveResponse->RetrieveResult;
1383  $Return = $this->ParseDatas ( $Datas, $Return );
1384  $Return->Result = $Return->Result [0];
1385  return $Return;
1386  }
1387 
1395  private function GenerateSoapHeader($operation) {
1396  $soap_action = 'http://schemas.microsoft.com/xrm/2011/Contracts/Services/IOrganizationService/' . $operation;
1397 
1398  $headers = array (
1399  'Method: POST',
1400  'Connection: Keep-Alive',
1401  'User-Agent: PHP-SOAP-CURL',
1402  'Content-Type: text/xml; charset=utf-8',
1403  'SOAPAction: "' . $soap_action . '"'
1404  );
1405  return $headers;
1406  }
1407 
1417  private function array_key_exists_r($needle, $haystack) {
1418  $result = array_key_exists ( $needle, $haystack );
1419  if ($result)
1420  return $result;
1421  foreach ( $haystack as $v ) {
1422  if (is_array ( $v ) || is_object ( $v ))
1423  $result = $this->array_key_exists_r ( $needle, $v );
1424  if ($result)
1425  return $result;
1426  }
1427  return $result;
1428  }
1429 }
ParseKeyPair($data)
array_key_exists_r($needle, $haystack)
FormatAttribute($Param)
ParseDatas($Datas, $Return)
FormatFetchAttribute($Columns)
call($operation, $soapBody)
FormatColumn($Columns)
FormatCondition($Filter)
Assign($Table, $Id, $IdAssign, $TypeAssign='systemuser')
__construct($serv_adress, $user, $password)
RetrieveMultiple($Table, $Where, $Columns=false, $Join=false, $Order=false)
GetErrorObject($message)
SetState($Id, $Table, $StateCode, $StatusCode)
FormatFetchJoin($Joins)
setUser($user)
ParseRetrieve($xml, $Return)
setServAdress($serv_adress)
if(!b.support.opacity)
Definition: jquery.js:28
ParseRetrieveMultiple($xml, $Return)
TestParameter($Param, $field)
GenerateSoapHeader($operation)
FormatFetchOrder($Orders)
TestAgreggate($Param)
Retrieve($Table, $Id, $Columns)
Delete($Table, $Id)
ParseResultLine($Data)
TestParameters($Param, $Fields)
Workflow($EntityId, $WorkflowId)
setPassword($password)
FormatAttributes($Params)
Create($Table, $Params)
Result object for DynamicCRM.
Definition: CrmResponse.php:36
FormatFetchFilter($Filters)
Update($Table, $Params, $Id)
ExecuteBody($Request)
FormatFetchEntity($EntityName)