Overview
The WooCommerce Document Preview plugin (version 1.5.0) enables merchants to add document preview functionality to their WooCommerce product pages. It supports traditional file uploads (PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX, TXT) as well as embeddable URLs from Google Docs, Google Sheets, Google Slides, OneDrive, and Dropbox.
Plugin Information
- Plugin Name: Document Preview For WooCommerce
- Version: 1.5.0
- Author: Wbcom Designs
- Text Domain:
wc-document-preview - Minimum Requirements:
- WordPress 5.0+
- WooCommerce 3.0+
- PHP 7.4+
Architecture
The plugin follows the WordPress Plugin Boilerplate structure with clear separation between admin and public functionality:
woo-product-document-preview/
├── admin/ # Admin-specific functionality
├── includes/ # Core plugin files
├── public/ # Public-facing functionality
├── languages/ # Internationalization files
└── woo-product-document-preview.php # Main plugin file
Key Features
1. Multiple Document Support
- Add multiple documents per product
- Drag-and-drop reordering
- Individual naming for each document
2. File Type Support
- Traditional Files: PDF, DOC, DOCX, XLS, XLSX, PPT, PPTX, TXT
- Embeddable Services:
- Google Docs/Sheets/Slides
- OneDrive
- Dropbox (including new content-based URLs)
3. Preview Methods
- Google Docs Viewer for PDFs and Office files
- Native browser support for PDFs
- Custom iframe implementation for local development
- Thickbox modal integration
4. Local Development Support
- Universal preview support for all file types in local environments
- Custom preview endpoint with fallback options
- Automatic detection of local development environments
Core Classes
1. Main Plugin Class (Wc_Document_Preview)
Location: includes/class-wc-document-preview.php
class Wc_Document_Preview {
protected $loader;
protected $plugin_name = 'wc-document-preview';
protected $version = '1.0.0';
public function __construct() {
$this->load_dependencies();
$this->set_locale();
$this->define_constants();
$this->define_admin_hooks();
$this->define_public_hooks();
}
}
2. Admin Class (Wc_Document_Preview_Admin)
Location: admin/class-wc-document-preview-admin.php
Key properties:
private $allowed_file_types = array('pdf', 'doc', 'docx', 'xls', 'xlsx', 'ppt', 'pptx', 'txt');
private $allowed_mime_types = array(
'application/pdf',
'application/msword',
'application/vnd.openxmlformats-officedocument.wordprocessingml.document',
// ... other MIME types
);
private $embeddable_patterns = array(
'google_docs' => [...],
'google_sheets' => [...],
'dropbox' => [...]
);
3. Public Class (Wc_Document_Preview_Public)
Location: public/class-wc-document-preview-public.php
Handles front-end display and preview functionality.
Admin Functionality
Meta Box Implementation
The plugin adds a meta box to the WooCommerce product edit page:
public function wcdp_register_meta_boxes() {
add_meta_box(
'wc-preview-doc-mata-id',
__('Preview Documents', 'wc-document-preview'),
array($this, 'wcdp_display_callback'),
'product'
);
}
Document Management Interface
The admin interface provides:
- Document name input field
- File URL/sharing link input
- Media library upload button
- Add/Remove buttons for multiple documents
- Drag-and-drop sorting
Validation System
private function validate_document_file($file_url) {
// Check embeddable URLs first
$embed_info = $this->is_embeddable_url($file_url);
if ($embed_info) {
return array(
'success' => true,
'type' => 'embeddable',
'service' => $embed_info['service']
);
}
// Traditional file validation
$file_extension = strtolower(pathinfo($file_url, PATHINFO_EXTENSION));
if (!in_array($file_extension, $this->allowed_file_types, true)) {
return array('success' => false, 'message' => 'Invalid file type');
}
return array('success' => true, 'type' => 'file');
}
Public Functionality
Preview Button Generation
The plugin generates preview buttons with comprehensive metadata:
private function generate_preview_button($preview_url, $file_name, $validation) {
$button_class = 'wcdp-preview-btn thickbox button';
if ($this->is_local_environment() && $validation['type'] !== 'embeddable') {
$button_class .= ' wcdp-local-preview-btn wcdp-local-' . $validation['extension'];
}
return sprintf(
'
%s
',
esc_attr($button_class),
esc_url($final_url),
esc_attr($file_name),
esc_attr($validation['extension']),
$icon,
esc_html($button_text)
);
}
Local Preview Implementation
For local environments, the plugin creates a custom preview endpoint:
public function add_local_preview_rewrite_rule() {
add_rewrite_rule('^wcdp-local-preview/?$', 'index.php?wcdp_local_preview=1', 'top');
add_rewrite_tag('%wcdp_local_preview%', '([^&]+)');
}
Embeddable URL Support
Pattern Matching
The plugin uses comprehensive regex patterns to detect embeddable URLs:
'dropbox' => array(
// Legacy format
'/(?:www\.)?dropbox\.com\/s\/([a-zA-Z0-9_-]+)\/([^?\s]+)/i',
// New content-based format with rlkey
'/(?:www\.)?dropbox\.com\/scl\/fi\/([a-zA-Z0-9_-]+)\/(.+?)(?:\?|$)/i',
// Shared folders
'/(?:www\.)?dropbox\.com\/sh\/([a-zA-Z0-9_-]+)/i'
)
Embed URL Generation
private function generate_embed_url($embed_info) {
switch ($embed_info['service']) {
case 'google_docs':
return str_replace('{id}', $embed_info['id'],
'https://docs.google.com/document/d/{id}/preview');
case 'dropbox':
// Handle various Dropbox URL formats
if (strpos($original_url, '/scl/fi/') !== false) {
// New format - preserve parameters
$dropbox_url = str_replace('dl=0', 'raw=1', $original_url);
}
return $dropbox_url;
}
}
JavaScript Implementation
Admin JavaScript (admin/js/wc-document-preview-admin.js)
Key features:
- Real-time URL validation
- Embeddable URL detection
- Drag-and-drop sorting
- Media library integration
const WCDP = {
embeddablePatterns: {
google_docs: [
/docs\.google\.com\/document\/d\/([a-zA-Z0-9-_]+)/i
],
dropbox: [
/(?:www\.)?dropbox\.com\/scl\/fi\/([a-zA-Z0-9_-]+)\/.+?(?:\?|$)/i
]
},
detectEmbeddableUrl: function() {
const url = $(this).val();
const serviceInfo = WCDP.getEmbeddableServiceInfo(url);
if (serviceInfo) {
WCDP.showServiceIndicator($(this).closest('tr'), serviceInfo);
}
}
};
Form Validation
validateForm: function(e) {
$('.wcdp-document-file').each(function() {
const fileName = $.trim($row.find('.wcdp-file-name').val());
const fileUrl = $.trim($row.find('.wcdp_file_urls').val());
// Check embeddable first
const serviceInfo = WCDP.getEmbeddableServiceInfo(fileUrl);
if (serviceInfo) {
hasValidDocuments = true;
} else if (WCDP.isValidFileType(WCDP.getFileExtension(fileUrl))) {
hasValidDocuments = true;
} else {
errors.push('Invalid file type or unsupported URL');
}
});
}
CSS Structure
Admin CSS (admin/css/wc-document-preview-admin.css)
Key classes:
.wcdp-preview-tr– Sortable table rows.wcdp-embeddable-row– Highlighted embeddable URL rows.wcdp-service-indicator– Service detection badges.wcdp-error-box– Error message styling
Public CSS (public/css/wc-document-preview-public.css)
Key classes:
.wcdp-preview-container– Main container.wcdp-preview-btn– Preview button styling.wcdp-local-preview-btn– Local environment indicators.wcdp-service-badge– Service type badges
Database Structure
Post Meta Storage
Documents are stored as serialized arrays in post meta:
$wcdp_documents = array(
'wcdp_file_names' => array('Document 1', 'Document 2'),
'wcdp_file_urls' => array('url1', 'url2')
);
update_post_meta($post_id, 'wcdp_documents', $wcdp_documents);
Legacy Support
The plugin maintains backward compatibility with the old meta structure:
$legacy_preview = get_post_meta($post->ID, 'wcdp_preview_attachment', true);
Hooks and Filters
Actions
// Admin hooks
add_action('add_meta_boxes', array($this, 'wcdp_register_meta_boxes'));
add_action('save_post', array($this, 'wcdp_save_meta_box'));
add_action('admin_enqueue_scripts', array($this, 'enqueue_scripts'));
// Public hooks
add_action('woocommerce_after_add_to_cart_button', array($this, 'wcdp_add_preview_field'), 0);
add_action('template_redirect', array($this, 'wcdp_add_thickbox'));
AJAX Handlers
add_action('wp_ajax_wcdp_delete_document_ajax', array($this, 'wcdp_delete_document_ajax'));
Security Considerations
Nonce Verification
// In save_meta_box
$nonce_name = isset($_POST['wcdp_nonce']) ? $_POST['wcdp_nonce'] : '';
if (!wp_verify_nonce($nonce_name, 'wcdp_nonce_action')) {
return;
}
Capability Checks
if (!current_user_can('edit_post', $post_id)) {
return;
}
Data Sanitization
$file_name = sanitize_text_field($file_name);
$file_url = esc_url_raw($file_url);
Testing Guide
Local Environment Testing
- Setup: Install on localhost/local development environment
- Test file uploads: All file types should show local preview options
- Test embeddable URLs: Should work normally even in local environment
Production Testing
- File accessibility: Ensure files are publicly accessible
- CORS issues: Check for cross-origin errors in console
- SSL/HTTPS: Verify mixed content warnings are not present
Embeddable URL Testing
Test URLs:
- Google Docs:
https://docs.google.com/document/d/[ID]/edit - Dropbox new format:
https://www.dropbox.com/scl/fi/[ID]/filename.pdf?rlkey=[KEY]&dl=0 - OneDrive:
https://1drv.ms/w/s/[ID]
Troubleshooting
Common Issues
-
Preview not loading
- Check file URL accessibility
- Verify file type is supported
- Check browser console for errors
-
Embeddable URLs not detected
- Ensure URL matches expected patterns
- Check JavaScript console for pattern matching errors
-
Local preview issues
- Verify rewrite rules are flushed
- Check if local environment detection is working
Debug Mode
Enable WordPress debug mode to see detailed error messages:
define('WP_DEBUG', true);
define('WP_DEBUG_LOG', true);
define('WP_DEBUG_DISPLAY', false);
Error Logging
The plugin logs validation errors when WP_DEBUG is enabled:
if (defined('WP_DEBUG') && WP_DEBUG) {
error_log('WCDP Preview Error: ' . $validation['error']);
}
Best Practices
- Always validate URLs before saving to database
- Use proper escaping when outputting URLs and text
- Check file accessibility before displaying preview buttons
- Test across different browsers for compatibility
- Monitor performance with multiple documents per product
