# WP Content Migration Plugin

A WordPress plugin that enables selective content migration between staging and production environments without requiring full site migrations.

## The Problem

Traditional WordPress workflows force you to migrate entire sites when moving content between environments. This plugin solves that by allowing you to select and migrate specific pages, posts, and their associated media.

## Current Features

### Connection Management
- **Hybrid approach**: Database connection for content + REST API for authentication
- **Secure authentication**: WordPress Application Passwords (built-in since WP 5.6+)
- **Socket support**: Works with Local by WP Engine's MySQL socket connections
- **Connection storage**: Save and reuse connections
- **Duplicate prevention**: Automatically updates existing connections instead of creating duplicates

### Content Migration
- **Selective migration**: Choose specific posts and pages to migrate
- **Full metadata**: Preserves all post meta fields
- **Categories and tags**: Automatically migrates and creates missing terms
- **Hierarchical categories**: Parent-child relationships preserved
- **URL replacement**: Automatically replaces source URLs with target URLs
- **Conflict resolution**: Three strategies:
  - **Overwrite**: Update existing content
  - **Skip**: Don't migrate if content exists
  - **Duplicate**: Create new posts even if they exist

### Media Migration
- **Image detection**: Finds all images in post content
- **Featured image support**: Migrates post thumbnails/featured images
- **Automatic download**: Fetches images from source site
- **WordPress integration**: Uploads to Media Library with proper thumbnails
- **Hash-based deduplication**: Prevents duplicate image uploads using MD5 hashing
- **URL updating**: Updates all image references in content

### Logging
- **Migration history**: Records all migration activities
- **Detailed tracking**: Tracks success, errors, and skipped items

## Requirements

- **WordPress**: 5.6+ (for Application Passwords)
- **PHP**: 7.4+
- **MySQL/MariaDB**: Database access to both sites
- **cURL**: Enabled for REST API requests

## Installation

1. Download or clone this repository to your WordPress plugins directory:
   ```
   wp-content/plugins/wp-content-migration/
   ```

2. Activate the plugin in WordPress admin:
   - Go to **Plugins** → Find "WP Content Migration"
   - Click **Activate**

3. Access the plugin:
   - Go to **Tools** → **Content Migration**

## Quick Start Guide

### Step 1: Generate Application Password

On your **remote WordPress site** (the one you want to connect to):

1. Go to **Users** → **Your Profile**
2. Scroll to **"Application Passwords"** section
3. Enter application name: "Content Migration Plugin"
4. Click **"Add New Application Password"**
5. **Copy the generated password** (format: `xxxx xxxx xxxx xxxx xxxx xxxx`)
   - You'll only see this once!

### Step 2: Configure Connection

In the plugin on your **local site**:

1. Go to **Tools** → **Content Migration** → **Connection tab**
2. Fill in the connection form:

   **Site URL**: 
   - Full URL of remote site
   - Example: `https://production.yoursite.com`

   **Database Host**:
   - For regular servers: `localhost` or `127.0.0.1`
   - For Local by WP Engine: Full socket path from Database tab
     - Example: `/Users/username/Library/Application Support/Local/run/xyz/mysql/mysqld.sock`

   **Database Name**:
   - Remote site's database name
   - Find in Local's Database tab or hosting control panel

   **Database Username**: 
   - Usually `root` for local, varies for servers

   **Database Password**:
   - Database password (not your WordPress password)

   **API Username**:
   - Your WordPress admin username on the remote site

   **Application Password**:
   - The password you generated in Step 1

3. Click **"Test Connection"**
4. If successful, connection will be saved automatically

### Step 3: Migrate Content

1. Go to **Migration tab**
2. Select connection from dropdown
3. Choose direction:
   - **Remote → Local**: Import from remote to this site
   - **Local → Remote**: Export from this site (not yet implemented)
4. Click **"Load Content"**
5. Select posts/pages to migrate (checkboxes)
6. Configure options:
   - **Conflict Resolution**: Choose overwrite/skip/duplicate
   - **Migrate media**: Enable to download and upload images
   - **Deduplication**: Enable to prevent duplicate images
7. Click **"Start Migration"**
8. Watch progress bar and wait for completion

## Architecture

### File Structure

```
wp-content-migration/
├── wp-content-migration.php          # Main plugin file
├── README.md                          # This file
├── PROJECT.md                         # Technical documentation
├── includes/
│   └── class-connection-manager.php  # DB & API connections
├── admin/
│   ├── admin-page.php                # Admin interface
│   └── assets/
│       ├── css/admin.css             # Styling
│       └── js/admin.js               # JavaScript functionality
```

### How It Works

1. **Connection**: Establishes both database (PDO) and REST API connections
2. **Content Loading**: Queries remote database for posts/pages
3. **Migration Process**:
   - Fetches full post data from remote database
   - Detects conflicts with existing content
   - Applies conflict resolution strategy
   - Saves post content (unchanged initially)
   - **Image Migration** (if enabled):
     - Finds all `<img>` tags in content
     - Downloads images via HTTP
     - Calculates MD5 hash
     - Checks for existing image with same hash
     - Uploads new images or reuses existing ones
     - Updates image URLs in content
   - **URL Replacement**: Changes source URLs to target URLs
   - Saves final content
   - Logs result

