islandora/chullo
Chullo is a PHP 7.4+ client for the Fedora repository, built on Guzzle and EasyRdf. Create resources, fetch and modify RDF graphs, and save updates back to Fedora. Install via Composer and use in Islandora/Fedora integrations.
Installation:
composer require islandora/chullo:^1
Or via local clone (add to composer.json):
"repositories": [{
"type": "path",
"url": "/path/to/chullo"
}],
"require": {
"islandora/chullo": "^1"
}
First Use Case: Initialize the client and create a resource:
use Islandora\Chullo\Chullo;
$chullo = Chullo::create('http://localhost:8080/fcrepo/rest');
$uri = $chullo->createResource(); // Returns Fedora 4 URI (e.g., `/0b/0b/6c/68/...`)
Key Classes:
Chullo (main client)FedoraApi (legacy alias, use Chullo for new code)UuidGenerator (for UUID-based URIs)Resource CRUD:
// Create
$uri = $chullo->createResource();
// Read (as EasyRdf Graph)
$graph = $chullo->getGraph($uri);
// Update
$graph->set($uri, 'dc:title', 'New Title');
$chullo->saveGraph($uri, $graph);
// Delete
$chullo->deleteResource($uri);
Binary Operations:
// Upload binary (e.g., PDF)
$binaryUri = $chullo->createBinary($uri, 'file.pdf');
$chullo->uploadBinary($binaryUri, fopen('local.pdf', 'r'));
// Download binary
$content = $chullo->downloadBinary($binaryUri);
Transactions:
$txUri = $chullo->beginTransaction();
$chullo->extendTransaction($txUri); // Extend timeout
$chullo->commitTransaction($txUri);
Laravel Service Provider:
Bind Chullo to the container for dependency injection:
$this->app->singleton('chullo', function ($app) {
return Chullo::create(config('fedora.base_uri'));
});
EasyRdf Integration:
Use getGraph()/saveGraph() for RDF operations. Example:
$graph = $chullo->getGraph($uri);
$graph->addLiteral($uri, 'http://purl.org/dc/elements/1.1/description', 'Metadata');
$chullo->saveGraph($uri, $graph);
Error Handling:
Wrap calls in try-catch for GuzzleException:
try {
$chullo->deleteResource($uri);
} catch (GuzzleException $e) {
Log::error("Fedora error: " . $e->getMessage());
}
UUID vs. Path URIs:
createResource() returns a path URI (e.g., /0b/0b/6c/68/...), not a UUID.UuidGenerator if UUIDs are required:
$uuid = $chullo->getUuidGenerator()->generate();
$uri = $chullo->prepareUri($uuid); // Converts UUID to path URI
Binary Uploads:
uploadBinary() with a stream (e.g., fopen()) for large files.Content-Type) via getClient()->getConfig():
$chullo->getClient()->getConfig(['headers' => ['Content-Type' => 'application/pdf']]);
Transactions:
extendTransaction() for long operations.EasyRdf Quirks:
$graph->namespace('dc', 'http://purl.org/dc/elements/1.1/');
saveGraph() for updates; avoid manual JSON/XML serialization.Enable Guzzle Debugging:
$chullo->getClient()->getConfig(['debug' => true]);
Logs requests/responses to storage/logs/laravel.log.
Check HTTP Status Codes:
Fedora 4 returns 201 (created), 204 (no content), or 404 (not found). Handle accordingly:
if ($chullo->resourceExists($uri)) {
// Resource exists.
}
Custom Clients: Override the default Guzzle client:
$client = new \GuzzleHttp\Client(['base_uri' => 'http://fedora:8080/fcrepo/rest']);
$chullo = new Chullo($client);
Event Hooks:
Extend Chullo to trigger events (e.g., before/after save):
class ExtendedChullo extends Chullo {
public function saveGraph($uri, $graph) {
event('fedora.preSave', [$uri, $graph]);
parent::saveGraph($uri, $graph);
event('fedora.postSave', [$uri, $graph]);
}
}
Caching:
Cache UUID-to-path mappings (if using UuidGenerator) to reduce Fedora calls:
$cache = new \Symfony\Component\Cache\Adapter\FilesystemAdapter();
$chullo->setUuidCache($cache);
/fcrepo/rest (e.g., http://localhost:8080/fcrepo/rest).$chullo->getClient()->getConfig([
'headers' => ['Authorization' => 'Basic ' . base64_encode('user:pass')]
]);
$chullo->uploadBinary($binaryUri, fopen('large_file.pdf', 'r'));
How can I help you explore Laravel packages today?