Installation:
composer require ahmed-ghiloubi/acl-bundle
Add to config/bundles.php:
return [
// ...
AhmedGhiloubi\AclBundle\AhmedGhiloubiAclBundle::class => ['all' => true],
];
Configuration: Publish the default config (optional):
php artisan vendor:publish --tag=acl-bundle-config
Update config/packages/ahmed_ghiloubi_acl.yaml if needed.
First Use Case:
Grant ownership to a user for a domain object (e.g., Post):
use AhmedGhiloubi\AclBundle\Manager\AclManager;
use Symfony\Component\Security\Core\User\UserInterface;
$aclManager = app(AclManager::class);
$user = auth()->user(); // Assuming Laravel's auth helper
$aclManager->manageObjectAces()
->grant($post, MaskBuilder::MASK_OWNER, $user);
Granting Permissions:
// Grant read/write access to a group
$aclManager->manageObjectAces()
->grant($post, MaskBuilder::MASK_READ | MaskBuilder::MASK_WRITE, $group);
Revocations:
$aclManager->manageObjectAces()
->revoke($post, MaskBuilder::MASK_OWNER, $user);
Bulk Operations:
$posts = Post::where('author_id', $user->id)->get();
$aclManager->manageObjectAces()->batchGrant($posts, MaskBuilder::MASK_OWNER, $user);
Middleware Integration: Use in a middleware to enforce ACLs:
public function handle($request, Closure $next)
{
$aclManager = app(AclManager::class);
if (!$aclManager->isGranted($request->post, MaskBuilder::MASK_READ, auth()->user())) {
abort(403);
}
return $next($request);
}
Event Listeners:
Automatically clean up ACLs when objects are deleted (via onKernelTerminate or Doctrine events):
$aclManager->cleanupOrphanedAcls();
Caching: ACLs are cached by default. Clear the cache after bulk operations:
php artisan cache:clear
Or manually:
$aclManager->getProvider()->clearCache();
Object Identity:
Ensure domain objects implement Serializable or use ObjectIdentity::fromDomainObject() explicitly. For custom objects:
$identity = ObjectIdentity::fromDomainObject($customObject, 'App\CustomObject');
$aclManager->manageObjectAces()->grant($identity, MaskBuilder::MASK_OWNER, $user);
Performance:
Avoid granting/revoking ACLs in loops. Batch operations (e.g., batchGrant) are more efficient.
Symfony vs. Laravel:
The bundle is Symfony-first. For Laravel, inject the AclManager via service providers:
$this->app->bind(AclManager::class, function ($app) {
return $app->make('projecta_acl.manager');
});
$acl = $aclManager->getProvider()->findAcl(ObjectIdentity::fromDomainObject($post));
dump($acl->getAces());
config/packages/ahmed_ghiloubi_acl.yaml:
logging: true
Custom Mask Builder:
Extend MaskBuilder for domain-specific permissions:
class PostMaskBuilder extends MaskBuilder
{
const MASK_PUBLISH = 0x8000;
}
Register as a service:
services:
App\Security\PostMaskBuilder:
tags: ['ahmed_ghiloubi_acl.mask_builder']
Event Subscribers: Listen for ACL changes:
use AhmedGhiloubi\AclBundle\Event\AclEvent;
public static function getSubscribedEvents()
{
return [
AclEvent::ACL_GRANTED => 'onAclGranted',
AclEvent::ACL_REVOKED => 'onAclRevoked',
];
}
Doctrine Integration:
Use the AclListener to auto-cleanup ACLs on entity deletion:
services:
AhmedGhiloubi\AclBundle\EventListener\AclListener:
tags:
- { name: doctrine.event_listener, event: onFlush }
How can I help you explore Laravel packages today?