Skip to content
← Back to Functions
Code

Restore Preflight Checker

Checks target database compatibility before importing a dump.

Function signature

ogCheckRestorePreflight(manifest = array(), target = array(), options = array())

Categories

  • Database Integrity

Parameters

manifestBackup manifest data. Recognized keys: `database_name`, `tables`.targetTarget database metadata. Recognized keys: `database_name`.optionsRequired database name and allowed tables policy. Recognized keys: `allowed_tables`, `expected_database`.

Return value

Public-safe status string returned by the function.

  • success
  • message
  • data

Compatibility

Existing function name, slug, path, and call order preserved; advertised metadata corrected to the actual source behavior.

Minimum PHP version: 7.4

Security notes

Use caller-owned allowlists and procedural mysqli prepared execution where SQL plans are returned; validate file paths, MIME policies, and permissions before file or download workflows.

Code

<?php

/*
 * Copyright (c) 2026 Jeffery L. Paris <jparis@phpog.com>.
 * Free for personal and internal use. Paid project use requires visible credit
 * to Jeffery L. Paris. Corporate use requires a paid license fee unless a
 * separate written license states otherwise.
 */

/**
 * Checks whether a planned restore appears safe before importing a dump.
 *
 * This function only reports restore risks. It does not run destructive SQL.
 *
 * @param array $manifest Backup manifest data.
 * @param array $target Target database metadata.
 * @param array $options Required database name and allowed tables policy.
 * @return array Restore preflight report.
 */
function ogCheckRestorePreflight($manifest = array(), $target = array(), $options = array()) {
	$result = array(
		'success' => false,
		'message' => '',
		'data' => array()
	);

	if (!is_array($manifest) || !is_array($target)) {
		$result['message'] = 'Manifest and target metadata must be arrays.';
		return $result;
	}

	if (!is_array($options)) {
		$options = array();
	}

	$errors = array();
	$warnings = array();

	$expected_database = '';
	if (!empty($options['expected_database'])) {
		$expected_database = trim((string)$options['expected_database']);
	}

	$manifest_database = '';
	if (!empty($manifest['database_name'])) {
		$manifest_database = trim((string)$manifest['database_name']);
	}

	$target_database = '';
	if (!empty($target['database_name'])) {
		$target_database = trim((string)$target['database_name']);
	}

	if (!empty($expected_database)) {
		if ($target_database != $expected_database) {
			$errors[] = 'Target database does not match the expected database.';
		}
	}

	if (!empty($manifest_database) && !empty($target_database)) {
		if ($manifest_database != $target_database) {
			$warnings[] = 'Manifest database and target database names differ.';
		}
	}

	$allowed_tables = array();
	if (!empty($options['allowed_tables']) && is_array($options['allowed_tables'])) {
		$allowed_tables = $options['allowed_tables'];
	}

	$tables = array();
	if (!empty($manifest['tables']) && is_array($manifest['tables'])) {
		$tables = $manifest['tables'];
	}

	foreach ($tables as $table) {
		if (!is_array($table) || empty($table['name'])) {
			continue;
		}
		$table_name = trim((string)$table['name']);
		if (!preg_match('/^[a-zA-Z0-9_]+$/', $table_name)) {
			$errors[] = 'Unsafe table name detected in manifest.';
			continue;
		}
		if (!empty($allowed_tables) && !in_array($table_name, $allowed_tables, true)) {
			$warnings[] = 'Table is not in the restore allowlist: ' . $table_name;
		}
	}

	$result['success'] = empty($errors);
	if (empty($errors)) {
		$result['message'] = 'Restore preflight passed.';
	} else {
		$result['message'] = 'Restore preflight failed.';
	}
	$result['data'] = array(
		'errors' => $errors,
		'warnings' => $warnings,
		'table_count' => count($tables)
	);

	return $result;
}