Files
wc-licensed-product/src/Email/LicenseEmailController.php

295 lines
11 KiB
PHP
Raw Normal View History

<?php
/**
* License Email Controller
*
* @package Jeremias\WcLicensedProduct\Email
*/
declare(strict_types=1);
namespace Jeremias\WcLicensedProduct\Email;
use Jeremias\WcLicensedProduct\License\LicenseManager;
use Jeremias\WcLicensedProduct\Admin\SettingsController;
/**
* Handles email notifications for licenses
*/
final class LicenseEmailController
{
private LicenseManager $licenseManager;
public function __construct(LicenseManager $licenseManager)
{
$this->licenseManager = $licenseManager;
$this->registerHooks();
}
/**
* Register WordPress hooks
*/
private function registerHooks(): void
{
// Register custom WooCommerce email classes
add_filter('woocommerce_email_classes', [$this, 'registerEmailClasses']);
// Add license info to order completed email
add_action('woocommerce_email_after_order_table', [$this, 'addLicenseInfoToEmail'], 20, 4);
// Add license info to order details in emails
add_action('woocommerce_order_item_meta_end', [$this, 'addLicenseToOrderItem'], 10, 4);
// Schedule cron job for expiration warnings
add_action('init', [$this, 'scheduleExpirationCheck']);
// Cron action for checking expiring licenses
add_action('wclp_check_expiring_licenses', [$this, 'sendExpirationWarnings']);
}
/**
* Register custom email classes with WooCommerce
*
* @param array $email_classes Existing email classes
* @return array Modified email classes
*/
public function registerEmailClasses(array $email_classes): array
{
$email_classes['WCLP_License_Expiration'] = new LicenseExpirationEmail();
return $email_classes;
}
/**
* Schedule the expiration check cron job
*/
public function scheduleExpirationCheck(): void
{
if (!wp_next_scheduled('wclp_check_expiring_licenses')) {
wp_schedule_event(time(), 'daily', 'wclp_check_expiring_licenses');
}
}
/**
* Send expiration warning emails
*/
public function sendExpirationWarnings(): void
{
// Check if expiration emails are enabled in settings
if (!SettingsController::isExpirationEmailsEnabled()) {
return;
}
// Get the WooCommerce email instance
$mailer = WC()->mailer();
$emails = $mailer->get_emails();
if (!isset($emails['WCLP_License_Expiration'])) {
return;
}
/** @var LicenseExpirationEmail $expirationEmail */
$expirationEmail = $emails['WCLP_License_Expiration'];
// Check if the email is enabled
if (!$expirationEmail->is_enabled()) {
return;
}
// Get configurable warning days
$firstWarningDays = SettingsController::getFirstWarningDays();
$secondWarningDays = SettingsController::getSecondWarningDays();
// Check for licenses expiring at first warning threshold
$this->processExpirationWarnings($expirationEmail, $firstWarningDays, 'expiring_first_warning');
// Check for licenses expiring at second warning threshold (if enabled)
if ($secondWarningDays > 0 && $secondWarningDays < $firstWarningDays) {
$this->processExpirationWarnings($expirationEmail, $secondWarningDays, 'expiring_second_warning');
}
}
/**
* Process and send expiration warnings for a specific time frame
*
* @param LicenseExpirationEmail $email Email instance
* @param int $days Days until expiration
* @param string $notificationType Notification type identifier
*/
private function processExpirationWarnings(LicenseExpirationEmail $email, int $days, string $notificationType): void
{
$licenses = $this->licenseManager->getLicensesExpiringSoon($days);
foreach ($licenses as $license) {
// Skip if already notified
if ($this->licenseManager->wasExpirationNotified($license->getId(), $notificationType)) {
continue;
}
// Send the warning email using WooCommerce email system
if ($email->trigger($license, $days)) {
// Mark as notified
$this->licenseManager->markExpirationNotified($license->getId(), $notificationType);
}
}
}
/**
* Add license information to order completed email
*/
public function addLicenseInfoToEmail(\WC_Order $order, bool $sentToAdmin, bool $plainText, $email): void
{
// Only add to completed order email sent to customer
if ($sentToAdmin || !$email || $email->id !== 'customer_completed_order') {
return;
}
$licenses = $this->getLicensesForOrder($order);
if (empty($licenses)) {
return;
}
if ($plainText) {
$this->renderPlainTextLicenseInfo($licenses, $order);
} else {
$this->renderHtmlLicenseInfo($licenses, $order);
}
}
/**
* Add license key to order item in email
*/
public function addLicenseToOrderItem(int $itemId, \WC_Order_Item $item, \WC_Order $order, bool $plainText): void
{
$product = $item->get_product();
if (!$product || !$product->is_type('licensed')) {
return;
}
$license = $this->licenseManager->getLicenseByOrderAndProduct($order->get_id(), $product->get_id());
if (!$license) {
return;
}
if ($plainText) {
echo "\n" . esc_html__('License Key:', 'wc-licensed-product') . ' ' . esc_html($license->getLicenseKey()) . "\n";
} else {
?>
<div style="margin-top: 10px; padding: 10px; background-color: #f8f9fa; border-left: 3px solid #7f54b3;">
<strong><?php esc_html_e('License Key:', 'wc-licensed-product'); ?></strong>
<code style="display: block; margin-top: 5px; padding: 5px; background: #fff; font-family: monospace;">
<?php echo esc_html($license->getLicenseKey()); ?>
</code>
</div>
<?php
}
}
/**
* Get all licenses for an order
*/
private function getLicensesForOrder(\WC_Order $order): array
{
$licenses = [];
foreach ($order->get_items() as $item) {
$product = $item->get_product();
if ($product && $product->is_type('licensed')) {
$license = $this->licenseManager->getLicenseByOrderAndProduct($order->get_id(), $product->get_id());
if ($license) {
$licenses[] = [
'license' => $license,
'product_name' => $product->get_name(),
];
}
}
}
return $licenses;
}
/**
* Render license info in HTML format
*/
private function renderHtmlLicenseInfo(array $licenses, \WC_Order $order): void
{
$domain = $order->get_meta('_licensed_product_domain');
?>
<div style="margin: 20px 0; padding: 20px; background-color: #f8f9fa; border: 1px solid #e5e5e5; border-radius: 4px;">
<h2 style="margin-top: 0; color: #333;"><?php esc_html_e('Your License Keys', 'wc-licensed-product'); ?></h2>
<?php if ($domain) : ?>
<p style="margin-bottom: 15px;">
<strong><?php esc_html_e('Licensed Domain:', 'wc-licensed-product'); ?></strong>
<?php echo esc_html($domain); ?>
</p>
<?php endif; ?>
<table style="width: 100%; border-collapse: collapse;">
<thead>
<tr>
<th style="text-align: left; padding: 10px; border-bottom: 2px solid #ddd;"><?php esc_html_e('Product', 'wc-licensed-product'); ?></th>
<th style="text-align: left; padding: 10px; border-bottom: 2px solid #ddd;"><?php esc_html_e('License Key', 'wc-licensed-product'); ?></th>
<th style="text-align: left; padding: 10px; border-bottom: 2px solid #ddd;"><?php esc_html_e('Expires', 'wc-licensed-product'); ?></th>
</tr>
</thead>
<tbody>
<?php foreach ($licenses as $item) : ?>
<tr>
<td style="padding: 10px; border-bottom: 1px solid #eee;"><?php echo esc_html($item['product_name']); ?></td>
<td style="padding: 10px; border-bottom: 1px solid #eee;">
<code style="background: #fff; padding: 3px 6px; font-family: monospace;">
<?php echo esc_html($item['license']->getLicenseKey()); ?>
</code>
</td>
<td style="padding: 10px; border-bottom: 1px solid #eee;">
<?php
$expiresAt = $item['license']->getExpiresAt();
echo $expiresAt
? esc_html($expiresAt->format(get_option('date_format')))
: esc_html__('Never', 'wc-licensed-product');
?>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<p style="margin-top: 15px; margin-bottom: 0; font-size: 0.9em; color: #666;">
<?php esc_html_e('You can also view your licenses in your account under "Licenses".', 'wc-licensed-product'); ?>
</p>
</div>
<?php
}
/**
* Render license info in plain text format
*/
private function renderPlainTextLicenseInfo(array $licenses, \WC_Order $order): void
{
$domain = $order->get_meta('_licensed_product_domain');
echo "\n\n";
echo "==========================================================\n";
echo esc_html__('YOUR LICENSE KEYS', 'wc-licensed-product') . "\n";
echo "==========================================================\n\n";
if ($domain) {
echo esc_html__('Licensed Domain:', 'wc-licensed-product') . ' ' . esc_html($domain) . "\n\n";
}
foreach ($licenses as $item) {
echo esc_html($item['product_name']) . "\n";
echo esc_html__('License Key:', 'wc-licensed-product') . ' ' . esc_html($item['license']->getLicenseKey()) . "\n";
$expiresAt = $item['license']->getExpiresAt();
echo esc_html__('Expires:', 'wc-licensed-product') . ' ';
echo $expiresAt
? esc_html($expiresAt->format(get_option('date_format')))
: esc_html__('Never', 'wc-licensed-product');
echo "\n\n";
}
echo esc_html__('You can also view your licenses in your account under "Licenses".', 'wc-licensed-product') . "\n";
echo "==========================================================\n\n";
}
}