Skip to content

Tutorial

Pavel Selitskas edited this page May 7, 2018 · 12 revisions

On this page you can find a few samples of code using this toolkit.

Including Composer autoloader

Before you start using this library, you need to install it via Composer and include the generated autoloader into your application.

require_once 'vendor/autoload.php';

Creating the client instance

The library exposes a public API which includes an IOrganizationService-compatible Client. There are a few options to create a new instance of the client.

Use ClientFactory

ClientFactory provides a simple way to instantiate a new Client with all dependencies in place. As Dynamics 365 (online) is currently the only supported type of deployment, ClientFactory contains only one static method, ClientFactory::createOnlineClient. For IFD and On-Premises support please refer to Roadmap.

The minimal set of values you need to connect to Dynamics 365 Online is as follows:

  • Organization URI, e.g. https://contoso.crm.dynamics.com
  • Application ID - identifies the Azure AD application registration associated with your Dynamics 365 organization
  • Application Secret - a password generated in Settings / API Access / Keys section of your Azure AD application registration

Read this article (archive) to understand how to register a new app in Azure Active Directory and associate it with an application user in Dynamics 365.

Once you have all three items, it's time to create a new client:

$client = \AlexaCRM\WebAPI\ClientFactory::createOnlineClient(
    'https://contoso.crm.dynamics.com',
    '00000000-0000-0000-0000-000000000000',
    'Application Secret'
);

ClientFactory::createOnlineClient() accepts an optional fourth argument. The method expects a map with logger and cachePool keys which hold as values PSR-3 compliant logger and PSR-6 compliant cache adapter correspondingly.

The library follows the lazy initialization pattern and doesn't actually validate the connection at client initialization time. To see how to handle errors, see below.

Manual creation

Sometimes you may want to create all necessary objects yourself. One case when this is useful is when you need to specify extra options in the client settings.

Settings

The first step is to create a Settings object. For online deployments, use OnlineSettings.

$settings = new \AlexaCRM\WebAPI\OData\OnlineSettings();
$settings->instanceURI = 'https://contoso.crm.dynamics.com';
$settings->applicationID = '00000000-0000-0000-0000-000000000000';
$settings->applicationSecret = 'Application Secret';

You can optionally supply a PSR-3 compliant logger.

$settings->setLogger( $logger );

You can optionally supply a PSR-6 compliant cache adapter.

$settings->cachePool = $cacheAdapter;

By default, the HTTP client used by the library verifies SSL certificates against the local CA certificate bundle. If it is broken, like as what happens often on development environments in Windows and OS X, you can either supply a valid CA bundle or disable verification.

$settings->caBundle = false;
$settings->caBundle = '/path/to/ca-bundle.crt';

The default Web API version which the plugin connects to is 8.2. It is the minimal tested Web API version as well. (Although not tested, it might very well work with earlier versions, perhaps with some limitations.)

If you need to change the API version, it is also configured in the Settings object:

$settings->apiVersion = '9.0';

Authentication Middleware

The authentication process kicks in when the request is being made. For Online deployments, that means receiving an access token from Azure AD and putting it into the Authorization header of the request.

$middleware = new \AlexaCRM\WebAPI\OData\OnlineAuthMiddleware( $settings );

OData Client

Under the hood works a helper object that creates OData-compliant requests to the service endpoint. It consumes the Settings and AuthMiddlewareInterface objects.

$odataClient = new \AlexaCRM\WebAPI\OData\Client( $settings, $middleware );

Web API Client

The Web API Client class is compatible with IOrganizationService from the CRM SDK. To create one, you need to provide the OData client created earlier.

$client = new \AlexaCRM\WebAPI\Client( $odataClient );

After this step, the client is ready to make requests to Dynamics 365 Web API.

Making CRUD requests

Create a record

To create a new record in CRM, make an Entity object and pass it to the Client::Create() method.

$contact = new \AlexaCRM\Xrm\Entity( 'contact' );
$contact['firstname'] = 'Nancy';
$contact['lastname'] = 'Anderson';
$contact['emailaddress1'] = '[email protected]';

