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

Accessible Laravel Package

delormejonathan/accessible

Accessible is a PHP library that uses docblock annotations to automate class behavior: generates getters/setters, validates setter arguments with Symfony Assert, initializes properties in constructors, and manages collections and associations with add/remove helpers.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup

  1. Installation

    composer require delormejonathan/accessible
    

    Add the Accessible trait to your model or class:

    use Delorme\Accessible\Accessible;
    
    class User extends Model
    {
        use Accessible;
    }
    
  2. Define Annotations Use PHPDoc annotations to control access to properties/methods:

    /**
     * @access public
     */
    public $name;
    
    /**
     * @access protected
     */
    public $email;
    
    /**
     * @access private
     */
    public $apiToken;
    
  3. First Use Case Access properties while respecting annotations:

    $user = new User();
    $user->name = 'John'; // Works (public)
    $user->email = '[email protected]'; // Throws exception (protected)
    

Where to Look First

  • Annotations Reference: Check src/Accessible.php for supported annotations (@access, @read-only, @write-only).
  • Exceptions: Review src/Exceptions/ for error handling (e.g., AccessDeniedException).
  • Testing: Run php artisan test (if included) or manually test edge cases.

Implementation Patterns

Workflows

  1. Model-Level Access Control Apply Accessible to Eloquent models to enforce business logic rules:

    class Order extends Model
    {
        use Accessible;
    
        /**
         * @access public
         * @read-only
         */
        public $total;
    
        /**
         * @access protected
         */
        public $customerId;
    }
    
    • Use Case: Prevent direct modification of total or customerId in controllers.
  2. Dynamic Property Access Use annotations to gate dynamic properties (e.g., API responses):

    class UserResource extends JsonResource
    {
        public function toArray($request)
        {
            $user = new User();
            return [
                'name' => $user->name, // Respects @access public
                'email' => $user->email, // Fails silently or throws
            ];
        }
    }
    
  3. Integration with Laravel Policies Combine with Laravel’s built-in policies for layered security:

    // Policy
    public function update(User $user, Order $order)
    {
        if ($order->customerId !== $user->id) {
            throw new AccessDeniedException("Cannot modify non-owned orders.");
        }
        return true;
    }
    

Tips for Daily Use

  • Batch Processing: Use Accessible::setAccessible() to temporarily override rules:
    Accessible::setAccessible($user, ['email'], 'public'); // Allow email writes
    
  • API Responses: Filter collections with accessible() helper:
    $filtered = collect($users)->map->accessible(['name', 'email']);
    
  • Testing: Mock annotations in unit tests:
    $user = new User();
    $user->setAccessibleProperty('email', 'public'); // Override for tests
    

Gotchas and Tips

Pitfalls

  1. Annotation Parsing Quirks

    • False Positives: Annotations on methods (not properties) are ignored. Ensure @access is on the property line.
    • Case Sensitivity: @Access (wrong case) will fail silently. Use @access.
    • Magic Methods: __get()/__set() bypass annotations. Avoid overriding these unless intentional.
  2. Performance Overhead

    • Annotations are parsed on every access by default. For high-traffic apps, cache the parser:
      $parser = new \Delorme\Accessible\Parser();
      $parser->parse($user); // Cache result if needed
      
  3. Laravel-Specific Issues

    • Serialized Models: Annotations are lost during serialization (e.g., session()). Re-parse after deserialization.
    • Mass Assignment: fill() ignores annotations. Use Accessible::fill() instead:
      $user->accessibleFill(['name' => 'John']); // Respects @access
      
  4. Edge Cases

    • Circular References: Annotations on nested objects (e.g., User->orders->items) may cause infinite loops. Use maxDepth in parser:
      $parser->setMaxDepth(2);
      

Debugging Tips

  • Enable Debugging: Set ACCESSIBLE_DEBUG=true in .env to log denied accesses.
  • Check Parser Output: Dump parsed rules:
    dd($user->getAccessibleProperties());
    
  • Override Defaults: Extend the Accessible trait to customize behavior:
    trait CustomAccessible extends Accessible
    {
        protected function onAccessDenied()
        {
            Log::warning("Access denied to {$this->property}");
            return null; // Silent fail
        }
    }
    

Extension Points

  1. Custom Annotations Extend the parser to support new annotations (e.g., @validate):

    // In a service provider
    $parser->addAnnotationHandler('validate', function ($value) {
        return validator()->make(['field' => $value], ['field' => 'required|email']);
    });
    
  2. Dynamic Access Control Use the Accessible::canAccess() method to implement runtime checks:

    if (Accessible::canAccess($user, 'email', 'write')) {
        $user->email = '[email protected]';
    }
    
  3. Integration with Laravel Events Trigger events on access attempts:

    Accessible::onAccessAttempt(function ($object, $property, $accessType) {
        event(new AccessAttempted($object, $property, $accessType));
    });
    
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.
calmfox/watch-sylius
damienfern/grpc-symfony-bundle
atoolo/index-bundle
atoolo/genai-bundle
coprotoai/laravel-ticket
davidjln/llm-carbon-bundle
cryonighter/valid-request-bundle
coolms/taxonomy-bundle
coolms/field-bundle
articulate-orm/symfony
aaix/laravel-tall-architect
ephoto/akeneo-connector
emmanuelballery/eb-plantumlbundle
emielburgman/symfony-visitor-beacon
emielburgman/symfony-visit-storage
emielburgman/symfony-security-headers
emielburgman/symfony-log-viewer
emarref/xdebug-bundle
emarref/pubnub-bundle
elriseio/finance-money-bundle