Weave Code
Code Weaver
Helps Laravel developers discover, compare, and choose open-source packages. See popularity, security, maintainers, and scores at a glance to make better decisions.
Feedback
Share your thoughts, report bugs, or suggest improvements.
Subject
Message

Dynamics Crm Bundle Laravel Package

devigner/dynamics-crm-bundle

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require devigner/dynamics-crm-bundle
    

    Add to config/bundles.php:

    return [
        // ...
        Devigner\DynamicsCrmBundle\DevignerDynamicsCrmBundle::class => ['all' => true],
    ];
    
  2. Configuration Create config/packages/devigner_dynamics_crm.yaml:

    devigner_dynamics_crm:
        client_id: 'your_client_id'
        client_secret: 'your_client_secret'
        auth_url: 'https://login.microsoftonline.com/your_tenant_id/oauth2/token'
        api_url: 'https://yourorg.crm.dynamics.com/api/data/v9.2/'
    
  3. First Use Case: Fetching Accounts Inject the service in a controller:

    use Devigner\DynamicsCrmBundle\Service\DynamicsCrmService;
    
    class AccountController extends Controller
    {
        public function __construct(private DynamicsCrmService $crm)
        {
        }
    
        public function index()
        {
            $accounts = $this->crm->getRecords('accounts');
            return response()->json($accounts);
        }
    }
    

Key Files to Review

  • config/packages/devigner_dynamics_crm.yaml (configuration)
  • src/Service/DynamicsCrmService.php (core service)
  • src/DependencyInjection/ (bundle setup)

Implementation Patterns

Common Workflows

1. CRUD Operations

// Create
$account = $this->crm->createRecord('accounts', [
    'name' => 'Test Account',
    'revenue' => 100000
]);

// Read
$account = $this->crm->getRecord('accounts', $accountId);

// Update
$this->crm->updateRecord('accounts', $accountId, ['name' => 'Updated Name']);

// Delete
$this->crm->deleteRecord('accounts', $accountId);

2. Querying with OData Filters

// Filter accounts by name
$accounts = $this->crm->getRecords('accounts', [
    '$filter' => "name eq 'Test Account'"
]);

// Paging
$accounts = $this->crm->getRecords('accounts', [
    '$top' => 10,
    '$skip' => 20
]);

3. Relationships

// Fetch contacts for an account
$contacts = $this->crm->getRelatedRecords('accounts', $accountId, 'contacts');

// Link a contact to an account
$this->crm->createRelationship('accounts', $accountId, 'contacts', $contactId);

4. Bulk Operations

$this->crm->bulkCreateRecords('accounts', [
    ['name' => 'Account 1'],
    ['name' => 'Account 2']
]);

Integration Tips

  • Authentication: Use Symfony’s ParameterBag or environment variables for sensitive credentials.
  • Error Handling: Wrap CRM calls in try-catch blocks to handle DynamicsCrmException.
  • Caching: Cache frequent queries (e.g., dropdown lists) using Symfony’s cache component.
  • Logging: Enable logging in config/packages/devigner_dynamics_crm.yaml for debugging:
    devigner_dynamics_crm:
        logging: true
    

Gotchas and Tips

Pitfalls

  1. Deprecated API Version

    • The bundle uses v9.2 by default. If your CRM instance uses a newer version, update api_url in config.
    • Fix: Check your CRM’s API version and adjust the URL (e.g., v9.2/v10.0/).
  2. Authentication Failures

    • Hardcoded credentials in config may fail silently. Use Symfony’s env() helper:
      client_id: '%env(DYNAMICS_CRM_CLIENT_ID)%'
      
    • Debug: Enable logging (logging: true) and check var/log/dev.log.
  3. OData Query Limits

    • Dynamics CRM enforces query limits (e.g., $top max 5000). Exceeding limits returns empty results.
    • Fix: Use pagination ($skip/$top) for large datasets.
  4. Case Sensitivity in Filters

    • Filters like $filter are case-sensitive for unique identifiers (e.g., accountid). Use exact matches:
      '$filter' => "accountid eq '00000000-0000-0000-0000-000000000000'"
      
  5. Missing Response Handling

    • The bundle may not handle all CRM response formats (e.g., errors in @odata.context). Validate responses:
      try {
          $data = $this->crm->getRecord('accounts', $id);
      } catch (\Exception $e) {
          if (strpos($e->getMessage(), 'Invalid entity') !== false) {
              // Handle invalid entity
          }
      }
      

Tips

  1. Use Entity Metadata Fetch entity metadata to discover available fields/relationships:

    $metadata = $this->crm->getMetadata('accounts');
    
  2. Leverage Webhooks (Advanced) For real-time updates, use Dynamics CRM’s webhook system alongside this bundle. Store webhook secrets in Symfony’s security.yaml.

  3. Testing Mock DynamicsCrmService in PHPUnit:

    $mock = $this->createMock(DynamicsCrmService::class);
    $mock->method('getRecord')->willReturn(['name' => 'Test']);
    $this->instance(DynamicsCrmService::class, $mock);
    
  4. Performance

    • Batch requests where possible (e.g., bulkCreateRecords).
    • Avoid fetching unnecessary fields (use $select in queries):
      $this->crm->getRecords('accounts', ['$select' => 'name,revenue']);
      
  5. Extension Points

    • Override the service by binding your own implementation in services.yaml:
      services:
          App\Service\CustomCrmService:
              decorates: 'devigner_dynamics_crm.service.crm'
              arguments: ['@devigner_dynamics_crm.service.crm']
      
Weaver

How can I help you explore Laravel packages today?

Conversation history is not saved when not logged in.
Prompt
Add packages to context
No packages found.
anousss007/vigilance
supportpal/eloquent-model
ardenexal/fhir-models
laravel-at/laravel-image-sanitize
romalytar/yammi-audit-log-laravel
ardenexal/fhir-validation
arshaviras/weather-widget
laravel-chronicle/core
sunchayn/nimbus
daikazu/eloquent-salesforce-objects
unseen-codes/chat
romalytar/yammi-jobs-monitoring-laravel
kisame76/filament-db-table-state
nqxcode/laravel-lucene-search
dpfx/laravel-livewire-wizards
workos/workos-php-laravel
sofa/laravel-global-scope
nawasara/auth-primitives
adhocrat-io/arkhe-main
make-dev/orca-harpoon