$contactId = $client->Create( $contact );

Retrieve a record

To retrieve a record, you need to specify its entity name, entity ID and a column set. Although you can retrieve all columns, it is strongly advised to select only necessary attributes for performance reasons, both at CRM and client side.

$retrievedContact = $client->Retrieve( 'contact', $contactId, new \AlexaCRM\Xrm\ColumnSet( [ 'fullname', 'emailaddress1' ] );

To retrieve all columns:

new \AlexaCRM\Xrm\ColumnSet( true )

Retrieve multiple records

Client::RetrieveMultiple() is used to retrieve multiple records from Dynamics 365. It supports FetchExpression and QueryByAttribute. QueryExpression is not currently supported. For advanced OData queries in Web API see below.

Client::RetrieveMultiple() returns an EntityCollection.

Fetching records via FetchExpression

Querying data with FetchXML is pretty straightforward. Use FetchExpression and supply a stringt with a FetchXML query.

$fetchXML = <<<FETCHXML
<fetch mapping="logical"> 
    <entity name="contact">
        <attribute name="accountid" /> 
        <attribute name="fullname" /> 
        <attribute name="emailaddress1" />
    </entity>
</fetch>
FETCHXML;

$fetchExpression = new \AlexaCRM\Xrm\Query\FetchExpression( $fetchXML );
$collection = $client->RetrieveMultiple( $fetchExpression );

Fetching records via QueryByAttribute

$query = new \AlexaCRM\Xrm\Query\QueryByAttribute( 'contact' );
$query->AddAttributeValue( 'lastname', 'Example' );
$query->AddOrder( 'firstname', \AlexaCRM\Xrm\Query\OrderType::Descending() );
$query->ColumnSet = new \AlexaCRM\Xrm\ColumnSet( [ 'fullname', 'emailaddress1' ] );
$collection = $client->RetrieveMultiple( $query );

Update a record

$record = new \AlexaCRM\Xrm\Entity( 'contact', '00000000-0000-0000-0000-000000000000' );
$record['emailaddress1'] = '[email protected]';
$client->Update( $record );

Delete a record

$client->Delete( 'contact', '00000000-0000-0000-0000-000000000000' );

Associating records

You can associate/disassociate records in two different ways: in a separate request (Associate and Disassociate) and during Create/Update.

Associate and Disassociate in a separate request

The example given below will associate the account record with three contact records by setting contact[parentcustomerid] lookup (Customer) attribute to the corresponding account lookup value.

$client->Associate(
    'account',
    '00000000-0000-0000-0000-000000000009',
    new \AlexaCRM\Xrm\Relationship( 'contact_customer_accounts' ),
    [
        new \AlexaCRM\Xrm\EntityReference( 'contact', '00000000-0000-0000-0000-000000000001' ),
        new \AlexaCRM\Xrm\EntityReference( 'contact', '00000000-0000-0000-0000-000000000002' ),
        new \AlexaCRM\Xrm\EntityReference( 'contact', '00000000-0000-0000-0000-000000000003' ),
    ]
);

Client::Associate() and Client::Disassociate() have the same signature.

Associate records on create/update

Dynamics 365 Web API allows you making associations between records during create/update request. When you prepare such a request, you need to know the corresponding navigation property for the given entity. In addition, lookup values with multiple targets like Customer lookups, require specifying different navigation properties for different entities (accounts and contacts for the Customer type).

This library does the heavy-lifting for you:

$contact = \AlexaCRM\Xrm\Entity( 'contact', '00000000-0000-0000-0000-000000000001' );

$contact['parentcustomerid'] = new \AlexaCRM\Xrm\EntityReference( 'account', '00000000-0000-0000-0000-000000000009' );
// or
$contact['parentcustomerid'] = new \AlexaCRM\Xrm\EntityReference( 'contact', '00000000-0000-0000-0000-000000000002' );

$client->Update( $contact );
Clone this wiki locally