You've already forked wc-licensed-product
Implement version 0.0.3 features
- Add file attachment support for product versions (Media Library) - Add version auto-detection from uploaded filenames - Implement secure customer downloads with hash verification - Add license key copy-to-clipboard functionality - Redesign customer licenses page with card-based UI - Fix product versions meta box visibility for non-licensed types - Add DownloadController for secure file delivery - Update CLAUDE.md roadmap and session history Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
@@ -61,12 +61,6 @@ final class VersionAdminController
|
||||
*/
|
||||
public function renderVersionsMetaBox(\WP_Post $post): void
|
||||
{
|
||||
$product = wc_get_product($post->ID);
|
||||
if (!$product || !$product->is_type('licensed')) {
|
||||
echo '<p>' . esc_html__('This meta box is only available for Licensed Products.', 'wc-licensed-product') . '</p>';
|
||||
return;
|
||||
}
|
||||
|
||||
$versions = $this->versionManager->getVersionsByProduct($post->ID);
|
||||
wp_nonce_field('wc_licensed_product_versions', 'wc_licensed_product_versions_nonce');
|
||||
?>
|
||||
@@ -82,10 +76,24 @@ final class VersionAdminController
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><label for="new_download_url"><?php esc_html_e('Download URL', 'wc-licensed-product'); ?></label></th>
|
||||
<th><label for="new_attachment_id"><?php esc_html_e('Download File', 'wc-licensed-product'); ?></label></th>
|
||||
<td>
|
||||
<input type="hidden" id="new_attachment_id" name="new_attachment_id" value="" />
|
||||
<span id="selected_file_name" class="selected-file-name"></span>
|
||||
<button type="button" class="button" id="upload-version-file-btn">
|
||||
<?php esc_html_e('Select File', 'wc-licensed-product'); ?>
|
||||
</button>
|
||||
<button type="button" class="button" id="remove-version-file-btn" style="display: none;">
|
||||
<?php esc_html_e('Remove', 'wc-licensed-product'); ?>
|
||||
</button>
|
||||
<p class="description"><?php esc_html_e('Upload or select a file from the media library. Version will be auto-detected from filename (e.g., plugin-v1.2.3.zip).', 'wc-licensed-product'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<th><label for="new_download_url"><?php esc_html_e('Or External URL', 'wc-licensed-product'); ?></label></th>
|
||||
<td>
|
||||
<input type="url" id="new_download_url" name="new_download_url" class="large-text" placeholder="https://" />
|
||||
<p class="description"><?php esc_html_e('URL to the downloadable file for this version.', 'wc-licensed-product'); ?></p>
|
||||
<p class="description"><?php esc_html_e('Alternative: Enter an external download URL instead of uploading a file.', 'wc-licensed-product'); ?></p>
|
||||
</td>
|
||||
</tr>
|
||||
<tr>
|
||||
@@ -110,7 +118,7 @@ final class VersionAdminController
|
||||
<thead>
|
||||
<tr>
|
||||
<th><?php esc_html_e('Version', 'wc-licensed-product'); ?></th>
|
||||
<th><?php esc_html_e('Download URL', 'wc-licensed-product'); ?></th>
|
||||
<th><?php esc_html_e('Download File', 'wc-licensed-product'); ?></th>
|
||||
<th><?php esc_html_e('Release Notes', 'wc-licensed-product'); ?></th>
|
||||
<th><?php esc_html_e('Status', 'wc-licensed-product'); ?></th>
|
||||
<th><?php esc_html_e('Released', 'wc-licensed-product'); ?></th>
|
||||
@@ -127,12 +135,19 @@ final class VersionAdminController
|
||||
<tr data-version-id="<?php echo esc_attr($version->getId()); ?>">
|
||||
<td><strong><?php echo esc_html($version->getVersion()); ?></strong></td>
|
||||
<td>
|
||||
<?php if ($version->getDownloadUrl()): ?>
|
||||
<a href="<?php echo esc_url($version->getDownloadUrl()); ?>" target="_blank">
|
||||
<?php echo esc_html(wp_basename($version->getDownloadUrl())); ?>
|
||||
<?php
|
||||
$effectiveUrl = $version->getEffectiveDownloadUrl();
|
||||
$filename = $version->getDownloadFilename();
|
||||
if ($effectiveUrl):
|
||||
?>
|
||||
<a href="<?php echo esc_url($effectiveUrl); ?>" target="_blank">
|
||||
<?php echo esc_html($filename ?: wp_basename($effectiveUrl)); ?>
|
||||
</a>
|
||||
<?php if ($version->getAttachmentId()): ?>
|
||||
<span class="dashicons dashicons-media-archive" title="<?php esc_attr_e('Uploaded file', 'wc-licensed-product'); ?>"></span>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<em><?php esc_html_e('No download URL', 'wc-licensed-product'); ?></em>
|
||||
<em><?php esc_html_e('No download file', 'wc-licensed-product'); ?></em>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?php echo esc_html($version->getReleaseNotes() ? wp_trim_words($version->getReleaseNotes(), 10) : '—'); ?></td>
|
||||
@@ -173,6 +188,9 @@ final class VersionAdminController
|
||||
return;
|
||||
}
|
||||
|
||||
// Enqueue WordPress media uploader
|
||||
wp_enqueue_media();
|
||||
|
||||
wp_enqueue_script(
|
||||
'wc-licensed-product-versions',
|
||||
WC_LICENSED_PRODUCT_PLUGIN_URL . 'assets/js/versions.js',
|
||||
@@ -189,6 +207,8 @@ final class VersionAdminController
|
||||
'versionRequired' => __('Please enter a version number.', 'wc-licensed-product'),
|
||||
'versionInvalid' => __('Please enter a valid version number (e.g., 1.0.0).', 'wc-licensed-product'),
|
||||
'error' => __('An error occurred. Please try again.', 'wc-licensed-product'),
|
||||
'selectFile' => __('Select Download File', 'wc-licensed-product'),
|
||||
'useThisFile' => __('Use this file', 'wc-licensed-product'),
|
||||
],
|
||||
]);
|
||||
|
||||
@@ -215,6 +235,7 @@ final class VersionAdminController
|
||||
$version = sanitize_text_field($_POST['version'] ?? '');
|
||||
$downloadUrl = esc_url_raw($_POST['download_url'] ?? '');
|
||||
$releaseNotes = sanitize_textarea_field($_POST['release_notes'] ?? '');
|
||||
$attachmentId = absint($_POST['attachment_id'] ?? 0);
|
||||
|
||||
if (!$productId || !$version) {
|
||||
wp_send_json_error(['message' => __('Product ID and version are required.', 'wc-licensed-product')]);
|
||||
@@ -234,7 +255,8 @@ final class VersionAdminController
|
||||
$productId,
|
||||
$version,
|
||||
$releaseNotes ?: null,
|
||||
$downloadUrl ?: null
|
||||
$downloadUrl ?: null,
|
||||
$attachmentId ?: null
|
||||
);
|
||||
|
||||
if (!$newVersion) {
|
||||
@@ -317,12 +339,19 @@ final class VersionAdminController
|
||||
<tr data-version-id="<?php echo esc_attr($version->getId()); ?>">
|
||||
<td><strong><?php echo esc_html($version->getVersion()); ?></strong></td>
|
||||
<td>
|
||||
<?php if ($version->getDownloadUrl()): ?>
|
||||
<a href="<?php echo esc_url($version->getDownloadUrl()); ?>" target="_blank">
|
||||
<?php echo esc_html(wp_basename($version->getDownloadUrl())); ?>
|
||||
<?php
|
||||
$effectiveUrl = $version->getEffectiveDownloadUrl();
|
||||
$filename = $version->getDownloadFilename();
|
||||
if ($effectiveUrl):
|
||||
?>
|
||||
<a href="<?php echo esc_url($effectiveUrl); ?>" target="_blank">
|
||||
<?php echo esc_html($filename ?: wp_basename($effectiveUrl)); ?>
|
||||
</a>
|
||||
<?php if ($version->getAttachmentId()): ?>
|
||||
<span class="dashicons dashicons-media-archive" title="<?php esc_attr_e('Uploaded file', 'wc-licensed-product'); ?>"></span>
|
||||
<?php endif; ?>
|
||||
<?php else: ?>
|
||||
<em><?php esc_html_e('No download URL', 'wc-licensed-product'); ?></em>
|
||||
<em><?php esc_html_e('No download file', 'wc-licensed-product'); ?></em>
|
||||
<?php endif; ?>
|
||||
</td>
|
||||
<td><?php echo esc_html($version->getReleaseNotes() ? wp_trim_words($version->getReleaseNotes(), 10) : '—'); ?></td>
|
||||
|
||||
Reference in New Issue
Block a user