PHPackages                             kiwilan/php-opds - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [API Development](/categories/api)
4. /
5. kiwilan/php-opds

ActiveLibrary[API Development](/categories/api)

kiwilan/php-opds
================

PHP package to create OPDS feed for eBooks.

2.2.0(11mo ago)104.9k3[3 PRs](https://github.com/kiwilan/php-opds/pulls)1MITPHPPHP ^8.1CI passing

Since May 9Pushed 4mo agoCompare

[ Source](https://github.com/kiwilan/php-opds)[ Packagist](https://packagist.org/packages/kiwilan/php-opds)[ Docs](https://github.com/kiwilan/php-opds)[ GitHub Sponsors](https://github.com/kiwilan)[ RSS](/packages/kiwilan-php-opds/feed)WikiDiscussions main Synced 1mo ago

READMEChangelog (10)Dependencies (8)Versions (34)Used By (1)

PHP OPDS
========

[](#php-opds)

[![Banner with woman with eReader picture in background and PHP OPDS title](https://raw.githubusercontent.com/kiwilan/php-opds/main/docs/banner.jpg)](https://raw.githubusercontent.com/kiwilan/php-opds/main/docs/banner.jpg)

[![php](https://camo.githubusercontent.com/2d44ab343cf5a2aab849b6954ee31dd09ba1f1f11bf0f168ccd08e186ec060b1/68747470733a2f2f696d672e736869656c64732e696f2f7374617469632f76313f7374796c653d666c6174266c6162656c3d504850266d6573736167653d76382e3126636f6c6f723d373737424234266c6f676f3d706870266c6f676f436f6c6f723d666666666666266c6162656c436f6c6f723d313831383162)](https://www.php.net/)[![version](https://camo.githubusercontent.com/debbe2366551a963dd7e76aee3332a03faec6ed2cb0b30ba861be7667d330f61/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f6b6977696c616e2f7068702d6f7064732e7376673f7374796c653d666c617426636f6c6f72413d31383138314226636f6c6f72423d373737424234)](https://packagist.org/packages/kiwilan/php-opds)[![downloads](https://camo.githubusercontent.com/e4f124c211e16e22faa3286a84b0d7c9384a8659ec4c8df1c8f9ddefcece5ca8/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f64742f6b6977696c616e2f7068702d6f7064732e7376673f7374796c653d666c617426636f6c6f72413d31383138314226636f6c6f72423d373737424234)](https://packagist.org/packages/kiwilan/php-opds)[![license](https://camo.githubusercontent.com/70d1d34bf2fd5b5860690f57a3ee7ee383f10400be76d7c63e635db5a6368fbe/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6c6963656e73652f6b6977696c616e2f7068702d6f7064732e7376673f7374796c653d666c617426636f6c6f72413d31383138314226636f6c6f72423d373737424234)](https://github.com/kiwilan/php-opds/blob/main/README.md)[![tests](https://camo.githubusercontent.com/4deb17740da4b981bc594fbe55d1076d2dabe046bb7e8615b062976f985009fb/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f616374696f6e732f776f726b666c6f772f7374617475732f6b6977696c616e2f7068702d6f7064732f72756e2d74657374732e796d6c3f6272616e63683d6d61696e266c6162656c3d7465737473267374796c653d666c617426636f6c6f72413d313831383142)](https://packagist.org/packages/kiwilan/php-opds)[![codecov](https://camo.githubusercontent.com/79ab8733ac13314c08d05056483375bb74a3e122aa1e39d0c995d3d71d7c3ad8/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f67682f6b6977696c616e2f7068702d6f7064732f6d61696e3f7374796c653d666c617426636f6c6f72413d31383138314226636f6c6f72423d373737424234)](https://codecov.io/gh/kiwilan/php-opds)

PHP package to create [OPDS feed](https://opds.io/) (Open Publication Distribution System) for eBooks.

- **Demo**:  from [`bookshelves-project/bookshelves`](https://github.com/bookshelves-project/bookshelves)

VersionSupportedDateFormatQuery param1.2✅November 11, 2018XML`?v=1.2`2.0✅DraftJSON`?v=2.0`All old versions: 0.9, 1.0 and 1.1 have a fallback to OPDS 1.2.

Requirements
------------

[](#requirements)

- `php` v8.1 minimum

About
-----

[](#about)

OPDS is like RSS feeds but adapted for eBooks, it's a standard to share eBooks between libraries, bookstores, publishers, and readers. Developed by [Hadrien Gardeur](https://github.com/HadrienGardeur) and [Leonard Richardson](https://github.com/leonardr).

This package has been created to be used with [`bookshelves-project/bookshelves`](https://github.com/bookshelves-project/bookshelves), an open source eBook web app.

Note

The Open Publication Distribution System (OPDS) catalog format is a syndication format for electronic publications based on Atom and HTTP. OPDS catalogs enable the aggregation, distribution, discovery, and acquisition of electronic publications. OPDS catalogs use existing or emergent open standards and conventions, with a priority on simplicity.

The Open Publication Distribution System specification is prepared by an informal grouping of partners, combining Internet Archive, O'Reilly Media, Feedbooks, OLPC, and others.

From [Wikipedia](https://en.wikipedia.org/wiki/Open_Publication_Distribution_System)

Some resources about OPDS and eBooks:

- [opds.io](https://opds.io/): OPDS official website
- OPDS feeds examples
    - [bookshelves.ink](https://bookshelves.ink/opds): Bookshelves (eBook web app, which use `kiwilan/php-opds`)
    - [gallica.bnf.fr](https://gallica.bnf.fr/opds): Gallica (French National Library)
    - [cops-demo.slucas.fr](https://cops-demo.slucas.fr/feed.php): COPS (OPDS PHP Server)
    - [feedbooks.com](https://catalog.feedbooks.com/catalog/public_domain.atom): Feedbooks
- [`kiwilan/php-ebook`](https://github.com/kiwilan/php-ebook): PHP package to handle eBook
- [`koreader/koreader`](https://github.com/koreader/koreader): eBook reader for Android, iOS, Kindle, Kobo, Linux, macOS, Windows, and more. If your eReader can't use OPDS feeds, you can install KOReader on it
- [`edrlab/thorium-reader`](https://github.com/edrlab/thorium-reader): A cross platform desktop reading app, based on the Readium Desktop toolkit. You can use it to use OPDS feeds and read eBooks

Features
--------

[](#features)

- ⚛️ Generate OPDS XML and JSON feed (navigation feeds and acquisition feeds)
- 👌 Support OPDS 1.2 and 2.0
- 🔖 With pagination option
- 🔍 Search page included, but NOT search engine
- 🌐 Option to handle response to browser as XML or JSON

### Roadmap

[](#roadmap)

- OPDS 1.2: support advanced acquisition feeds
- OPDS 2.0: support `Facets`, `Groups`, advanced `belongsTo`
- Add [OPDS Page Streaming Extension](https://github.com/anansi-project/opds-pse) from `anansi-project`

Installation
------------

[](#installation)

You can install the package via composer:

```
composer require kiwilan/php-opds
```

Usage
-----

[](#usage)

You have to use `Opds::make()` method to create an OPDS instance, the only param is `config` to set OPDS config, totally optional. Default response is XML with OPDS version 1.2, you can force JSON response with `OpdsConfig::class` method `forceJson()` to use only OPDS 2.0. With `get()` method, you can get full instance of `Opds` with `OpdsEngine` and `OpdsResponse`.

```
use Kiwilan\Opds\Opds;
use Kiwilan\Opds\OpdsConfig;

$opds = Opds::make(new OpdsConfig()) // OpdsConfig::class, optional
  ->title('My feed')
  ->feeds([...]) // OpdsEntryNavigation[]|OpdsEntryBook[]|OpdsEntryNavigation|OpdsEntryBook
  ->get()
;
```

You have different informations into `Opds::class`.

Some informations about OPDS instance:

```
use Kiwilan\Opds\Opds;

$opds = Opds::make()
  ->title('My feed')
  ->feeds([...])
  ->get()
;

$opds->getConfig(); // OpdsConfig - Configuration used to create OPDS feed set into `make()` method
$opds->getUrl(); // string|null - Current URL, generated automatically but can be overrided with `url()` method
$opds->getTitle(); // string - Title of OPDS feed set with `title()` method
$opds->getVersion(); // OpdsVersionEnum - OPDS version used, determined by query parameter `v` or `OpdsConfig::class` method `forceJson()`
$opds->getQueryVersion(); // OpdsVersionEnum|null - Name of query parameter used to set OPDS version, default is `v`
$opds->getUrlParts(); // array - URL parts, determined from `url`
$opds->getQuery(); // array - Query parameters, determined from `url`
$opds->getFeeds(); // array - Feeds set with `feeds()` method
$opds->checkIfSearch(); // bool, default is false, set to true if `isSearch()` method is used
```

And about engine and response:

```
use Kiwilan\Opds\Opds;

$opds = Opds::make()
  ->title('My feed')
  ->feeds([...])
  ->get()
;

$opds->getEngine(); // OpdsEngine|null - Engine used to create OPDS feed, determined by OPDS version, can be `OpdsXmlEngine::class` or `OpdsJsonEngine::class`
$opds->getOutput(); // OpdsOutputEnum|null - Output of response, useful for debug
$opds->getPaginator(); // OpdsPaginator|OpdsPaginate|null - Paginator used to paginate feeds, if you use `paginate()` method
$opds->getResponse(); // OpdsResponse|null - Response of OPDS feed, will use `OpdsEngine` to create a response
```

### OPDS Version

[](#opds-version)

You can use query parameter `version` to set it dynamically. You could change this query into `OpdsConfig::class`.

- Version `1.2` can be set with `?v=1.2`
- Version `2.0` can be set with `?v=2.0`

Warning

If you set `v` query parameter to `1.2` with `OpdsConfig::class` method `forceJson()`, query param will be ignored.

### OPDS Engine

[](#opds-engine)

Engine will convert your feeds to OPDS, depending of OPDS version.

- [OPDS 1.2](https://specs.opds.io/opds-1.2) will use `OpdsXmlEngine::class`
- [OPDS 2.0](https://drafts.opds.io/opds-2.0) will use `OpdsJsonEngine::class`

You can get engine used with `getEngine()` method from `Opds::class`. Property `contents` contains array of feeds, `OpdsEngine` allow conversion into XML or JSON with `__toString()` method, the output depends of OPDS version.

```
use Kiwilan\Opds\Opds;

$opds = Opds::make()
  ->title('My feed')
  ->feeds([...])
  ->get()
;

$engine = $opds->getEngine(); // OpdsEngine
$contents = $engine->getContents(); // array
$output = $engine->__toString(); // string
```

### OPDS Response

[](#opds-response)

To build OPDS feed, you have to `get()` method. It will return an instance of `Opds` with `OpdsEngine`, `OpdsResponse` and paginator filled.

```
use Kiwilan\Opds\Opds;

$opds = Opds::make()
  ->title('My feed')
  ->feeds([...])
  ->get() // `Opds` to fill `OpdsEngine`, `OpdsResponse` and paginator
;
```

To get response, you can use `getResponse()` method from `Opds::class`.

```
use Kiwilan\Opds\Opds;

$opds = Opds::make()
  ->title('My feed')
  ->feeds([...])
  ->get()
;

$response = $opds->getResponse(); // OpdsResponse

$response->getStatus(); // int - Status code of response
$response->isJson(); // bool - If response is JSON
$response->isXml(); // bool - If response is XML
$response->getHeaders(); // array - Headers of response
$response->getContents(); // string - Contents of response
```

#### Send response

[](#send-response)

Note

This method is totally optional, you can send response to browser by yourself.

You can send response to browser by yourself from `OpdsResponse` to get status code, headers and contents or use `send()` method available into `Opds` and `OpdsResponse`.

- You can use `send()` from `Opds` or `OpdsResponse` to send response to browser (exactly the same)
- You don't have to call `get()` method before `send()` method, `send()` will call `get()` automatically

```
use Kiwilan\Opds\Opds;

Opds::make()
  ->title('My feed')
  ->feeds([...])
  ->send(); // XML or JSON response
;
```

You can call `get()` method before `send()` method if you want to get `OpdsResponse` instance.

```
use Kiwilan\Opds\Opds;

$opds = Opds::make()
  ->title('My feed')
  ->feeds([...])
  ->get()
;

// do something with `OpdsResponse` instance

$opds->send(); // XML or JSON response
```

To get response

```
use Kiwilan\Opds\Opds;

$opds = Opds::make()
  ->title('My feed')
  ->feeds([...])
  ->get();

$response = $opds->getResponse(); // OpdsResponse
$response->send(); // XML or JSON response
```

Note

You can use `exit` parameter from `send()` method to stop script after sending response.

### OPDS Config

[](#opds-config)

OPDS config can be set with `OpdsConfig::class`:

```
