glueful / archive
Data-lifecycle archiving for Glueful (table archiving, retention, compression, restore).
Requires
- php: ^8.3
Requires (Dev)
- glueful/framework: ^1.52.0
- phpstan/phpstan: ^1.0
- phpunit/phpunit: ^10.5
- squizlabs/php_codesniffer: ^3.6
README
Overview
Archive adds data-lifecycle archiving to your Glueful application: move aged rows out of operational tables into compressed (optionally encrypted) archive files, keep a searchable index of what was archived, and restore archived rows back into a table when you need them again.
It is a self-contained product — there is no core seam to bind. Installing the
extension ships its own schema (registry, search index, table-stats), a
ArchiveService for programmatic use, and an archive:manage CLI for
operational tasks. The schema is config-gated: migrations only register when
you explicitly opt in via ARCHIVE_DATABASE_SCHEMA (→ archive.enabled).
Features
- Table archiving: export rows older than a cutoff date, compress (gzip/bzip2) and optionally encrypt (AES-256-GCM), checksum, register, then delete the originals — all guarded by verification before the source rows are removed
- Restore: replay archived rows back into a target table inside a single
transaction, with
skip/overwriteconflict resolution and offset/limit slicing - Search: query across compressed archives by user, endpoint, action, IP, and date range, backed by a per-archive search index built at archive time
- Verification & integrity: SHA-256 checksums with on-demand
verifyArchive()and corruption flagging - Table growth tracking: record row counts / sizes per table and surface which tables exceed configured row/age thresholds and need archiving
archive:manageCLI:archive,status,search,verify,health,cleanup,auto, andtrackactions for day-to-day operations- Config-gated schema: ships its own migrations, registered only when
ARCHIVE_DATABASE_SCHEMAis enabled — zero footprint until you opt in - Dedicated storage disk: archives are written to a private local disk rooted at the configured storage path
Installation
Installation (Recommended)
Install via Composer
composer require glueful/archive
# Rebuild the extensions cache after adding new packages
php glueful extensions:cache
Composer discovers packages of type glueful-extension, but installing does not auto-enable them — the provider must be added to config/extensions.php's enabled allow-list. The CLI does that for you:
# Enable (adds the provider FQCN to config/extensions.php + recompiles the cache) php glueful extensions:enable archive # Disable (removes it) php glueful extensions:disable archive
In production, manage the enabled list in config and run php glueful extensions:cache in your deploy step.
This extension ships migrations, but the schema is config-gated. Set the opt-in flag, then run the migrations:
# .env
ARCHIVE_DATABASE_SCHEMA=true
php glueful migrate:run
The migrations only register when archive.enabled (ARCHIVE_DATABASE_SCHEMA) is
true, so nothing is created until you opt in.
Local Development Installation
To develop the extension locally, register it as a Composer path repository in your app's composer.json, then require and enable it:
// composer.json "repositories": [ { "type": "path", "url": "extensions/archive", "options": { "symlink": true } } ]
composer require glueful/archive:@dev php glueful extensions:enable archive
Entries in config/extensions.php are plain string FQCNs (no ::class) — prefer extensions:enable over editing by hand.
Verify Installation
php glueful extensions:list php glueful extensions:info archive php glueful extensions:diagnose
Post-install checklist:
- Opt into the schema: set
ARCHIVE_DATABASE_SCHEMA=true, thenphp glueful migrate:run - Rebuild cache after Composer operations:
php glueful extensions:cache - Confirm the CLI is registered:
php glueful archive:manage status
Configuration
Configuration is loaded from the extension's config/archive.php and merged under
the archive key by the service provider. It reads ARCHIVE_* environment
variables. Key settings:
# Opt-in gate for the schema/migrations (archive.enabled) ARCHIVE_DATABASE_SCHEMA=true # Compression: gzip | bzip2 | none ARCHIVE_COMPRESSION=gzip ARCHIVE_COMPRESSION_LEVEL=9 # Encryption (AES-256-GCM) — enabled when a key is present ARCHIVE_ENCRYPTION_KEY= # Processing ARCHIVE_CHUNK_SIZE=10000 ARCHIVE_MEMORY_LIMIT=512M ARCHIVE_MAX_EXECUTION_TIME=3600 ARCHIVE_VERIFY_CHECKSUMS=true # Storage / limits ARCHIVE_MAX_SIZE=1073741824 # 1GB # Search indexing ARCHIVE_ENABLE_SEARCH_INDEX=true ARCHIVE_MAX_SEARCH_RESULTS=1000 # Scheduling (used by the auto/track workflows) ARCHIVE_AUTO_ENABLED=true ARCHIVE_FREQUENCY=weekly ARCHIVE_MAX_PER_RUN=10
config/archive.php also defines retention_policies (per-table archive age /
row thresholds for audit_logs, api_metrics, auth_sessions, etc.),
monitoring (health-check and alerting thresholds), schedule, and backup
sections — see the file for the full set of ARCHIVE_* overrides.
Usage
CLI
The archive:manage command is the operational entry point. Its first argument
is the action (default status):
# Show archive system status php glueful archive:manage status # Archive rows in a table older than N days (default 90) php glueful archive:manage archive audit_logs 90 # Search across archives php glueful archive:manage search --user=<uuid> --start-date=2026-01-01 --limit=20 # Verify an archive's integrity php glueful archive:manage verify --uuid=<archiveUuid> # Run health checks, cleanup, the auto-archive workflow, or growth tracking php glueful archive:manage health php glueful archive:manage cleanup php glueful archive:manage auto php glueful archive:manage track audit_logs
Useful options: --uuid, --user, --endpoint, --start-date, --end-date,
--limit, --format (table|json|csv), and --dry-run.
Programmatic (ArchiveService)
Resolve the service from the container via its interface:
use Glueful\Extensions\Archive\ArchiveServiceInterface; use Glueful\Extensions\Archive\DTOs\ArchiveSearchQuery; use Glueful\Extensions\Archive\DTOs\ArchiveRestoreOptions; $archive = app($context, ArchiveServiceInterface::class); // Archive rows older than a cutoff $result = $archive->archiveTable('audit_logs', new \DateTime('-90 days')); // $result->archiveUuid, $result->recordCount, $result->fileSize, ... // Search across archives $results = $archive->searchArchives(new ArchiveSearchQuery(/* ... */)); // Restore an archive into its source table (or a target table) $restore = $archive->restoreFromArchive($archiveUuid, new ArchiveRestoreOptions( conflictResolution: 'skip', // or 'overwrite' )); // Integrity & housekeeping $archive->verifyArchive($archiveUuid); $archive->deleteArchive($archiveUuid); // Stats & planning $archive->trackTableGrowth('audit_logs'); $stats = $archive->getTableStats('audit_logs'); $summary = $archive->getArchiveSummary(); $tables = $archive->getTablesNeedingArchival(); $list = $archive->getTableArchives('audit_logs');
Schema
When enabled, the extension creates three tables:
archive_registry— one row per archive (table, period, record count, file path, size, checksum, status, metadata)archive_search_index— per-archive index of searchable entity values (FK toarchive_registry, cascade on delete)archive_table_stats— per-table growth tracking and archive thresholds
Requirements
- PHP 8.3 or higher
- Glueful 1.52.0 or higher
- MySQL, PostgreSQL, or SQLite database
ext-opensslfor archive encryption (optional, whenARCHIVE_ENCRYPTION_KEYis set)
License
MIT — licensed consistently with the Glueful framework.
Support
For issues, feature requests, or questions, please create an issue in the repository.