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:
@@ -22,6 +22,7 @@ class ProductVersion
|
||||
private int $patchVersion;
|
||||
private ?string $releaseNotes;
|
||||
private ?string $downloadUrl;
|
||||
private ?int $attachmentId;
|
||||
private bool $isActive;
|
||||
private \DateTimeInterface $releasedAt;
|
||||
private \DateTimeInterface $createdAt;
|
||||
@@ -40,6 +41,7 @@ class ProductVersion
|
||||
$version->patchVersion = (int) $data['patch_version'];
|
||||
$version->releaseNotes = $data['release_notes'] ?: null;
|
||||
$version->downloadUrl = $data['download_url'] ?: null;
|
||||
$version->attachmentId = !empty($data['attachment_id']) ? (int) $data['attachment_id'] : null;
|
||||
$version->isActive = (bool) $data['is_active'];
|
||||
$version->releasedAt = new \DateTimeImmutable($data['released_at']);
|
||||
$version->createdAt = new \DateTimeImmutable($data['created_at']);
|
||||
@@ -60,6 +62,36 @@ class ProductVersion
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* Extract version from filename
|
||||
*
|
||||
* Supports patterns like:
|
||||
* - product-name-v1.2.3.zip
|
||||
* - product-name-1.2.3.zip
|
||||
* - product_v1.2.3.zip
|
||||
* - v1.2.3.zip
|
||||
*/
|
||||
public static function extractVersionFromFilename(string $filename): ?string
|
||||
{
|
||||
// Remove extension
|
||||
$basename = pathinfo($filename, PATHINFO_FILENAME);
|
||||
|
||||
// Try various patterns
|
||||
$patterns = [
|
||||
'/[_-]v?(\d+\.\d+\.\d+)$/i', // ends with -v1.2.3 or -1.2.3
|
||||
'/[_-]v?(\d+\.\d+\.\d+)[_-]/i', // contains -v1.2.3- or -1.2.3-
|
||||
'/^v?(\d+\.\d+\.\d+)$/i', // just version number
|
||||
];
|
||||
|
||||
foreach ($patterns as $pattern) {
|
||||
if (preg_match($pattern, $basename, $matches)) {
|
||||
return $matches[1];
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public function getId(): int
|
||||
{
|
||||
return $this->id;
|
||||
@@ -100,6 +132,36 @@ class ProductVersion
|
||||
return $this->downloadUrl;
|
||||
}
|
||||
|
||||
public function getAttachmentId(): ?int
|
||||
{
|
||||
return $this->attachmentId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the effective download URL (from attachment or direct URL)
|
||||
*/
|
||||
public function getEffectiveDownloadUrl(): ?string
|
||||
{
|
||||
if ($this->attachmentId) {
|
||||
return wp_get_attachment_url($this->attachmentId) ?: null;
|
||||
}
|
||||
return $this->downloadUrl;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the filename for download
|
||||
*/
|
||||
public function getDownloadFilename(): ?string
|
||||
{
|
||||
if ($this->attachmentId) {
|
||||
return wp_basename(get_attached_file($this->attachmentId) ?: '');
|
||||
}
|
||||
if ($this->downloadUrl) {
|
||||
return wp_basename($this->downloadUrl);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public function isActive(): bool
|
||||
{
|
||||
return $this->isActive;
|
||||
@@ -129,6 +191,7 @@ class ProductVersion
|
||||
'patch_version' => $this->patchVersion,
|
||||
'release_notes' => $this->releaseNotes,
|
||||
'download_url' => $this->downloadUrl,
|
||||
'attachment_id' => $this->attachmentId,
|
||||
'is_active' => $this->isActive,
|
||||
'released_at' => $this->releasedAt->format('Y-m-d H:i:s'),
|
||||
'created_at' => $this->createdAt->format('Y-m-d H:i:s'),
|
||||
|
||||
Reference in New Issue
Block a user