jackalope/jackalope-fs
Filesystem-based PHPCR Jackalope backend. Stores repository content in flat files, useful for local development, demos, and lightweight setups where a full database backend isn’t needed. Provides a simple way to run PHPCR without extra infrastructure.
Installation Add the package via Composer:
composer require jackalope/jackalope-fs
Ensure you have jackalope/jackalope installed (dependency):
composer require jackalope/jackalope
Basic Usage Initialize the filesystem adapter:
use Jackalope\Filesystem\Filesystem;
use Jackalope\Filesystem\FilesystemAdapter;
$adapter = new FilesystemAdapter('/path/to/your/filesystem');
$filesystem = new Filesystem($adapter);
First Use Case: File Operations Test basic CRUD operations:
// Create a file
$filesystem->createFile('/test.txt')->setContent('Hello, Jackalope!');
// Read a file
$content = $filesystem->getNode('/test.txt')->getContent();
// Check if a file exists
$exists = $filesystem->nodeExists('/test.txt');
Integration with Laravel Filesystem
Use the adapter as a drop-in replacement for Laravel’s Filesystem contract:
use Illuminate\Contracts\Filesystem\Filesystem as LaravelFilesystem;
$adapter = new FilesystemAdapter(storage_path('app'));
$laravelFilesystem = new LaravelFilesystem($adapter);
Node Traversal Recursively list files/directories:
foreach ($filesystem->getNode('/')->getChildren() as $child) {
if ($child->isFile()) {
// Handle file
}
}
Event-Driven Operations
Hook into preSetContent/postSetContent for logging/auditing:
$filesystem->getNode('/file.txt')->setContent('data', function ($node) {
// Pre-operation logic
});
Service Provider Binding
Bind the adapter in AppServiceProvider:
$this->app->bind(
\Jackalope\Filesystem\Filesystem::class,
fn() => new Filesystem(new FilesystemAdapter(storage_path('app')))
);
Configuration
Store filesystem paths in .env:
JACKALOPE_PATH=/custom/path
Access via:
$adapter = new FilesystemAdapter(config('jackalope.path'));
Case Sensitivity
The adapter respects OS-level case sensitivity (e.g., /File.txt ≠ /file.txt on Linux).
Fix: Normalize paths or use strtolower() for comparisons.
Permission Handling
PHP’s FilesystemIterator may fail silently on restricted directories.
Fix: Use FilesystemAdapter::checkAccess() before operations.
Symbolic Links The adapter follows symlinks by default. Disable with:
$adapter = new FilesystemAdapter('/path', false);
Node Existence Checks
Use nodeExists() before operations to avoid NodeNotFoundException:
if (!$filesystem->nodeExists('/nonexistent')) {
$filesystem->createNode('/nonexistent');
}
Content Encoding Ensure content is UTF-8 encoded to avoid corruption when reading/writing.
Custom Node Types
Extend Jackalope\Filesystem\NodeInterface for domain-specific logic:
class CustomNode implements NodeInterface {
public function getMetadata() { ... }
}
Adapter Wrappers
Decorate FilesystemAdapter to add caching or logging:
class LoggingAdapter implements FilesystemAdapterInterface {
protected $adapter;
public function __construct(FilesystemAdapter $adapter) {
$this->adapter = $adapter;
}
public function get($uri) {
Log::debug("Accessing: $uri");
return $this->adapter->get($uri);
}
}
Event Listeners
Use Jackalope\Filesystem\EventDispatcher to trigger events:
$dispatcher = new EventDispatcher();
$filesystem = new Filesystem($adapter, $dispatcher);
$dispatcher->addListener('node.set_content', function ($event) {
// Handle content changes
});
How can I help you explore Laravel packages today?