ottosmops/oai-pmh
Laravel/PHP package that adds an OAI-PMH 2.0 data-provider endpoint to Laravel applications, making repository and digital-library records harvestable through standard verbs like Identify, ListMetadataFormats, ListRecords, and GetRecord, with configurable metadata formats and sets.
cursor/completeListSize, set hierarchy with descendant inclusion, three deleted-record modes, and two date granularities. That is a well-specified, low-differentiation surface with a compliance test suite behind it. Buy it; spend the engineering budget on metadata quality, which is where the actual product differentiation lives.OaiRepositoryContract (get, getRecordForId, getEarliestDatestamp) is a clean product boundary: the package owns the protocol, your team owns what a record is. That makes "which metadata formats do we expose, and in what fidelity?" a product conversation (Dublin Core as the floor, EAD/MARC/MODS/qualified DC as differentiators) rather than an engineering archaeology exercise.getEarliestDatestamp plus second-level granularity plus deleted-record modes means downstream partners can do delta harvests and stay in sync. That is a retention and partnership argument, not just a technical checkbox — it is what lets you tell an aggregator "you can harvest us nightly and not re-pull 200k records."composer require, publishable config, seven overridable Blade views. Worst case you spend days, not quarters, and the contract interface means your record-fetching logic stays yours if you ever swap the transport.Adopt when:
Look elsewhere or defer when:
Questions worth resolving before commitment: whether resumption tokens are stateless or persisted (affects horizontal scaling), how set membership is computed (query-time vs. materialised), and whether custom metadata formats can be added without forking the Blade views.
To executives: This is a small, reversible dependency that makes our content discoverable through the channels our peers and funders already use. Aggregators like Europeana, DPLA, and national library portals require OAI-PMH — a standardised harvesting protocol — and we currently cannot be harvested. Rather than fund a protocol build, we adopt a Laravel-native implementation that is already extracted from a production archive system and validated against the official specification schema. The cost is measured in days, the interface we must implement is three methods, and the strategic payoff is presence in external catalogues we do not have to build or maintain ourselves.
To engineering: The package owns the protocol surface — all six verbs, all eight error codes, resumption-token pagination with cursor and completeListSize, set hierarchy with descendant inclusion, deleted-record modes, and day/second date granularity — and ships an XSD-conformance suite covering every verb and error response. You implement OaiRepositoryContract: get, getRecordForId, getEarliestDatestamp. That is the entire coupling point; your record-fetching logic, models, and indexes are untouched and remain swappable. Config and seven Blade views are publishable, so XML output is customisable without forking. Supported on PHP 8.2–8.4 and Laravel 10–12. It is a server only — harvesting stays out of scope. Provenance is production: extracted from Anton, built with the Gosteli Archive.
One-line framing: We implement three methods; the package implements a standard we would otherwise spend a quarter getting subtly wrong.
How can I help you explore Laravel packages today?