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

Jackalope Jackrabbit Laravel Package

jackalope/jackalope-jackrabbit

PHPCR storage backend for Jackalope using Apache Jackrabbit. Provides a Jackrabbit-specific transport/implementation so PHPCR applications can connect to and work with Jackrabbit repositories via Jackalope.

View on GitHub
Deep Wiki
Context7

Getting Started

Minimal Setup in Laravel

  1. Install the Package

    composer require jackalope/jackalope-jackrabbit
    

    Ensure jackalope/jackalope is also installed (core PHPCR implementation).

  2. Configure Jackrabbit Connection Add a config entry in config/filesystems.php (or a custom config file):

    'jackrabbit' => [
        'driver' => 'jackalope',
        'client' => [
            'class' => \Jackalope\Transport\WebDAV\Client::class,
            'uri' => env('JACKRABBIT_WEBDAV_URI', 'http://localhost:8080/server'),
            'username' => env('JACKRABBIT_USERNAME', 'admin'),
            'password' => env('JACKRABBIT_PASSWORD', 'admin'),
        ],
        'repository' => [
            'class' => \Jackalope\Repository\RepositoryFactory::class,
            'transport' => 'client',
        ],
    ],
    
  3. First Use Case: Fetching a Node

    use Jackalope\Repository\RepositoryFactory;
    use Jackalope\Transport\WebDAV\Client;
    
    $client = new Client(env('JACKRABBIT_WEBDAV_URI'), env('JACKRABBIT_USERNAME'), env('JACKRABBIT_PASSWORD'));
    $repository = RepositoryFactory::createRepository($client);
    $session = $repository->login();
    
    $node = $session->getNode('/'); // Root node
    $children = $node->getNodes(); // List children
    

Implementation Patterns

Workflow: CRUD Operations

  1. Create a Node

    $parent = $session->getNode('/content');
    $newNode = $parent->addNode('article', 'nt:unstructured');
    $newNode->setProperty('title', 'My Article');
    $session->save();
    
  2. Querying with JCR-SQL2

    $query = $session->createQuery(
        "SELECT * FROM [nt:base] AS node WHERE ISDESCENDANTNODE(node, '/content')",
        \PHPCR\Query\Query::JCR_SQL2
    );
    $result = $query->execute();
    foreach ($result as $hit) {
        echo $hit->getPath() . "\n";
    }
    
  3. Bulk Operations with Transactions

    $session->beginTransaction();
    try {
        $node = $session->getNode('/content');
        $node->setProperty('last_updated', new \DateTime());
        $session->save();
        $session->commit();
    } catch (\Exception $e) {
        $session->rollback();
        throw $e;
    }
    

Integration with Laravel

  • Service Provider Binding Bind the repository in AppServiceProvider:

    public function register()
    {
        $this->app->singleton(\Jackalope\Repository\RepositoryInterface::class, function ($app) {
            $client = new Client(config('jackrabbit.client.uri'), config('jackrabbit.client.username'), config('jackrabbit.client.password'));
            return RepositoryFactory::createRepository($client);
        });
    }
    
  • Eloquent-like Repository Facade Create a facade for cleaner usage:

    // app/Facades/Jackrabbit.php
    namespace App\Facades;
    
    use Illuminate\Support\Facades\Facade;
    
    class Jackrabbit extends Facade
    {
        protected static function getFacadeAccessor() { return \Jackalope\Repository\RepositoryInterface::class; }
    }
    

    Usage:

    $node = Jackrabbit::getSession()->getNode('/content');
    

Event Listeners for Node Changes

Leverage PHPCR events to trigger Laravel events:

$session->addListener(new class implements \PHPCR\Event\EventListener {
    public function handleEvent(\PHPCR\Event\Event $event) {
        if ($event->getType() === \PHPCR\Event\Event::NODE_ADDED) {
            event(new \App\Events\NodeCreated($event->getNode()));
        }
    }
});

Gotchas and Tips

Pitfalls

  1. WebDAV vs. DAVex

    • Jackrabbit may expose either WebDAV (basic) or DAVex (JCR-specific). Ensure your client (WebDAV\Client) matches the server’s endpoint.
    • Debug with curl -v http://your-jackrabbit/dav/ to verify the protocol.
  2. Session Management

    • Always close sessions to avoid leaks:
      $session->logout();
      
    • Laravel’s service container may not auto-close sessions. Use a context manager or middleware to handle this.
  3. Property Types

    • PHPCR/JCR has strict types (e.g., Date, Binary). Cast values explicitly:
      $node->setProperty('date', new \DateTime('now'), \PHPCR\PropertyType::DATE);
      
  4. Performance with Large Repositories

    • Fetch nodes lazily to avoid memory issues:
      $nodeIterator = $session->getNode('/')->getNodes();
      foreach ($nodeIterator as $node) { /* ... */ }
      

Debugging

  • Enable Jackalope Logging Add to config/logging.php:

    'channels' => [
        'jackalope' => [
            'driver' => 'single',
            'path' => storage_path('logs/jackalope.log'),
            'level' => 'debug',
        ],
    ],
    

    Then configure the client:

    $client = new Client(..., null, null, [
        'logger' => \Monolog\Logger::getInstance('jackalope'),
    ]);
    
  • Common Errors

    • No such node: Verify paths are case-sensitive and absolute (e.g., /content, not content).
    • Unauthorized: Check credentials and Jackrabbit’s repository.xml for access rules.
    • Transport error: Ensure Jackrabbit’s WebDAV/DAVex port (default: 8080) is open and CORS is configured if accessing remotely.

Extension Points

  1. Custom Node Types Extend Jackrabbit’s node types via nodeType.xml (server-side) or use PHPCR’s dynamic types:

    $node->setPrimaryType('my:customType');
    
  2. Caching Cache sessions or node queries (e.g., with Laravel’s cache):

    $cacheKey = 'jackrabbit:node:/content';
    $node = cache($cacheKey, function () use ($session) {
        return $session->getNode('/content');
    }, now()->addMinutes(5));
    
  3. Async Operations Use Laravel Queues for long-running operations (e.g., bulk imports):

    dispatch(new ImportNodesJob($session, $nodes));
    
  4. Testing Spin up a local Jackrabbit instance for tests:

    docker run -p 8080:8080 -e REPO_HOME=/tmp/repository jackrabbit
    

    Use Laravel’s DatabaseMigrations pattern to reset the repo between tests.

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.
terminal42/code-quality-tools
codifyo/ts-generator-bundle
andydefer/laravel-cluster
testo/fiber
mintobit/jobqueue
a4sex/maintenance-bundle
a4sex/entity-date-update
a4sex/client-identifier
a4sex/base-utilites
a4sex/key-value-storage
a4sex/micro-status
chilldev/dependency-injection-extra
datinglibre/datinglibre-app-api
biberltd/corebundle
bricre/symfony-bundle-test
biberltd/logbundle
dominium/http-adapter-bundle
dominium/google-analytics
a4sex/auto-clean-entity
christhompsontldr/laravel-inky