You've already forked wc-licensed-product
Implement version 0.0.2 features
Add product version management: - ProductVersion model and VersionManager class - VersionAdminController with meta box on product edit page - AJAX-based version CRUD (add, delete, toggle status) - JavaScript for version management UI Add email notifications: - LicenseEmailController for order emails - License keys included in order completed emails - Support for both HTML and plain text emails Add REST API rate limiting: - 30 requests per minute per IP - Cloudflare and proxy-aware IP detection - HTTP 429 response with Retry-After header Other changes: - Bump version to 0.0.2 - Update CHANGELOG.md - Add version status styles to admin.css Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
This commit is contained in:
209
src/Product/VersionManager.php
Normal file
209
src/Product/VersionManager.php
Normal file
@@ -0,0 +1,209 @@
|
||||
<?php
|
||||
/**
|
||||
* Version Manager
|
||||
*
|
||||
* @package Jeremias\WcLicensedProduct\Product
|
||||
*/
|
||||
|
||||
declare(strict_types=1);
|
||||
|
||||
namespace Jeremias\WcLicensedProduct\Product;
|
||||
|
||||
use Jeremias\WcLicensedProduct\Installer;
|
||||
|
||||
/**
|
||||
* Manages product versions (CRUD operations)
|
||||
*/
|
||||
class VersionManager
|
||||
{
|
||||
/**
|
||||
* Get version by ID
|
||||
*/
|
||||
public function getVersionById(int $id): ?ProductVersion
|
||||
{
|
||||
global $wpdb;
|
||||
|
||||
$tableName = Installer::getVersionsTable();
|
||||
$row = $wpdb->get_row(
|
||||
$wpdb->prepare("SELECT * FROM {$tableName} WHERE id = %d", $id),
|
||||
ARRAY_A
|
||||
);
|
||||
|
||||
return $row ? ProductVersion::fromArray($row) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all versions for a product
|
||||
*/
|
||||
public function getVersionsByProduct(int $productId): array
|
||||
{
|
||||
global $wpdb;
|
||||
|
||||
$tableName = Installer::getVersionsTable();
|
||||
$rows = $wpdb->get_results(
|
||||
$wpdb->prepare(
|
||||
"SELECT * FROM {$tableName} WHERE product_id = %d ORDER BY major_version DESC, minor_version DESC, patch_version DESC",
|
||||
$productId
|
||||
),
|
||||
ARRAY_A
|
||||
);
|
||||
|
||||
return array_map(fn(array $row) => ProductVersion::fromArray($row), $rows ?: []);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get latest active version for a product
|
||||
*/
|
||||
public function getLatestVersion(int $productId): ?ProductVersion
|
||||
{
|
||||
global $wpdb;
|
||||
|
||||
$tableName = Installer::getVersionsTable();
|
||||
$row = $wpdb->get_row(
|
||||
$wpdb->prepare(
|
||||
"SELECT * FROM {$tableName} WHERE product_id = %d AND is_active = 1 ORDER BY major_version DESC, minor_version DESC, patch_version DESC LIMIT 1",
|
||||
$productId
|
||||
),
|
||||
ARRAY_A
|
||||
);
|
||||
|
||||
return $row ? ProductVersion::fromArray($row) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get latest version for a specific major version
|
||||
*/
|
||||
public function getLatestVersionForMajor(int $productId, int $majorVersion): ?ProductVersion
|
||||
{
|
||||
global $wpdb;
|
||||
|
||||
$tableName = Installer::getVersionsTable();
|
||||
$row = $wpdb->get_row(
|
||||
$wpdb->prepare(
|
||||
"SELECT * FROM {$tableName} WHERE product_id = %d AND major_version = %d AND is_active = 1 ORDER BY minor_version DESC, patch_version DESC LIMIT 1",
|
||||
$productId,
|
||||
$majorVersion
|
||||
),
|
||||
ARRAY_A
|
||||
);
|
||||
|
||||
return $row ? ProductVersion::fromArray($row) : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new version
|
||||
*/
|
||||
public function createVersion(
|
||||
int $productId,
|
||||
string $version,
|
||||
?string $releaseNotes = null,
|
||||
?string $downloadUrl = null
|
||||
): ?ProductVersion {
|
||||
global $wpdb;
|
||||
|
||||
$parsed = ProductVersion::parseVersion($version);
|
||||
|
||||
$tableName = Installer::getVersionsTable();
|
||||
$result = $wpdb->insert(
|
||||
$tableName,
|
||||
[
|
||||
'product_id' => $productId,
|
||||
'version' => $version,
|
||||
'major_version' => $parsed['major'],
|
||||
'minor_version' => $parsed['minor'],
|
||||
'patch_version' => $parsed['patch'],
|
||||
'release_notes' => $releaseNotes,
|
||||
'download_url' => $downloadUrl,
|
||||
'is_active' => 1,
|
||||
],
|
||||
['%d', '%s', '%d', '%d', '%d', '%s', '%s', '%d']
|
||||
);
|
||||
|
||||
if ($result === false) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return $this->getVersionById((int) $wpdb->insert_id);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update a version
|
||||
*/
|
||||
public function updateVersion(
|
||||
int $versionId,
|
||||
?string $releaseNotes = null,
|
||||
?string $downloadUrl = null,
|
||||
?bool $isActive = null
|
||||
): bool {
|
||||
global $wpdb;
|
||||
|
||||
$data = [];
|
||||
$formats = [];
|
||||
|
||||
if ($releaseNotes !== null) {
|
||||
$data['release_notes'] = $releaseNotes;
|
||||
$formats[] = '%s';
|
||||
}
|
||||
|
||||
if ($downloadUrl !== null) {
|
||||
$data['download_url'] = $downloadUrl;
|
||||
$formats[] = '%s';
|
||||
}
|
||||
|
||||
if ($isActive !== null) {
|
||||
$data['is_active'] = $isActive ? 1 : 0;
|
||||
$formats[] = '%d';
|
||||
}
|
||||
|
||||
if (empty($data)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$tableName = Installer::getVersionsTable();
|
||||
$result = $wpdb->update(
|
||||
$tableName,
|
||||
$data,
|
||||
['id' => $versionId],
|
||||
$formats,
|
||||
['%d']
|
||||
);
|
||||
|
||||
return $result !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete a version
|
||||
*/
|
||||
public function deleteVersion(int $versionId): bool
|
||||
{
|
||||
global $wpdb;
|
||||
|
||||
$tableName = Installer::getVersionsTable();
|
||||
$result = $wpdb->delete(
|
||||
$tableName,
|
||||
['id' => $versionId],
|
||||
['%d']
|
||||
);
|
||||
|
||||
return $result !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if version exists for product
|
||||
*/
|
||||
public function versionExists(int $productId, string $version): bool
|
||||
{
|
||||
global $wpdb;
|
||||
|
||||
$tableName = Installer::getVersionsTable();
|
||||
$count = $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"SELECT COUNT(*) FROM {$tableName} WHERE product_id = %d AND version = %s",
|
||||
$productId,
|
||||
$version
|
||||
)
|
||||
);
|
||||
|
||||
return (int) $count > 0;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user