The client works standalone from the command line. It can additionally be wired into the project in three stages — from "not at all" to "fully".
Relevant files:
manage-client/lib/client.php – the only entry point, loads everything elsemanage-client/ui/panel.php – the complete UImanage-client/ui/status-partial.php – a small status blockmanage-client/bin/manage-client.php – command line for cronNothing to do. The client is operated exclusively from the command line and the project knows nothing about it. Only the folder needs to exist and be configured.
This stage is enough when updates and backups are maintained by one person with shell access.
ui/panel.php is a ready-made page. It expects the project to have
already checked its own login before the file is included.
New file admin/manage.php in the project:
<?php
require_once __DIR__ . "/../config.php";
require_once __DIR__ . "/../includes/functions.php";
// The project's own login check - whatever the project already uses.
if (empty($_SESSION["admin_logged_in"])) {
header("Location: login.php");
exit;
}
require __DIR__ . "/../manage-client/ui/panel.php";
The panel brings its own check on $_SESSION["admin_logged_in"], so a
direct call isn't left unprotected. If the project uses a different session
flag, there are two options:
ui/panel.php (this folder is maintained per project
anyway), ordefine("MANAGE_PANEL_SKIP_AUTH_GUARD", true); before including it,
if the login is already guaranteed in the calling script.The second option only disables the panel's extra check. Setting it without checking the login yourself publishes update and backup functions to the internet.
For a settings page, the small block is often enough:
<?php
$manageStatusPanelUrl = "manage.php";
include __DIR__ . "/../manage-client/ui/status-partial.php";
?>
It renders only a fragment, never throws an exception, and shows version, update availability, last backup and pending migrations.
All functions from 04_FUNCTION_API can be called directly:
require_once __DIR__ . "/manage-client/lib/client.php";
// e.g. on the admin dashboard: automatic backup when due
manageBackupCreateAutomaticIfDue();
This call is the option for hosting without cron: it creates a backup once
MANAGE_BACKUP_AUTO_INTERVAL_SECONDS has passed since the last automatic
backup, and otherwise returns null immediately. A backup takes several
seconds depending on the amount of data — so the call belongs on a rarely
loaded admin page, not on every page of the project.
Cron is the recommended path. Example lines live in
examples/cron/manage-client.cron:
# Backup, every night at 03:20.
20 3 * * * /usr/bin/php /path/to/project/manage-client/bin/manage-client.php backup --trigger=cron --quiet
# Status report to the Manage server, hourly.
7 * * * * /usr/bin/php /path/to/project/manage-client/bin/manage-client.php heartbeat --quiet
# Update check, weekdays at 08:00 (exit 2 = update available).
0 8 * * 1-5 /usr/bin/php /path/to/project/manage-client/bin/manage-client.php check --quiet
--quiet suppresses normal output; errors still go to STDERR and are
delivered by cron via mail. Updates are deliberately not installed
automatically: update remains a deliberate decision.
The project's .gitignore should contain:
manage-client/config.php
data/manage/
The rest of manage-client/ should be checked in, so it's part of the
release package and gets deployed along with it.
PHP needs write access to:
data/manage/backups/ – local archivesdata/manage/work/ – working directory for updates (cleared after every run)data/manage/updates/ – copies of the files an update overwroteWithout write access in the application root, an update fails partway through. See 09_TROUBLESHOOTING.
These directories must not be reachable over the web. On Apache, the
project's own .htaccess usually handles that; the bundled
manage-client/.htaccess additionally protects config.php, lib/ and
bin/.