initTwig(); $this->initComponents(); $this->registerHooks(); } /** * Initialize Twig environment */ private function initTwig(): void { $loader = new FilesystemLoader(WC_LICENSED_PRODUCT_PLUGIN_DIR . 'templates'); $this->twig = new Environment($loader, [ 'cache' => WP_CONTENT_DIR . '/cache/wc-licensed-product/twig', 'auto_reload' => true, // Always check for template changes 'autoescape' => 'html', // Explicitly enable HTML autoescape for XSS protection ]); // Add WordPress functions as Twig functions $this->twig->addFunction(new \Twig\TwigFunction('__', function (string $text, string $domain = 'wc-licensed-product'): string { return __($text, $domain); })); $this->twig->addFunction(new \Twig\TwigFunction('esc_html', 'esc_html')); $this->twig->addFunction(new \Twig\TwigFunction('esc_attr', 'esc_attr')); $this->twig->addFunction(new \Twig\TwigFunction('esc_url', 'esc_url')); $this->twig->addFunction(new \Twig\TwigFunction('wp_nonce_field', 'wp_nonce_field', ['is_safe' => ['html']])); $this->twig->addFunction(new \Twig\TwigFunction('admin_url', 'admin_url')); $this->twig->addFunction(new \Twig\TwigFunction('wc_get_endpoint_url', 'wc_get_endpoint_url')); } /** * Initialize plugin components */ private function initComponents(): void { $this->licenseManager = new LicenseManager(); $this->versionManager = new VersionManager(); // Check plugin license $licenseChecker = PluginLicenseChecker::getInstance(); $isLicensed = $licenseChecker->isLicenseValid(); // Always initialize product type (needed for existing orders) new LicensedProductType(); // Only initialize frontend components if licensed or on localhost if ($isLicensed) { new CheckoutController($this->licenseManager); new StoreApiExtension($this->licenseManager); $this->registerCheckoutBlocksIntegration(); $this->downloadController = new DownloadController($this->licenseManager, $this->versionManager); new AccountController($this->twig, $this->licenseManager, $this->versionManager, $this->downloadController); } // Always initialize REST API and email controller new RestApiController($this->licenseManager); new LicenseEmailController($this->licenseManager); // Initialize response signing if server secret is configured if (defined('WC_LICENSE_SERVER_SECRET') && WC_LICENSE_SERVER_SECRET !== '') { (new ResponseSigner())->register(); } // Admin always available if (is_admin()) { new AdminController($this->twig, $this->licenseManager); new VersionAdminController($this->versionManager); new OrderLicenseController($this->licenseManager); new SettingsController(); new DashboardWidgetController($this->licenseManager); new DownloadWidgetController($this->versionManager); // Show admin notice if unlicensed and not on localhost if (!$isLicensed && !$licenseChecker->isLocalhost()) { add_action('admin_notices', [$this, 'showUnlicensedNotice']); } } } /** * Register WooCommerce Checkout Blocks integration */ private function registerCheckoutBlocksIntegration(): void { add_action('woocommerce_blocks_loaded', function (): void { if (class_exists('Automattic\WooCommerce\Blocks\Integrations\IntegrationRegistry')) { add_action( 'woocommerce_blocks_checkout_block_registration', function ($integration_registry): void { $integration_registry->register(new CheckoutBlocksIntegration()); } ); } }); } /** * Register plugin hooks */ private function registerHooks(): void { // Only register order hooks if licensed (license generation requires valid license) $licenseChecker = PluginLicenseChecker::getInstance(); if ($licenseChecker->isLicenseValid()) { // Generate license on order completion (multiple hooks for compatibility) add_action('woocommerce_order_status_completed', [$this, 'onOrderCompleted']); add_action('woocommerce_order_status_processing', [$this, 'onOrderCompleted']); // Also hook into payment complete for immediate license generation add_action('woocommerce_payment_complete', [$this, 'onOrderCompleted']); } } /** * Handle order completion - generate licenses */ public function onOrderCompleted(int $orderId): void { $order = wc_get_order($orderId); if (!$order) { return; } foreach ($order->get_items() as $item) { $product = $item->get_product(); if ($product && $product->is_type('licensed')) { $domain = $order->get_meta('_licensed_product_domain'); if ($domain) { $this->licenseManager->generateLicense( $orderId, $product->get_id(), $order->get_customer_id(), $domain ); } } } } /** * Get Twig environment */ public function getTwig(): Environment { return $this->twig; } /** * Get license manager */ public function getLicenseManager(): LicenseManager { return $this->licenseManager; } /** * Render a Twig template */ public function render(string $template, array $context = []): string { return $this->twig->render($template, $context); } /** * Show admin notice when plugin is unlicensed */ public function showUnlicensedNotice(): void { $settingsUrl = admin_url('admin.php?page=wc-settings&tab=licensed_product'); ?>