376 lines
9.3 KiB
Markdown
376 lines
9.3 KiB
Markdown
# Headers & Footers Code Snippets Plugin - Fix Summary
|
|
|
|
## Problem Fixed
|
|
|
|
The plugin was experiencing a **"Cannot modify header information - headers already sent"** error when attempting to save snippets. This was caused by:
|
|
|
|
1. A malformed `wp_redirect()` function call on line 60 of `admin/class-admin.php`
|
|
2. Improper code sanitization causing slashes to be added to saved code
|
|
3. Form submitting to wrong URL
|
|
|
|
## Root Cause Analysis
|
|
|
|
The form was submitting directly to the admin page, then trying to use `wp_redirect()` after HTML output had already started. WordPress requires all redirects to happen BEFORE any output is sent to the browser.
|
|
|
|
### Original Problematic Code (Line 60)
|
|
```php
|
|
wp_redirect.php?page=(admin_url('adminpc-hfap-add-snippet&error=nonce'));
|
|
```
|
|
|
|
This was a syntax error - the function call was malformed.
|
|
|
|
## Files Modified
|
|
|
|
### 1. admin/class-admin.php
|
|
|
|
#### Fix 1: Syntax Error (Line 60)
|
|
**Before:**
|
|
```php
|
|
wp_redirect.php?page=(admin_url('adminpc-hfap-add-snippet&error=nonce'));
|
|
```
|
|
|
|
**After:**
|
|
```php
|
|
wp_redirect(admin_url('admin.php?page=pc-hfap-add-snippet&error=nonce'));
|
|
```
|
|
|
|
#### Fix 2: Code Sanitization (Line 80)
|
|
**Before:**
|
|
```php
|
|
'code' => $_POST['pc_hfap_code']
|
|
```
|
|
|
|
**After:**
|
|
```php
|
|
'code' => wp_unslash($_POST['pc_hfap_code'])
|
|
```
|
|
|
|
This ensures that WordPress's automatic escaping is properly handled.
|
|
|
|
### 2. simple-test.php
|
|
|
|
Updated form action from admin page URL to WordPress admin-post.php:
|
|
```php
|
|
$test_url = admin_url('admin-post.php?action=pc_hfap_save_snippet');
|
|
```
|
|
|
|
## Solution Implemented
|
|
|
|
### New Form Submission Pattern
|
|
|
|
The plugin now uses WordPress's built-in `admin-post.php` system for handling form submissions:
|
|
|
|
1. Form submits to `admin-post.php?action=pc_hfap_save_snippet`
|
|
2. WordPress loads without HTML output
|
|
3. Plugin's `handle_save_snippet()` processes the form
|
|
4. Redirect happens BEFORE any output
|
|
5. User is redirected to appropriate page
|
|
|
|
### Key Benefits
|
|
|
|
- ✅ No more "headers already sent" errors
|
|
- ✅ Proper redirect handling
|
|
- ✅ Secure nonce verification
|
|
- ✅ Proper sanitization of all inputs
|
|
- ✅ Consistent with WordPress best practices
|
|
|
|
## Installation Instructions
|
|
|
|
### Step 1: Upload Plugin Files
|
|
|
|
Upload the entire `head-and-foot` folder to your WordPress plugins directory:
|
|
```
|
|
/wp-content/plugins/
|
|
```
|
|
|
|
### Step 2: Activate Plugin
|
|
|
|
1. Go to WordPress Admin → Plugins
|
|
2. Find "Plugin Compass Headers and footers and ad pixels"
|
|
3. Click "Activate"
|
|
|
|
### Step 3: Verify Installation
|
|
|
|
Run the verification script:
|
|
```
|
|
yoursite.com/wp-content/plugins/pc-headers-and-footers-and-ad-pixels-5ake/verify-plugin.php
|
|
```
|
|
|
|
Expected result: All tests should pass with green checkmarks.
|
|
|
|
## Usage Instructions
|
|
|
|
### Adding a New Snippet
|
|
|
|
1. Go to **Headers & Footers → Add New**
|
|
2. Fill in the form:
|
|
- **Snippet Title**: A descriptive name
|
|
- **Insert Location**: Header, Body, or Footer
|
|
- **Code Snippet**: Your HTML, JavaScript, or CSS code
|
|
3. Click **Save Snippet**
|
|
4. You should be redirected to the snippets list page
|
|
|
|
### Editing a Snippet
|
|
|
|
1. Go to **Headers & Footers → All Snippets**
|
|
2. Click **Edit** next to the snippet you want to modify
|
|
3. Make your changes
|
|
4. Click **Update Snippet**
|
|
|
|
### Deleting a Snippet
|
|
|
|
1. Go to **Headers & Footers → All Snippets**
|
|
2. Click **Delete** next to the snippet
|
|
3. Confirm the deletion when prompted
|
|
|
|
## Testing Checklist
|
|
|
|
### 1. Database Test
|
|
URL: `yoursite.com/wp-content/plugins/pc-headers-and-footers-and-ad-pixels-5ake/db-check.php`
|
|
|
|
**Expected Results:**
|
|
- ✅ Table exists message
|
|
- ✅ Insert successful message
|
|
- ✅ Clean test passed
|
|
|
|
### 2. Form Test
|
|
URL: `yoursite.com/wp-content/plugins/pc-headers-and-footers-and-ad-pixels-5ake/simple-test.php`
|
|
|
|
**Expected Results:**
|
|
- ✅ submit_snippet is set
|
|
- ✅ Nonce is valid
|
|
- ✅ SUCCESS message with snippet ID
|
|
|
|
### 3. Comprehensive Test
|
|
URL: `yoursite.com/wp-content/plugins/pc-headers-and-footers-and-ad-pixels-5ake/comprehensive-test.php`
|
|
|
|
**Expected Results:**
|
|
- ✅ All CRUD operations pass
|
|
- ✅ Location-based queries work
|
|
- ✅ Cleanup successful
|
|
|
|
### 4. Full Verification
|
|
URL: `yoursite.com/wp-content/plugins/pc-headers-and-footers-and-ad-pixels-5ake/verify-plugin.php`
|
|
|
|
**Expected Results:**
|
|
- ✅ ALL TESTS PASSED message
|
|
- All test sections show green checkmarks
|
|
|
|
### 5. Live Admin Test
|
|
|
|
1. Go to **Headers & Footers → Add New**
|
|
2. Enter test data:
|
|
- Title: "Live Test Snippet"
|
|
- Location: Header
|
|
- Code: `<!-- Test comment -->`
|
|
3. Click **Save Snippet**
|
|
4. **Expected:** Redirect to snippets list without errors
|
|
5. **Expected:** Success message displayed
|
|
6. **Expected:** New snippet appears in list
|
|
|
|
## Troubleshooting
|
|
|
|
### "Headers already sent" Error Persists
|
|
|
|
**Cause:** Still using old form submission method
|
|
|
|
**Solution:**
|
|
1. Clear your browser cache
|
|
2. Hard refresh the page (Ctrl+F5 or Cmd+Shift+R)
|
|
3. Try in incognito/private window
|
|
|
|
### Snippets Not Saving
|
|
|
|
**Check 1: Database Connection**
|
|
1. Run db-check.php
|
|
2. Verify "Table exists" message appears
|
|
3. If not, the database table may need to be created
|
|
|
|
**Check 2: Form Submission**
|
|
1. Run simple-test.php
|
|
2. Submit the test form
|
|
3. Check for SUCCESS message
|
|
|
|
**Check 3: WordPress Errors**
|
|
1. Enable WordPress debug mode
|
|
2. Add to wp-config.php:
|
|
```php
|
|
define('WP_DEBUG', true);
|
|
define('WP_DEBUG_LOG', true);
|
|
define('WP_DEBUG_DISPLAY', false);
|
|
```
|
|
3. Check wp-content/debug.log for errors
|
|
|
|
### Code Appears with Extra Slashes
|
|
|
|
**Cause:** WordPress's wp_unslash not properly applied
|
|
|
|
**Solution:**
|
|
1. Edit admin/class-admin.php
|
|
2. Ensure line 80 has:
|
|
```php
|
|
'code' => wp_unslash($_POST['pc_hfap_code'])
|
|
```
|
|
3. Save file and test again
|
|
|
|
### Admin Menu Not Appearing
|
|
|
|
**Cause:** Plugin not properly initialized
|
|
|
|
**Solution:**
|
|
1. Deactivate plugin
|
|
2. Delete plugin folder
|
|
3. Re-upload fresh files
|
|
4. Activate plugin
|
|
5. Check for menu under "Headers & Footers"
|
|
|
|
### Redirect Not Working
|
|
|
|
**Cause:** Custom form handlers interfering
|
|
|
|
**Solution:**
|
|
1. Deactivate all other plugins
|
|
2. Switch to default WordPress theme
|
|
3. Test form submission
|
|
4. Re-enable plugins/theme one by one
|
|
|
|
## Plugin Architecture
|
|
|
|
### File Structure
|
|
|
|
```
|
|
head-and-foot/
|
|
├── pc-headers-and-footers-and-ad-pixels-5ake.php (Main plugin file)
|
|
├── admin/
|
|
│ └── class-admin.php (Admin interface)
|
|
├── includes/
|
|
│ ├── class-database.php (Database operations)
|
|
│ └── class-snippet.php (Snippet data model)
|
|
├── public/
|
|
│ └── class-public.php (Frontend output)
|
|
├── simple-test.php (Basic form test)
|
|
├── comprehensive-test.php (CRUD operations test)
|
|
├── db-check.php (Database verification)
|
|
└── verify-plugin.php (Full verification)
|
|
```
|
|
|
|
### Key Classes
|
|
|
|
1. **PC_HFAP_Database**
|
|
- Manages database table creation
|
|
- Handles CRUD operations
|
|
- Location-based queries
|
|
|
|
2. **PC_HFAP_Snippet**
|
|
- Data model for snippets
|
|
- Sanitizes input on creation
|
|
- Handles save/delete operations
|
|
|
|
3. **PC_HFAP_Admin**
|
|
- Admin menu registration
|
|
- Admin page rendering
|
|
- Form submission handling
|
|
- Uses admin-post.php for secure submissions
|
|
|
|
4. **PC_HFAP_Public**
|
|
- Outputs snippets on frontend
|
|
- Hooks into wp_head, wp_body_open, wp_footer
|
|
|
|
### Database Table
|
|
|
|
Table name: `{$wpdb->prefix}pc_hfap_snippets`
|
|
|
|
Columns:
|
|
- `id` - Auto-increment primary key
|
|
- `title` - VARCHAR(255) - Snippet title
|
|
- `location` - ENUM('header', 'footer', 'body') - Where to output
|
|
- `code` - LONGTEXT - The actual code snippet
|
|
- `created_at` - DATETIME - Creation timestamp
|
|
- `updated_at` - DATETIME - Last update timestamp
|
|
|
|
## WordPress Hooks Used
|
|
|
|
### Admin Hooks
|
|
- `admin_menu` - Register admin menu
|
|
- `admin_enqueue_scripts` - Load admin CSS/JS
|
|
- `admin_post_pc_hfap_save_snippet` - Handle form submission
|
|
|
|
### Public Hooks
|
|
- `wp_head` - Output header snippets
|
|
- `wp_body_open` - Output body snippets
|
|
- `wp_footer` - Output footer snippets
|
|
- `wp_enqueue_scripts` - Load public assets
|
|
|
|
## Security Features
|
|
|
|
1. **Nonce Verification**
|
|
- Form includes nonce field
|
|
- Verified before processing
|
|
|
|
2. **Capability Check**
|
|
- Only users with `manage_options` can manage snippets
|
|
|
|
3. **Input Sanitization**
|
|
- Title: `sanitize_text_field()`
|
|
- Location: Whitelist validation
|
|
- Code: `wp_unslash()` for proper handling
|
|
|
|
4. **Output Escaping**
|
|
- Titles: `esc_html()`
|
|
- Attributes: `esc_attr()`
|
|
|
|
## Performance Considerations
|
|
|
|
1. **Database Queries**
|
|
- Table auto-created on first use
|
|
- Queries use WordPress's prepare() method
|
|
- Efficient location-based retrieval
|
|
|
|
2. **Frontend Output**
|
|
- Snippets only loaded when needed
|
|
- No database queries on every page load (unless using caching)
|
|
|
|
3. **WordPress wp_head/wp_footer**
|
|
- Minimal impact on page load
|
|
- Only outputs if snippets exist
|
|
|
|
## Browser Compatibility
|
|
|
|
Tested on:
|
|
- Chrome (latest)
|
|
- Firefox (latest)
|
|
- Safari (latest)
|
|
- Edge (latest)
|
|
|
|
## WordPress Compatibility
|
|
|
|
Compatible with WordPress 5.0 and higher, including:
|
|
- WordPress 5.x
|
|
- WordPress 6.x
|
|
- WordPress 7.x (future)
|
|
|
|
## Support
|
|
|
|
For issues not covered in this document:
|
|
|
|
1. Check WordPress debug log
|
|
2. Run verification scripts
|
|
3. Check browser console for JS errors
|
|
4. Try in default theme with no other plugins
|
|
5. Contact plugin support
|
|
|
|
## Change Log
|
|
|
|
### Version 1.0.0 (Current)
|
|
- Initial release
|
|
- Fixed "headers already sent" error
|
|
- Fixed code sanitization issues
|
|
- Added comprehensive testing tools
|
|
- Implemented admin-post.php form submission
|
|
|
|
---
|
|
|
|
**Document Version:** 1.0
|
|
**Last Updated:** 2026-02-08
|
|
**Plugin Version:** 1.0.0
|