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

Rad Laravel Package

21torr/rad

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation:

    composer require 21torr/rad
    

    Add the bundle to config/bundles.php:

    return [
        // ...
        RadBundle::class => ['all' => true],
    ];
    
  2. First Use Case: Use ApiResponse in a controller to standardize API responses:

    use Rad\ApiResponse;
    
    public function show(User $user): ApiResponse
    {
        return ApiResponse::ok($user);
    }
    
  3. Key Entry Points:


Implementation Patterns

Core Workflows

1. API Response Handling

  • Pattern: Use ApiResponse as a builder for consistent API responses.
  • Example:
    // Controller
    public function create(Request $request): ApiResponse
    {
        $data = $request->validate();
        $user = User::create($data);
    
        return ApiResponse::created($user, ['Location' => '/users/1']);
    }
    
  • Tip: Leverage ApiResponseNormalizer::createResponse() for nested data normalization.

2. Entity Management

  • Pattern: Use EntityModel for CRUD operations with Doctrine.
  • Example:
    // Service
    public function update(User $user, array $data): User
    {
        return EntityModel::update($user, $data, skipModified: true);
    }
    
  • Key Methods:
    • EntityModel::persist(): Unified add/edit.
    • EntityModel::refresh(): Reload entity from DB.

3. Data Import/Validation

  • Pattern: Use ImportData for robust data handling (e.g., CSV/JSON imports).
  • Example:
    $importData = ImportData::fromArray($rawData);
    $normalized = $importData->normalize(['field' => fn($v) => strtolower($v)]);
    
  • Features:
    • Auto-converts empty strings to null.
    • Supports nested arrays/objects.

4. Authorization

  • Pattern: Use AbilitiesVoter for attribute-based permissions.
  • Example:
    #[Can('edit', $user)]
    public function edit(User $user): ApiResponse { ... }
    
  • Integration:
    • Extend AbilitiesVoter to add custom attributes (e.g., @Can('delete')).

5. Translation

  • Pattern: Use TranslationHelper for dynamic translations.
  • Example:
    $helper = new TranslationHelper($translator);
    $message = $helper->translate('user.welcome', ['name' => $user->name]);
    

6. Request Handling

  • Pattern: Use ArgumentBag for typed request data.
  • Example:
    $bag = new ArgumentBag($request->all());
    $email = $bag->getString('email'); // Validates and casts
    

Integration Tips

Symfony Services

  • Dependency Injection: Autowire Rad\ApiResponse, Rad\EntityModel, etc.
    public function __construct(
        private EntityModel $entityModel,
        private TranslationHelper $translator
    ) {}
    

Doctrine Events

  • Change Tracking: Use DoctrineChangeChecker (deprecated in v3.4.5+) for pre-update validation:
    $changes = DoctrineChangeChecker::getEntityChanges($entityManager, $user);
    if ($changes->hasChanges()) {
        $this->denyAccessUnlessGranted('edit', $user);
    }
    

API Controllers

  • Base Controller: Extend Rad\BaseController for shared logic:
    class UserController extends BaseController
    {
        public function index(): ApiResponse
        {
            return $this->respondWith($this->userService->list());
        }
    }
    

Testing

  • Mocking: Use ApiResponse::mock() for unit tests:
    $mockResponse = ApiResponse::mock()->withData(['id' => 1]);
    $this->assertEquals(200, $mockResponse->getStatusCode());
    

Gotchas and Tips

Pitfalls

  1. Deprecated Features:

    • DoctrineChangeChecker is deprecated (v3.4.5+). Use custom logic or AbilitiesVoter instead.
    • Model class is removed (v3.0.0+). Use EntityModel or raw Doctrine.
  2. PHP Version:

    • Requires PHP 8.4+ (v3.4.0+). Downgrade if needed (e.g., for Symfony 6.2).
  3. Type Safety:

    • ArgumentBag throws exceptions for invalid types. Validate early:
      $bag->assertHas('email', 'string');
      
  4. Doctrine Quirks:

    • EntityModel::update() marks entities as modified by default. Use skipModified: true for bulk updates:
      EntityModel::update($entity, $data, skipModified: true);
      
  5. Translation Dependencies:

    • TranslationHelper requires symfony/translator. Install if missing:
      composer require symfony/translator
      

Debugging Tips

  1. API Responses:

    • Enable debug mode to log raw JSON failures:
      $this->container->getParameter('kernel.debug') // Check for debug logs
      
  2. Entity Changes:

    • Use DoctrineChangeChecker::getEntityChanges() (if not deprecated) to debug modified fields:
      dd(DoctrineChangeChecker::getEntityChanges($entityManager, $entity));
      
  3. ImportData:

    • Normalize data incrementally to catch issues early:
      $importData = ImportData::fromArray($rawData);
      $importData->normalize(['field' => fn($v) => $v ?? null]); // Handle nulls
      

Extension Points

  1. Custom Voters:

    • Extend AbilitiesVoter to add custom attributes:
      class CustomVoter extends AbilitiesVoter
      {
          protected function supports(string $attribute, $subject): bool
          {
              return in_array($attribute, ['custom:action']);
          }
      }
      
  2. ApiResponse Decorators:

    • Decorate ApiResponse to add middleware (e.g., logging):
      $response = ApiResponse::ok($data);
      $response->withHeader('X-Custom', 'value');
      
  3. EntityModel Hooks:

    • Override EntityModel methods for custom logic:
      class CustomEntityModel extends EntityModel
      {
          public static function persist(object $entity, array $data): object
          {
              // Add pre-persist logic
              return parent::persist($entity, $data);
          }
      }
      
  4. Translation Catalogs:

    • Extend TranslationHelper to support custom domains:
      $helper = new TranslationHelper($translator, 'custom_domain');
      

Configuration Quirks

  1. Optional Dependencies:

    • symfony/translator is optional. Explicitly require it if using TranslationHelper.
  2. Cache Invalidation:

    • InMemoryCache is not persistent. Use for short-lived data only.
  3. Id Fields:

    • Bundle defaults to unsigned int for IDs (v3.2.1+). Adjust Doctrine mappings if needed:
      # config/doctrine.yaml
      orm:
          mappings:
              App:
                  type: attribute
                  dir: '%kernel.project_dir%/src/Entity'
                  prefix: 'App\Entity'
                  alias: App
                  is_bundle: false
                  # Ensure unsigned int for IDs
                  id_generator:
                      strategy: UUID # or custom strategy
      
  4. Enum Support:

    • Use EnumValue helper for type-safe enums:
      $enumValue = EnumValue::from(UserRole::ADMIN);
      
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.
hamzi/corewatch
minionfactory/raw-hydrator
hexters/coinpayment
rjcodes/rjcms
act-training/laravel-permissions-manager
alimarchal/laravel-chart-of-accounts
babenkoivan/elastic-scout-driver
mkwebdesign/filament-watchdog-v5
renatomarinho/laravel-page-speed
zedmagdy/filament-business-hours
renatovdemoura/blade-elements-ui
devgeek/beacon-admin
benjamin-rqt/data-watcher-bundle
atriumphp/atrium
sandermuller/package-boost-laravel
sandermuller/boost-skills
redaxo/core
yusufgenc/filament-api-forge
l3aro/rating-star-for-filament
leek/filament-subtenant-scope