# Landing Page URL Bindings Export/Import (4.0.42)

## Problem

WPMktgEngine stores URL-to-template bindings for Genoo landing pages as post meta on a
custom post type (`wpme-landing-pages`). When a WordPress site is fully rebuilt and the
plugin is reinstalled, those CPT posts and their meta are gone. The **Sync Templates**
server action only re-fetches Genoo template HTML — it does not restore the URL routing.
Without the URL bindings, Genoo landing pages stop serving at their expected addresses.

## Solution

Two new widgets in the **WPMktgEngine → Tools** admin menu let administrators export all
URL bindings as a JSON file and later import them on a fresh install to restore the
routing without any manual data entry.

---

## What Is Exported

A JSON object with two top-level keys:

| Key | Description |
|-----|-------------|
| `format` | `"wpmktengine-landing-pages"` — sentinel used to validate the file on import |
| `version` | `1` — payload schema version |
| `pages` | Array of page objects (see below) |
| `option` | The serialised `WPMKTENGINELANDING` WordPress option (landing-page index) |

### Per-page object (19 meta keys)

| Meta key | Notes |
|----------|-------|
| `wpmktengine_landing_url` | The URL slug that routes to this landing page |
| `wpmktengine_landing_template` | **Genoo template ID** — centralized server-side value, stable across reinstalls |
| `wpmktengine_landing_active` | Boolean — whether this page is live |
| `wpmktengine_landing_homepage` | Boolean — whether this page serves as the site homepage |
| `wpmktengine_landing_redirect_active` | Boolean — redirect on/off |
| `wpmktengine_landing_redirect_url` | Destination URL when redirect is on |
| `wpmktengine_data_header` | Custom header HTML injected into this page |
| `wpmktengine_data_footer` | Custom footer HTML injected into this page |
| `wpmktengine_tracking_data_head` | Per-page tracking code (`<head>`) |
| `wpmktengine_referer_redirect` | Boolean — referrer redirect on/off |
| `wpmktengine_referer_redirect_when` | Condition for referrer redirect |
| `wpmktengine_referer_redirect_from_url` | Source URL for referrer redirect |
| `wpmktengine_referer_redirect_url` | Destination URL for referrer redirect |
| `enable_pop_over_to_open_automatically` | Boolean — auto-open pop-over on/off |
| `pop_over_cta_id` | CTA ID for automatic pop-over |
| `number_of_seconds_to_open_the_pop_up_after` | Delay in seconds |
| `pop_over_only_for_unknown` | Boolean — pop-over for unknown visitors only |
| `_scripts` | Per-page custom scripts |
| `_styles` | Per-page custom styles |

**Template HTML is not exported.** It lives on Genoo's servers and is re-fetched by
**Tools → Sync Templates** after the import. The Genoo template ID is a server-side
constant — the same ID refers to the same template across all WP installs connected to
the same Genoo account.

---

## New Class: `LandingPagesPorter`

File: `libs/WPMKTENGINE/LandingPagesPorter.php`

Namespace: `WPMKTENGINE`

Auto-loaded via the `WPMKTENGINE` namespace SPL autoloader (no registration changes
needed — the file placement in `libs/WPMKTENGINE/` is sufficient).

### Constants

```php
const FORMAT  = 'wpmktengine-landing-pages';
const VERSION = 1;
const META_KEYS = [ /* all 19 keys listed above */ ];
```

### `doExport(): void`

- Calls `buildPayload()` to assemble the JSON object.
- Sets `Content-Type: application/json` and
  `Content-Disposition: attachment; filename="landing-pages-YYYY-MM-DD.json"` headers.
- Echoes the JSON-encoded payload and calls `exit`.

### `doImport(): array`

Returns `['created' => int, 'updated' => int, 'skipped' => int, 'errors' => string[]]`.

- Validates: `format` sentinel must equal `FORMAT`, `version` must equal `1`, `pages`
  must be an array.
- Skips silently (increments `skipped`) any entry whose `wpmktengine_landing_url`
  or `wpmktengine_landing_template` is empty — these are incomplete draft posts that
  were captured during export.
- For each valid entry, looks for an existing `wpme-landing-pages` post that already has
  the same `wpmktengine_landing_url`. If found and the **overwrite** checkbox was checked,
  updates all 19 meta keys. If found and overwrite was not checked, skips. If not found,
  creates a new draft CPT post and writes all 19 meta keys.
- Optionally (when **import globals** is checked) restores the `WPMKTENGINELANDING`
  option.

### `buildPayload(): array`

- Queries all `wpme-landing-pages` posts with any status (publish, draft, private, trash)
  using `WP_Query`.
- For each post, reads all 19 meta keys with `get_post_meta()` (single value mode).
- Returns the assembled payload array.

---

## Changes to `Tools.php`

- `process()`: added `case 'genooActionExportLandingPages'` → calls
  `LandingPagesPorter::doExport()`.
- Added `getWidgetExportLandingPages()`: renders an export widget that shows the current
  landing page count and a **Download JSON** button (links to
  `?page=wpmktgengine&action=genooActionExportLandingPages`).
- Added `getWidgetImportLandingPages()`: renders an import widget with a file picker,
  **Overwrite existing** checkbox, **Import globals** checkbox, and a **Import** submit
  button. Import is handled via `admin_post_wpme_import_landing_pages`.
  Also shows a success/error notice when redirected back with `?wpme_import=1` GET params.

---

## Changes to `Admin.php`

- Registered `add_action('admin_post_wpme_import_landing_pages', ...)` in
  `registerHooks()`.
- The handler:
  1. Checks `manage_options` capability and verifies the `wpme_import_lp_nonce` nonce.
  2. Validates that a file was uploaded and that its temporary path is readable.
  3. Reads the file, JSON-decodes it, and calls `LandingPagesPorter::doImport()`.
  4. Redirects to the Tools page with `?wpme_import=1&created=N&updated=N&skipped=N`
     (on success) or `?wpme_import_error=1&msg=...` (on failure).

---

## UI Location

**WPMktgEngine → Tools** admin page — two new widgets in the tools grid:

- **Export Landing Page URL bindings** — shows page count, one-click JSON download.
- **Import Landing Page URL bindings** — file upload form with optional overwrite and
  global-settings restore.

---

## Workflow

1. On the old/source site: Tools → Export Landing Page URL bindings → download JSON.
2. Reinstall WordPress + WPMktgEngine on the new site.
3. Tools → Sync Templates to pull Genoo template HTML back down.
4. Tools → Import Landing Page URL bindings → upload the JSON file → Import.
5. Landing pages are now routed correctly at their original URLs.
