## ✅ Issue 1: Standalone Mode Navigation **Problem:** Standalone mode not getting WNW_NAV_TREE from PHP **Fixed:** Added WNW_NAV_TREE injection to StandaloneAdmin.php **Result:** Navigation now works in standalone mode with PHP as single source ## ✅ Issue 2: 404 Errors for branding and customer-settings **Problem:** REST URLs had trailing slashes causing double slashes **Root Cause:** - `rest_url("woonoow/v1")` returns `https://site.com/wp-json/woonoow/v1/` - Frontend: `restUrl + "/store/branding"` = double slash - WP-admin missing WNW_CONFIG entirely **Fixed:** 1. **Removed trailing slashes** from all REST URLs using `untrailingslashit()` - StandaloneAdmin.php - Assets.php (dev and prod modes) 2. **Added WNW_CONFIG to wp-admin** for API compatibility - Dev mode: Added WNW_CONFIG with restUrl, nonce, standaloneMode, etc. - Prod mode: Added WNW_CONFIG to localize_runtime() - Now both modes use same config structure **Result:** - ✅ `/store/branding` works in all modes - ✅ `/store/customer-settings` works in all modes - ✅ Consistent API access across standalone and wp-admin ## ✅ Issue 3: SVG Upload Error 500 **Problem:** WordPress blocks SVG uploads by default **Security:** "Sorry, you are not allowed to upload this file type" **Fixed:** Created MediaUpload.php with: 1. **Allow SVG uploads** for users with upload_files capability 2. **Fix SVG mime type detection** (WordPress issue) 3. **Sanitize SVG on upload** - reject files with: - `<script>` tags - `javascript:` protocols - Event handlers (onclick, onload, etc.) **Result:** - ✅ SVG uploads work securely - ✅ Dangerous SVG content blocked - ✅ Only authorized users can upload --- ## Files Modified: - `StandaloneAdmin.php` - Add nav tree + fix REST URL - `Assets.php` - Add WNW_CONFIG + fix REST URLs - `Bootstrap.php` - Initialize MediaUpload - `MediaUpload.php` - NEW: SVG upload support with security ## Testing: 1. ✅ Navigation works in standalone mode 2. ✅ Branding endpoint works in all modes 3. ✅ Customer settings endpoint works in all modes 4. ✅ SVG logo upload works 5. ✅ Dangerous SVG files rejected
108 lines
2.5 KiB
PHP
108 lines
2.5 KiB
PHP
<?php
|
|
/**
|
|
* Media Upload Handler
|
|
*
|
|
* Handles file uploads including SVG support with security checks.
|
|
*
|
|
* @package WooNooW
|
|
*/
|
|
|
|
namespace WooNooW\Core;
|
|
|
|
class MediaUpload {
|
|
|
|
/**
|
|
* Initialize media upload hooks
|
|
*/
|
|
public static function init() {
|
|
// Allow SVG uploads
|
|
add_filter( 'upload_mimes', [ __CLASS__, 'allow_svg_upload' ] );
|
|
|
|
// Fix SVG mime type detection
|
|
add_filter( 'wp_check_filetype_and_ext', [ __CLASS__, 'fix_svg_mime_type' ], 10, 5 );
|
|
|
|
// Sanitize SVG on upload
|
|
add_filter( 'wp_handle_upload_prefilter', [ __CLASS__, 'sanitize_svg_upload' ] );
|
|
}
|
|
|
|
/**
|
|
* Allow SVG file uploads
|
|
*
|
|
* @param array $mimes Allowed mime types
|
|
* @return array Modified mime types
|
|
*/
|
|
public static function allow_svg_upload( $mimes ) {
|
|
// Only allow for users with upload_files capability
|
|
if ( ! current_user_can( 'upload_files' ) ) {
|
|
return $mimes;
|
|
}
|
|
|
|
$mimes['svg'] = 'image/svg+xml';
|
|
$mimes['svgz'] = 'image/svg+xml';
|
|
|
|
return $mimes;
|
|
}
|
|
|
|
/**
|
|
* Fix SVG mime type detection
|
|
*
|
|
* @param array $data File data
|
|
* @param string $file File path
|
|
* @param string $filename File name
|
|
* @param array $mimes Allowed mimes
|
|
* @param string $real_mime Real mime type
|
|
* @return array Modified file data
|
|
*/
|
|
public static function fix_svg_mime_type( $data, $file, $filename, $mimes, $real_mime ) {
|
|
if ( ! $data['ext'] && ! $data['type'] ) {
|
|
$wp_filetype = wp_check_filetype( $filename, $mimes );
|
|
$ext = $wp_filetype['ext'];
|
|
$type = $wp_filetype['type'];
|
|
|
|
if ( $ext === 'svg' || $ext === 'svgz' ) {
|
|
$data['ext'] = $ext;
|
|
$data['type'] = $type;
|
|
}
|
|
}
|
|
|
|
return $data;
|
|
}
|
|
|
|
/**
|
|
* Sanitize SVG files on upload
|
|
*
|
|
* @param array $file Upload file data
|
|
* @return array Modified file data
|
|
*/
|
|
public static function sanitize_svg_upload( $file ) {
|
|
// Only process SVG files
|
|
if ( $file['type'] !== 'image/svg+xml' ) {
|
|
return $file;
|
|
}
|
|
|
|
// Read file content
|
|
$svg_content = file_get_contents( $file['tmp_name'] );
|
|
|
|
if ( $svg_content === false ) {
|
|
$file['error'] = __( 'Could not read SVG file', 'woonoow' );
|
|
return $file;
|
|
}
|
|
|
|
// Basic security check - reject if contains script tags or event handlers
|
|
$dangerous_patterns = [
|
|
'/<script/i',
|
|
'/javascript:/i',
|
|
'/on\w+\s*=/i', // onclick, onload, etc.
|
|
];
|
|
|
|
foreach ( $dangerous_patterns as $pattern ) {
|
|
if ( preg_match( $pattern, $svg_content ) ) {
|
|
$file['error'] = __( 'SVG file contains potentially dangerous content', 'woonoow' );
|
|
return $file;
|
|
}
|
|
}
|
|
|
|
return $file;
|
|
}
|
|
}
|