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

Ldaprecord Laravel Package

directorytree/ldaprecord

LDAPRecord is a fully featured LDAP and Active Directory ORM for Laravel and PHP. It provides Eloquent-style models, querying, authentication and user sync, and tools for working with directory entries, connections, and schema—built for reliable, modern LDAP apps.

View on GitHub
Deep Wiki
Context7
## Getting Started

### Minimal Setup
1. **Installation**:
   ```bash
   composer require directorytree/ldaprecord

For Laravel integration:

composer require directorytree/ldaprecord-laravel
  1. Configuration: Publish the config file:

    php artisan vendor:publish --provider="DirectoryTree\LdapRecord\Laravel\LdapRecordServiceProvider"
    

    Update config/ldaprecord.php with your LDAP server details (host, port, base DN, etc.).

  2. First Use Case: Define an LDAP model (e.g., User.php):

    use DirectoryTree\LdapRecord\Laravel\Models\Model;
    
    class User extends Model
    {
        protected $connection = 'ldap'; // Matches config key
        protected $dn = 'ou=users,dc=example,dc=com';
        protected $attributes = [
            'uid', 'cn', 'mail', 'userPassword'
        ];
    }
    

    Query users:

    $users = User::where('uid', 'john.doe')->get();
    

Implementation Patterns

Core Workflows

  1. Model Definition: Extend DirectoryTree\LdapRecord\Laravel\Models\Model and define:

    • $connection: Config key for LDAP connection.
    • $dn: Base DN for the model.
    • $attributes: LDAP attributes to map to model properties.
    • $casts: Attribute casting (e.g., timestamps, booleans).

    Example:

    class Group extends Model
    {
        protected $connection = 'ad';
        protected $dn = 'ou=groups';
        protected $attributes = ['cn', 'member', 'description'];
        protected $casts = [
            'member' => 'array',
            'description' => 'string'
        ];
    }
    
  2. Querying: Use familiar Laravel-like syntax:

    // Basic query
    $users = User::where('mail', 'like', '%@example.com')->get();
    
    // Complex filters
    $activeUsers = User::where(function ($query) {
        $query->where('accountStatus', 'active')
              ->orWhere('lastLogin', '>', now()->subDays(30));
    })->get();
    
    // Active Directory-specific
    $adUsers = User::whereMemberOf('cn=Admins,ou=groups')->get();
    
  3. CRUD Operations:

    // Create
    $user = User::create([
        'uid' => 'jane.doe',
        'cn' => 'Jane Doe',
        'mail' => 'jane@example.com',
        'userPassword' => 'securepassword'
    ]);
    
    // Update
    $user->mail = 'jane.doe@example.com';
    $user->save();
    
    // Delete
    $user->delete();
    
  4. Relationships: Define relationships using hasMany, belongsTo, etc.:

    class User extends Model
    {
        public function groups()
        {
            return $this->belongsToMany(Group::class, 'member', 'uid', 'cn');
        }
    }
    
  5. Events & Observers: Use Laravel’s observer pattern for LDAP events:

    // app/Observers/UserObserver.php
    class UserObserver
    {
        public function saved(User $user)
        {
            Log::info("User created: {$user->uid}");
        }
    }
    

    Register in AppServiceProvider:

    User::observe(UserObserver::class);
    
  6. Authentication: Integrate with Laravel’s auth:

    use DirectoryTree\LdapRecord\Laravel\Auth\CanAuthenticate;
    
    class User extends Model implements CanAuthenticate
    {
        // ...
    }
    

    Configure AuthServiceProvider:

    public function boot()
    {
        $this->app['auth']->provider('ldap', function ($app) {
            return new LdapProvider($app['auth']->createUserProvider('eloquent'));
        });
    }
    
  7. Chunking & Pagination: Handle large result sets:

    User::chunk(100, function ($users) {
        foreach ($users as $user) {
            // Process batch
        }
    });
    
  8. Transactions: Wrap LDAP operations in transactions (where supported):

    DB::transaction(function () {
        $user = User::create([...]);
        $user->groups()->attach([...]);
    });
    

Integration Tips

  1. Laravel Service Container: Bind custom LDAP connections:

    $this->app->bind('ldap.ad', function () {
        return new Connection([
            'host' => 'ad.example.com',
            'port' => 636,
            'use_ssl' => true,
            'base_dn' => 'dc=example,dc=com',
        ]);
    });
    
  2. Caching: Cache frequent queries:

    $users = Cache::remember('active_users', now()->addHours(1), function () {
        return User::where('accountStatus', 'active')->get();
    });
    
  3. Testing: Use DirectoryFake for unit tests:

    use DirectoryTree\LdapRecord\Testing\DirectoryFake;
    
    public function test_user_creation()
    {
        DirectoryFake::fake();
        $user = User::create([...]);
        $this->assertEquals('john.doe', $user->uid);
        DirectoryFake::assertCreated('ou=users', $user->toArray());
    }
    
  4. Debugging: Enable debug logging in config/ldaprecord.php:

    'debug' => [
        'enabled' => env('LDAP_DEBUG', false),
        'level' => Ldap::DEBUG_ANY,
    ],
    

Gotchas and Tips

Pitfalls

  1. Base DN Substitution:

    • Always ensure {base} is used in queries when needed (e.g., whereMemberOf('cn=Admins,{base}')).
    • Avoid hardcoding full DNs in queries; use relative paths or {base} substitution.
  2. Attribute Casting:

    • Casting issues may arise with binary data (e.g., binaryGUID, objectSid). Use explicit casts:
      protected $casts = [
          'binaryGUID' => 'binary',
          'objectSid' => 'binary',
      ];
      
  3. TLS/SSL:

    • If using ldap:// without TLS, ensure allow_insecure_password_changes is configured in config/ldaprecord.php:
      'allow_insecure_password_changes' => env('LDAP_ALLOW_INSECURE_CHANGES', false),
      
  4. Empty whereIn Queries:

    • Passing an empty array to whereIn() will return no results (fixed in v3.8.5). Handle edge cases:
      $ids = $request->input('ids', []);
      if (!empty($ids)) {
          $users = User::whereIn('uid', $ids)->get();
      }
      
  5. Timestamp Handling:

    • Active Directory timestamps may have rounding errors. Use ldap timestamp type:
      protected $casts = [
          'lastLogin' => 'ldap:timestamp',
      ];
      
  6. Model Morphing:

    • Morphing by object classes requires explicit configuration:
      protected $morphMap = [
          'person' => User::class,
          'group' => Group::class,
      ];
      
  7. Connection Pooling:

    • LDAP connections are not automatically pooled. For high traffic, implement a connection manager or use LdapRecord\ConnectionPool.
  8. Debugging Complex Filters:

    • Use Ldap::DEBUG_FILTER to log generated LDAP filters:
      config(['ldaprecord.debug.level' => Ldap::DEBUG_FILTER]);
      

Debugging Tips

  1. Enable Debugging:

    // In a route or command
    \DirectoryTree\LdapRecord\Ldap::setDebugLevel(\DirectoryTree\LdapRecord\Ldap::DEBUG_ANY);
    
  2. Log Raw Queries: Use a custom logger to inspect queries:

    \Log::debug('LDAP Query', [
        'query' => $query->toLdap(),
        'params' => $query->getBindings(),
    ]);
    
  3. Handle Exceptions: Catch DirectoryTree\LdapRecord\Exceptions\LdapException for LDAP-specific errors:

    try {
        $user = User::find('nonexistent');
    } catch (\DirectoryTree\LdapRecord\Exceptions\LdapException $e) {
        Log::error("LDAP Error: {$e->getErrorMessage()}");
    }
    
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.
davejamesmiller/laravel-breadcrumbs
artisanry/parsedown
christhompsontldr/phpsdk
enqueue/dsn
bunny/bunny
enqueue/test
enqueue/null
enqueue/amqp-tools
milesj/emojibase
bower-asset/punycode
bower-asset/inputmask
bower-asset/jquery
bower-asset/yii2-pjax
laravel/nova
spatie/laravel-mailcoach
spatie/laravel-superseeder
laravel/liferaft
nst/json-test-suite
danielmiessler/sec-lists
jackalope/jackalope-transport