Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
a7c8ce6
Document public library showcase and fix desiderata creator credits
fabiodalez-dev Oct 12, 2026
48293e1
Align mobile desiderata credits and address showcase review findings
fabiodalez-dev Oct 12, 2026
93d33dc
Prioritize showcase books and move card controls below covers
fabiodalez-dev Oct 12, 2026
4f6b88f
Keep card titles close to covers and compact footer controls
fabiodalez-dev Oct 12, 2026
db65dae
Record Android review fixes and final validation
fabiodalez-dev Oct 12, 2026
c22ce5f
Overlay status and wishlist inside the bottom of covers
fabiodalez-dev Oct 12, 2026
1c96e12
Give book titles space below the cover shadow
fabiodalez-dev Oct 12, 2026
92e0b1a
Refresh catalog screenshot with title shadow spacing
fabiodalez-dev Oct 12, 2026
eb56f06
Open PDF attachments in a responsive fullscreen lightbox
fabiodalez-dev Oct 12, 2026
beb653f
Localize PDF reader actions and refresh its showcase screenshot
fabiodalez-dev Oct 12, 2026
8373a81
Bundle a self-hosted light PDF reader with responsive side margins
fabiodalez-dev Oct 12, 2026
bda864a
Include the PDF engine and worker in releases and test local assets
fabiodalez-dev Oct 12, 2026
92d930a
Keep PDF side margins independent of global iframe rules
fabiodalez-dev Oct 12, 2026
f5c0b1f
Open PDFs as single pages for readable mobile layouts
fabiodalez-dev Oct 12, 2026
be58817
Make Escape close the reader consistently from PDF controls
fabiodalez-dev Oct 12, 2026
f30cc86
Document PDF reading, CORS checks and refresh the light reader screen…
fabiodalez-dev Oct 12, 2026
d4caf02
Fix PDF partial analysis and keep reader integration scanned
fabiodalez-dev Oct 12, 2026
22ba156
Validate PDF frame navigation at the DOM boundary
fabiodalez-dev Oct 12, 2026
76d53b6
Keep generated-cover publisher clear of bottom badges
fabiodalez-dev Oct 12, 2026
e57d946
fix: keep desktop book cover beside digital contents
fabiodalez-dev Oct 12, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions .gitattributes
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,8 @@
public/uploads/archives/e2e/*.pdf binary
tests/fixtures/archive-test.pdf binary -whitespace
tests/fixtures/test_import_languages.tsv -whitespace
# Preserve the published PDF.js distribution and its license texts verbatim.
public/assets/vendor/pdfjs-6.4.299/** linguist-vendored -whitespace

# Exclude from release archives (git archive)
# NOTE: public/installer/assets/ MUST be in the ZIP — contains installer.js
Expand Down
6 changes: 6 additions & 0 deletions .github/codeql/codeql-config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -18,3 +18,9 @@ paths-ignore:
- 'installer/assets/**'
- 'public/installer/assets/**'
- 'scripts/**'

# Verified, unmodified upstream PDF.js modules; application integration stays scanned.
- 'public/assets/vendor/pdfjs-6.4.299/build/pdf.mjs'
- 'public/assets/vendor/pdfjs-6.4.299/build/pdf.worker.mjs'
- 'public/assets/vendor/pdfjs-6.4.299/build/pdf.sandbox.mjs'
- 'public/assets/vendor/pdfjs-6.4.299/web/viewer.mjs'
4 changes: 2 additions & 2 deletions .github/workflows/ci-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -364,8 +364,8 @@ jobs:
# Run after plugin schema setup so the cross-plugin cases cannot skip.
REQUIRE_DESIDERATA_TESTS=1 php tests/bookclub-lending.unit.php

- name: Donation form CSRF concurrency regression
run: node --test tests/desiderata-csrf-concurrency.test.cjs
- name: JavaScript security and concurrency regressions
run: node --test tests/*.test.cjs

- name: Shell test — bin/setup-permissions.sh
run: bash tests/setup-permissions.test.sh
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -421,6 +421,8 @@ yarn.lock
dist/
!public/assets/star-rating/dist/
build/
!/public/assets/vendor/pdfjs-6.4.299/build/
!/public/assets/vendor/pdfjs-6.4.299/build/**
frontend/dist/
frontend/build/
frontend/storage/
Expand Down
23 changes: 21 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,14 @@ Pinakes is a self-hosted, full-featured ILS for schools, municipalities, and pri

---

## Live demo

Explore **[Biblioteca delle idee libere](https://biblioteca.fabiodalez.it/)**: real ISBN records, anarchist classics, social ecology and Palestine studies, alongside periodicals, illustrated articles, wanted books, PDFs and complete audiobooks.

The showcase contains 50 catalogue books, 8 desiderata, 3 periodicals with 10 issues, 22 articles, 11 PDFs and 2 audiobooks across 12 tracks. Holdings and activities are illustrative. [Sources, screenshots and verification notes](docs/demo/README.md).

---

## Requirements

- **PHP 8.2 or higher** — matches `composer.json` (`^8.2`); the installer and the in-app updater enforce this floor.
Expand Down Expand Up @@ -213,8 +221,19 @@ Pinakes provides cataloging, circulation, a self-service public frontend, and RE
</p>

<p align="center">
<img src="./docs/catalog.png" alt="Public Catalog" width="800"><br>
<em>Public Catalog (OPAC) — Search, filters, and patron self-service</em>
<img src="./docs/demo/home.jpg" alt="Public homepage with real book covers" width="800"><br>
<em>Public homepage — a library of free ideas</em>
</p>

| Catalogue | Books and digital reading |
| --- | --- |
| ![Catalogue](docs/demo/catalogo.jpg) | ![Book record](docs/demo/libro.jpg) |
| ![Periodicals](docs/demo/rivista.jpg) | ![Article record](docs/demo/articolo.jpg) |
| ![Wanted books](docs/demo/desiderata.jpg) | ![PDF reader](docs/demo/pdf.jpg) |

<p align="center">
<img src="./docs/demo/home-mobile.jpg" alt="Public homepage on a 390 pixel mobile viewport" width="250">
<img src="./docs/demo/desiderata-mobile.jpg" alt="Wanted books on a mobile viewport" width="250">
</p>

---
Expand Down
8 changes: 8 additions & 0 deletions app/Services/UnifiedCatalogService.php
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,14 @@ public function page(string $bookFrom, string $authorSelect, string $bookTypes,
'author_desc' => 'author_sort IS NULL, author_sort DESC',
default => 'created_at DESC',
};
// An installation can foreground its book holdings in the recent view.
// Apply this to the UNION before LIMIT: sorting the rendered page would
// still put newer articles on the first pages. Alphabetical and other
// explicit sort orders keep their unified-catalogue semantics (#412).
if (($filters['sort'] ?? 'newest') === 'newest'
&& (new \App\Models\SettingsRepository($this->db))->get('catalog', 'books_first', '0') === '1') {
$order = "CASE WHEN kind = 'book' THEN 0 ELSE 1 END, $order";
}
$keys = $this->rows("SELECT * FROM ($union) results ORDER BY $order, kind ASC, id ASC LIMIT ? OFFSET ?",
$bookTypes . $types . 'ii', array_merge($bookParams, $params, [$limit, $offset]));
$records = [];
Expand Down
4 changes: 2 additions & 2 deletions app/Views/frontend/partials/pk-book-card.php
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
<?php
/**
* One book as a card (2026 design): the cover as a 3D book on a panel tinted
* from the cover's own colour, the availability badge and the wishlist heart
* on the panel, then title, subtitle, author, publisher and "Details".
* from the cover's own colour, then title, subtitle, author and publisher.
* Availability and wishlist overlay the bottom of the cover.
*
* Shared by the home, the catalogue grid and the book page's related books,
* so every list of books looks the same. Keeps every element the previous
Expand Down
54 changes: 54 additions & 0 deletions docs/demo/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
# Biblioteca delle idee libere

[Open the public showcase](https://biblioteca.fabiodalez.it/). Captured and checked on 12 October 2026, Pinakes 0.8.2.

The catalogue contains real editions, real periodicals and real articles. Inventory, copies, archive arrangement and activities demonstrate the software; this installation is not an operating lending library.

| Collection | Records |
| --- | ---: |
| Catalogue books | 50 |
| Desiderata | 8 |
| Periodicals / issues | 3 / 10 |
| Illustrated articles | 22 |
| Complete PDF texts | 11 |
| Audiobooks / tracks | 2 / 12 |
| Reading clubs | 2 |
| Archive units | 4 |

## Explore

- [Catalogue](https://biblioteca.fabiodalez.it/catalogo)
- [Wanted books](https://biblioteca.fabiodalez.it/#desiderata-heading)
- [Periodicals](https://biblioteca.fabiodalez.it/emeroteca)
- [Article: La fine del diritto](https://biblioteca.fabiodalez.it/emeroteca/articolo/4)
- [Malatesta: digital editions and audio](https://biblioteca.fabiodalez.it/errico-malatesta/anarchia-il-nostro-programma/144)
- [Reading clubs](https://biblioteca.fabiodalez.it/book-club)
- [Digital archive](https://biblioteca.fabiodalez.it/archivio)

## Sources and editions

The installed Scraping Pro plugin supplied bibliographic enrichment. Publisher records resolved conflicting creator roles, dates and pagination; author names were consolidated. Shelf marks use actual shelf/mensola records, for example `E-1-04`, and inventory codes use `2026-00001`.

[Book sources](catalogue-sources.json) and [periodical/article sources](periodical-sources.json) list the original publications. Covers and article images retain their respective owners’ rights; the code licence does not grant rights to those images.

Ten PDFs are copyleft editions published by elèuthera. Malatesta’s PDF and Italian recording by Mela Boev come from [Liber Liber](https://liberliber.it/autori/autori-m/errico-malatesta/lanarchia-audiolibro/) under CC BY-NC-SA 4.0. The ISBN record identifies the E-text ebook; the attached Liber Liber version is a distinct edition. Bakunin’s [God and the State](https://librivox.org/god-and-the-state-by-mikhail-bakunin/) is the complete English LibriVox recording by Carl Manchester, not an Italian audiobook.

## Screenshots

Desktop and 390 × 844 mobile browser views. Some detailed screenshots were captured with a staff session; management buttons in those images are not offered to anonymous visitors.

![Home](home.jpg)

| Catalogue | Book |
| --- | --- |
| ![Catalogue](catalogo.jpg) | ![Book](libro.jpg) |
| ![Periodicals](rivista.jpg) | ![Article](articolo.jpg) |
| ![Desiderata](desiderata.jpg) | ![PDF](pdf.jpg) |
| ![Audio](audiolibro.jpg) | ![Archive](archivio.jpg) |
Comment thread
fabiodalez-dev marked this conversation as resolved.
| ![Periodicals archive](emeroteca.jpg) | ![Reading clubs](club.jpg) |

## Verification

[Checks and issues discovered during preparation](verification.md). A full database/upload backup was validated before replacing the old collection and is retained privately outside the public web directory.

The demo catalogue lists books first in the recent view through the `catalog.books_first=1` preference in `system_settings`. Book priority is applied before pagination; articles stay in the catalogue, and alphabetical sorts remain shared across books and articles. Other installations keep the mixed recent order when the preference is absent or disabled.
Binary file added docs/demo/archivio.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/demo/articolo.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/demo/audiolibro.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added docs/demo/catalogo.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Loading