### Database Tables

**wp_content_migration_connections**
- Stores saved connection configurations
- Passwords are base64 encoded (basic security)

**wp_content_migration_logs**
- Records all migration activities
- Tracks source, target, content type, status, messages

## Current Limitations

### Not Yet Implemented
- Custom post types
- Custom taxonomies (only category and post_tag supported)
- Custom fields (ACF, etc.)
- Widgets and menus
- Theme customizations
- Migration from local → remote (export)
- Logs viewer in UI
- Detailed progress feedback (migration details not displayed in UI)
- User data

### Known Issues
- **Local by WP Engine only**: Socket path method only works for development
  - Real servers use standard `localhost` or hostname
- **No encryption**: Database passwords use basic base64 encoding
  - Fine for development, consider encryption for production
- **No batch size control**: Processes all selected items at once
  - May timeout with large migrations
- **Limited error feedback**: Console logging only
  - No detailed UI error messages yet

## Troubleshooting

### Connection Issues

**"Database connection failed"**
- Verify database host, name, username, and password
- For Local: Use exact socket path from Database tab
- Check database user has appropriate permissions

**"REST API connection failed"**
- Verify site URL includes protocol (http:// or https://)
- Check username is correct WordPress admin username
- Ensure Application Password is correctly formatted (24 chars with spaces)
- Verify WordPress version is 5.6+ (Application Passwords required)

**"Network error occurred"**
- AJAX handler may be missing or misconfigured
- Check browser console for specific error
- Verify plugin is activated

### Migration Issues

**"Images not migrating"**
- Check "Migrate associated media files" is checked
- Verify source images are accessible via HTTP
- Check file write permissions on wp-content/uploads/
- Look for errors in wp-content/debug.log

**"Post content missing after migration"**
- Check conflict resolution setting
- If "skip" is selected, existing posts won't be updated
- Verify source post actually has content

**"Image shows alt text instead of image"**
- Plugin version may have bug (fixed in recent update)
- Re-migrate with updated plugin version
- Check Media Library to see if image uploaded

### Debug Mode

Enable WordPress debug logging in `wp-config.php`:

```php
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
```

Check `/wp-content/debug.log` for detailed error messages.

## Security Considerations

### Current Implementation
- Database passwords stored base64 encoded (not encrypted)
- Application Passwords use WordPress native authentication
- Connection validation before migration
- Data sanitization on all inputs
- Nonce verification for AJAX requests
- Capability checks (manage_options required)

### Production Recommendations
- Use proper encryption for stored passwords
- Implement audit logging
- Add rate limiting for migrations
- Consider IP whitelisting for API access
- Regular security audits

## Deployment Notes

### Local by WP Engine → Real Servers

When moving from Local development to actual staging/production:

1. **No socket paths needed**: Use `localhost` or hostname
2. **Different credentials**: Use actual database credentials
3. **SSL certificates**: May need to handle HTTPS properly
4. **Firewall rules**: Ensure database port access between servers
5. **File permissions**: Verify uploads directory is writable

### Real Server Requirements
- Database server must be accessible from web server
- MySQL user must have appropriate permissions
- PHP must have PDO MySQL extension enabled
- cURL must be enabled for HTTP requests

## Development

### Testing Checklist
- [ ] Connection saves properly
- [ ] Delete connection works
- [ ] Content loads from remote
- [ ] Posts migrate successfully
- [ ] URLs are replaced correctly
- [ ] Images download and upload
- [ ] Deduplication prevents duplicates
- [ ] Conflict resolution works (all three modes)
- [ ] Logs are created
- [ ] No PHP errors in debug.log

### Future Roadmap
See PROJECT.md for detailed development plans.

## Support

For issues or questions:
1. Check debug.log for error messages
2. Verify all requirements are met
3. Test with simple content first
4. Review troubleshooting section

## License

GPL v2 or later

## Changelog

### 2.2.8
- Adding telemetry to help improving the plugin.
- Restored and enhanced the 'View details' plugin information page with better documentation and brand assets.

### 2.2.7
- Improved Media Path Preservation to ensure folder structures are maintained during transfers.
- Hardened Beaver Builder support for more reliable complex layout migrations.
- Implemented a promotional UI for the Migro Beta program for Free users.
- General stability improvements and minor bug fixes.

### 2.2.6
- Enhanced remote connection authentication with advanced Sodium encryption capabilities.
- Improved media deduplication logic to prevent redundant file uploads during complex migrations.
- Expanded page builder compatibility by refining URL rewriting processes.
- Resolved minor issues to ensure complete media metadata preservation during transfers.

## Credits

Built to solve the common WordPress development problem of selective content migration between environments.

---

**Current Version**: 2.2.8
**Status**: Stable release with secure media, builder migration support, and opt-in telemetry
