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, ?int $attachmentId = null ): ?ProductVersion { global $wpdb; $parsed = ProductVersion::parseVersion($version); $tableName = Installer::getVersionsTable(); // Build data and formats arrays, handling null values properly $data = [ '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, ]; $formats = ['%d', '%s', '%d', '%d', '%d', '%s', '%s', '%d']; // Only include attachment_id if it's set if ($attachmentId !== null && $attachmentId > 0) { $data['attachment_id'] = $attachmentId; $formats[] = '%d'; } $result = $wpdb->insert($tableName, $data, $formats); if ($result === false) { // Log error for debugging error_log('WC Licensed Product: Failed to create version - ' . $wpdb->last_error); 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, ?int $attachmentId = 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 ($attachmentId !== null) { if ($attachmentId > 0) { $data['attachment_id'] = $attachmentId; $formats[] = '%d'; } else { // Set to NULL using raw SQL instead of adding to $data global $wpdb; $tableName = Installer::getVersionsTable(); $wpdb->query( $wpdb->prepare( "UPDATE {$tableName} SET attachment_id = NULL WHERE id = %d", $versionId ) ); } } 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; } }