Modernized phpDivingLog using a decoupled PHP core and separate web/API adapters.
This codebase has been rewritten from the legacy monolithic stack to:
- a strict-typed domain/repository core under
src/(PhpDivingLog\\*), - a standalone Twig web adapter under
adapters/web/andpublic/index.php, - a standalone JSON API adapter under
adapters/api/andpublic/api.php.
The application reads from a Diving Log MySQL export schema (table prefix configurable, default DL_).
- PHP 8.3+
- Extensions:
pdo,mbstring,json, plus one of:pdo_mysql(for a MySQL/MariaDB database), orpdo_sqlite(for a SQLite file -- no database server required; also used by the fixture-backed integration/smoke tests regardless of which driver you deploy with)
- Composer 2+
For a concise setup checklist, see INSTALL.md.
-
Install dependencies:
composer install -
Copy environment template and configure DB access:
cp .env.example .env -
Ensure writable runtime directories:
var/cachevar/log
-
Configure web server front controller routing to:
public/index.php(web)public/api.php(API)
See deployment details in docs/deployment.md.
If you deploy under a subfolder (for example https://example.com/divelog),
see the subfolder section in INSTALL.md.
All options are environment-driven via src/Support/Config.php.
Important keys:
DB_DSNandDB_USER(preferred), orDB_HOST/DB_PORT/DB_NAME/DB_USERTABLE_PREFIX(defaultDL_)APP_QUERY_STRINGfalse: pretty URL mode (rewrite rules)true: fallback query-string mode
Complete option list: .env.example.
DB_DSN quick examples:
mysql:host=127.0.0.1;port=3306;dbname=divelog;charset=utf8mb4mysql:unix_socket=/var/run/mysqld/mysqld.sock;dbname=divelog;charset=utf8mb4sqlite:/absolute/path/to/divinglog.sqlite
phpDivingLog can run against either engine -- switching is a .env change, not a code
change:
-
MySQL (default): set
DB_DSN(orDB_HOST/DB_PORT/DB_NAME) plusDB_USER/DB_PASSWORD, and keepTABLE_PREFIX=DL_(or your custom prefix). -
SQLite: set
DB_DSN=sqlite:/absolute/path/to/your-file.sqlite. NoDB_USER/DB_PASSWORDis needed -- SQLite has no server-side authentication. Requires thepdo_sqlitePHP extension. Store the file outsidepublic/(e.g. undervar/), since it's opened read-only and never needs to be web-accessible.Two SQLite file shapes are supported, selected via
TABLE_PREFIX:- A native Diving Log SQLite export (the file Diving Log itself can export, with
unprefixed tables like
Logbook,Place,Country): setTABLE_PREFIX=(empty). - A MySQL-export-shaped SQLite file (tables named like
DL_Logbook): keepTABLE_PREFIX=DL_as usual.
Known limitation: photos, maps, and certification scans stored as in-database BLOBs in a native Diving Log export are not rendered -- phpDivingLog only reads filesystem-path columns (e.g.
PhotoPath-style fields) for images, matching its MySQL-export behavior. If your SQLite file only has BLOB image data, those images simply won't display; nothing else is affected. - A native Diving Log SQLite export (the file Diving Log itself can export, with
unprefixed tables like
- Web UI:
public/index.php - API:
public/api.php
When rewrites are unavailable and APP_QUERY_STRING=true:
/?type=dives/?type=dives&id=1/?type=stats
Run the full gate:
composer testcomposer stancomposer cs
Or one-liner:
composer test && composer stan && composer cs
- Core domain + repositories:
src/ - Web adapter (Twig):
adapters/web/,templates/ - API adapter (JSON):
adapters/api/ - Public front controllers/assets:
public/
The following legacy stack has been retired in favor of the modernized architecture:
- monolithic
classes.inc.php - legacy page controllers in repository root
includes/(Smarty/wp-db.php/jqPlot/img scripts)tpl/sql/
Static media assets are served from public/images/, and frontend runtime assets are served from public/assets/.
GPL-3.0-or-later