README

WordPress backup, migration and restore plugin for internal use.

SL MigrationsUpdated 21 Oct 2026

SL Migrations

WordPress backup, migration and restore plugin for internal use.

Version: 1.8.10 License: GPLv2 or later Author: Steven Lam - https://phatdev.net

Features

  • Full-site backup (files + database) packaged into a portable archive (ZIP or DAF) + installer.
  • One-click restore on any compatible WordPress host.
  • Scheduled recurring backups.
  • Remote storage via SFTP / FTP.
  • Disaster Recovery Point - mark one package as a quick restore point; generate a recovery URL with one click, automatically protected from the cron retention purge and from manual deletion.
  • Self-contained: no external license server, no telemetry, no phone-home.

Requirements

  • WordPress 4.9+ (tested up to 7.0)
  • PHP 7.4+ (PHP 8.2 recommended)
  • Single-site activation only (Network: false in the plugin header): activate it on each site; it cannot be network-activated

Storage backends

  • Local - packages stored in wp-content/backups-slm/.
  • FTP / SFTP - upload to a remote SSH/FTP server.
  • Cloud storage (Amazon S3, Dropbox, Google Drive, OneDrive and similar) is not included: those SDKs are removed from this build.

Branding

Visual style follows the TanDoanh Plugins design system:

  • Primary: #1b64f2 (blue)
  • Accent dark: #1349ba
  • Surface: #ffffff on #eef2f7 background
  • Typography: Plus Jakarta Sans / Manrope / system fallback

Activation

wp plugin activate sl-migrations

Or via WP Admin → Plugins → Activate.

Backup output

  • Folder: wp-content/backups-slm/
  • Per package: an archive (*_archive.zip or *_archive.daf, depending on the archive engine) of the full site + a *_installer.php (self-contained restorer).

Restore

Upload the archive (*_archive.zip or *_archive.daf) + *_installer.php to the destination host, then open installer.php in a browser and follow the wizard.

Security note

installer.php, when uploaded to a public web root during restore, is executable by anyone who knows the URL until it self-destructs at the end of the process. Always either:

  • protect the upload folder with HTTP basic auth, or
  • delete installer.php immediately after a successful restore (the wizard offers a cleanup step).

License

GPLv2 - see source headers. Internal-use plugin; not for redistribution.

CSS architecture

Single source of truth: assets/css/slm.css - all of the plugin's UI rules live here. The old CSS files (style.css, slm-overrides.css, modern.css, packages.css, import.css, info-page.css, style-ctrl.css, global_admin_style.css, admin-notifications.css, admin-notices.css) have been STUBBED (empty) - they are kept only to avoid 404s for the old wp_register_style handles.

slm.css uses CSS @layer to control the cascade - no !important is needed in new code:

@layer reset, tokens, base, components, pages, vendor-fix;
Layer Purpose Add a new rule when?
tokens CSS variables (--slm-*) Changing global color/spacing/shadow
base Typography + form defaults inside .slm-modern Rarely
components Buttons, cards, tables, badges, pills, modals, toasts, progress A new component
pages Page-specific overrides A new page
vendor-fix Overrides for legacy plugin classes + jstree/select2 Strictly a last resort

Class naming convention

  • New: prefix slm-* for every class you write (.slm-btn, .slm-card, .slm-pill-complete, …).
  • Legacy (.dup-*, .dpro-*): only touch them when editing an old template; prefer adding a parallel .slm-* class instead of renaming the legacy one.

When you need to add a new rule

  1. Open assets/css/slm.css
  2. Find the right @layer (see the table above)
  3. Add the rule inside that block - do not create a new CSS file
  4. Do NOT use !important unless you are in the vendor-fix layer
  5. Use CSS variables instead of hardcoded color/spacing (var(--slm-blue) rather than #2563eb)

When you need to change the theme color

Edit @layer tokens at the top of slm.css. Change one variable and everywhere that uses it updates automatically.

Anti-patterns (do not do these)

  • Creating a separate CSS file for a single component (for example my-feature.css)
  • Inline style="..." in PHP templates (unless the value is computed dynamically)
  • Overly specific selectors like body[class*="page"] .wrap table.widefat:not(.a):not(.b) ... - use a simple .slm-* class instead
  • !important in the components or pages layer