Installation:
composer require artox-lab/clarc-bundle
Enable the bundle in config/bundles.php:
ArtoxLab\Bundle\ClarcBundle\ArtoxLabClarcBundle::class => ['all' => true],
Basic Configuration (config/packages/artox_lab_clarc.yaml):
artox_lab_clarc:
api:
serializer:
class: \ArtoxLab\Bundle\ClarcBundle\Core\Interfaces\UI\API\Transformers\Serializers\NullObjectArraySerializer
security:
rbac:
permissions:
ROLE_MAINTAINER:
- show
First Use Case: RBAC Permissions Check
Inject AuthorizationChecker in a controller:
use ArtoxLab\Bundle\ClarcBundle\Core\Entity\Security\AuthorizationChecker;
class SomeController {
public function __construct(private AuthorizationChecker $authorizationChecker) {}
public function index() {
if (!$this->authorizationChecker->isGranted('show')) {
throw new AccessDeniedException();
}
// ...
}
}
Workflow:
artox_lab_clarc.yaml under security.rbac.permissions.security.yaml:
access_control:
- { path: ^/admin, roles: ROLE_MAINTAINER }
$this->authorizationChecker->isGranted('permission_name');
# config/routes.yaml
artox_lab_clarc_bundle_user_permissions:
path: /v1/user/permissions
controller: ArtoxLab\Bundle\ClarcBundle\Core\Interfaces\UI\API\Controllers\PermissionController::permissions
Integration Tip:
Use IS_AUTHENTICATED_FULLY for API routes requiring authentication.
Workflow:
artox_lab_clarc.navigation.left_menu:
left_menu:
items:
- icon: dashboard
title: Dashboard
permissions: dashboard.view
children:
- link: /dashboard/analytics
title: Analytics
permissions: analytics.view
# config/routes.yaml
artox_lab_admin_user_navigations:
path: /user/navigations
controller: ArtoxLab\Bundle\ClarcBundle\Core\Interfaces\UI\API\Controllers\NavigationController::userNavigation
GET /user/navigations (permissions auto-filter items).Integration Tip:
Use show_orphaned_root: true to display root-level items without children.
Workflow for Async Communication:
Producer Setup:
artox-lab/example-protobuf-messages).messenger.yaml:
framework:
messenger:
transports:
broadcasting:
dsn: '%env(BROADCASTING_MESSENGER_TRANSPORT_DSN)%'
serializer: artox_lab_clarc.messenger.transport.serializer.protobuf_self_origin_stamps
routing:
'Google\Protobuf\Internal\Message': broadcasting
BroadcastingBus:
$this->broadcastingBus->dispatch(new \ArtoxLab\ExampleMessage\V1\Order\Created());
Consumer Setup:
#[AsMessageHandler]
class OrderCreatedHandler {
public function __invoke(Order\Created $message) {
// Process message
}
}
php bin/console messenger:consume listening
Integration Tips:
listening.bus for external messages (pre-configured in the bundle).failure_listening:
dsn: doctrine://default
serializer: artox_lab_clarc.messenger.transport.serializer.protobuf
Usage:
CommandBus for write operations.QueryBus for read operations.EventBus for async workflows.// Command
$this->commandBus->dispatch(new CreateCompanyCommand());
// Query
$result = $this->queryBus->ask(new GetCompanyQuery($id));
// Event
$this->eventBus->dispatch(new CompanyCreatedEvent($company));
Integration Tip:
Extend AbstractApiController for auto-injected buses:
class CompanyController extends AbstractApiController {
public function create(CreateCompanyCommand $command) {
$this->commandBus->dispatch($command);
// ...
}
}
AuthorizationChecker caches permissions. Clear cache after dynamic role updates:
php bin/console cache:clear
security.yaml before using them in artox_lab_clarc.yaml:
security:
role_hierarchy:
ROLE_ADMIN: [ROLE_MAINTAINER, ROLE_USER]
protobuf_self_origin_stamps serializer validates message origin. Ensure messages include a @type annotation to avoid validation errors.php bin/console messenger:consume listening -vv
.env for transport DSNs (e.g., BROADCASTING_MESSENGER_TRANSPORT_DSN). Avoid hardcoding credentials./user/navigations. Ensure permissions are correctly defined in the config.security.yaml:
access_control:
- { path: ^/user/navigations, roles: IS_AUTHENTICATED_FULLY }
# config/packages/messenger.yaml
framework:
messenger:
buses:
command.bus:
middleware:
- artox_lab_clarc.messenger.middleware.validation
- your_custom_middleware
DomainHttpException for HTTP-friendly errors in domain logic:
throw new DomainHttpException(403, 'Permission denied');
php bin/console messenger:consume listening -vv
dump($this->authorizationChecker->getUserPermissions());
protoc:
protoc --php_out=. path/to/message.proto
NullObjectArraySerializer for custom API responses:
class CustomSerializer implements SerializerInterface {
public function serialize($data): array {
// Custom logic
}
}
Register in artox_lab_clarc.api.serializer.class.messenger.yaml:
framework:
messenger:
buses:
command.bus:
middleware:
- your_namespace.middleware
composer require artox-lab/example-protobuf-messages
How can I help you explore Laravel packages today?