Files
wc-licensed-product/src/Product/ProductVersion.php
magdev 034593f896 Dashboard widget improvements and download counter feature (v0.3.7)
- Fixed: Dashboard widget "View All Licenses" link used wrong page slug
- Fixed: Download links in customer account resulted in 404 errors
- Removed: Redundant "Status Breakdown" section from dashboard widget
- Changed: License Types section now uses card style layout
- Added: Download counter for licensed product versions
- Added: Download Statistics admin dashboard widget
- Updated translations (356 strings)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-24 10:17:46 +01:00

214 lines
5.5 KiB
PHP

<?php
/**
* Product Version Model
*
* @package Jeremias\WcLicensedProduct\Product
*/
declare(strict_types=1);
namespace Jeremias\WcLicensedProduct\Product;
/**
* Product version entity model
*/
class ProductVersion
{
private int $id;
private int $productId;
private string $version;
private int $majorVersion;
private int $minorVersion;
private int $patchVersion;
private ?string $releaseNotes;
private ?string $downloadUrl;
private ?int $attachmentId;
private ?string $fileHash;
private int $downloadCount;
private bool $isActive;
private \DateTimeInterface $releasedAt;
private \DateTimeInterface $createdAt;
/**
* Create version from database row
*/
public static function fromArray(array $data): self
{
$version = new self();
$version->id = (int) $data['id'];
$version->productId = (int) $data['product_id'];
$version->version = $data['version'];
$version->majorVersion = (int) $data['major_version'];
$version->minorVersion = (int) $data['minor_version'];
$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->fileHash = $data['file_hash'] ?? null;
$version->downloadCount = (int) ($data['download_count'] ?? 0);
$version->isActive = (bool) $data['is_active'];
$version->releasedAt = new \DateTimeImmutable($data['released_at']);
$version->createdAt = new \DateTimeImmutable($data['created_at']);
return $version;
}
/**
* Parse version string into components
*/
public static function parseVersion(string $versionString): array
{
$parts = explode('.', $versionString);
return [
'major' => (int) ($parts[0] ?? 0),
'minor' => (int) ($parts[1] ?? 0),
'patch' => (int) ($parts[2] ?? 0),
];
}
/**
* 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;
}
public function getProductId(): int
{
return $this->productId;
}
public function getVersion(): string
{
return $this->version;
}
public function getMajorVersion(): int
{
return $this->majorVersion;
}
public function getMinorVersion(): int
{
return $this->minorVersion;
}
public function getPatchVersion(): int
{
return $this->patchVersion;
}
public function getReleaseNotes(): ?string
{
return $this->releaseNotes;
}
public function getDownloadUrl(): ?string
{
return $this->downloadUrl;
}
public function getAttachmentId(): ?int
{
return $this->attachmentId;
}
public function getFileHash(): ?string
{
return $this->fileHash;
}
public function getDownloadCount(): int
{
return $this->downloadCount;
}
/**
* Get the download URL from attachment
*/
public function getEffectiveDownloadUrl(): ?string
{
if ($this->attachmentId) {
return wp_get_attachment_url($this->attachmentId) ?: null;
}
return null;
}
/**
* Get the filename for download
*/
public function getDownloadFilename(): ?string
{
if ($this->attachmentId) {
return wp_basename(get_attached_file($this->attachmentId) ?: '');
}
return null;
}
public function isActive(): bool
{
return $this->isActive;
}
public function getReleasedAt(): \DateTimeInterface
{
return $this->releasedAt;
}
public function getCreatedAt(): \DateTimeInterface
{
return $this->createdAt;
}
/**
* Convert to array
*/
public function toArray(): array
{
return [
'id' => $this->id,
'product_id' => $this->productId,
'version' => $this->version,
'major_version' => $this->majorVersion,
'minor_version' => $this->minorVersion,
'patch_version' => $this->patchVersion,
'release_notes' => $this->releaseNotes,
'download_url' => $this->downloadUrl,
'attachment_id' => $this->attachmentId,
'file_hash' => $this->fileHash,
'download_count' => $this->downloadCount,
'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'),
];
}
}