id = 'tier_package_prices'; $this->label = __('Tier & Package Prices', 'wc-tier-package-prices'); parent::__construct(); // Add AJAX handlers for license validation add_action('wp_ajax_wc_tpp_validate_license', array($this, 'ajax_validate_license')); add_action('wp_ajax_wc_tpp_activate_license', array($this, 'ajax_activate_license')); } /** * Get own sections - Modern WooCommerce pattern * * @return array */ protected function get_own_sections() { return array( '' => __('General', 'wc-tier-package-prices'), 'license' => __('License', 'wc-tier-package-prices'), ); } /** * Get settings for the default (General) section * * @return array */ protected function get_settings_for_default_section() { return array( array( 'title' => __('Tier & Package Prices Settings', 'wc-tier-package-prices'), 'type' => 'title', 'desc' => __('Configure tier pricing and package pricing options for your WooCommerce products.', 'wc-tier-package-prices'), 'id' => 'wc_tpp_settings', ), array( 'title' => __('Enable Tier Pricing', 'wc-tier-package-prices'), 'desc' => __('Enable tier pricing for products', 'wc-tier-package-prices'), 'id' => 'wc_tpp_enable_tier_pricing', 'default' => 'yes', 'type' => 'checkbox', 'desc_tip' => __('Allow quantity-based pricing tiers. Customers get discounted prices when buying in larger quantities.', 'wc-tier-package-prices'), ), array( 'title' => __('Enable Package Pricing', 'wc-tier-package-prices'), 'desc' => __('Enable fixed-price packages for products', 'wc-tier-package-prices'), 'id' => 'wc_tpp_enable_package_pricing', 'default' => 'yes', 'type' => 'checkbox', 'desc_tip' => __('Allow fixed-price packages with specific quantities. For example: 10 pieces for $50, 25 pieces for $100.', 'wc-tier-package-prices'), ), array( 'title' => __('Display Pricing Table', 'wc-tier-package-prices'), 'desc' => __('Show tier and package pricing table on product pages', 'wc-tier-package-prices'), 'id' => 'wc_tpp_display_table', 'default' => 'yes', 'type' => 'checkbox', 'desc_tip' => __('Display the pricing table to customers on product pages.', 'wc-tier-package-prices'), ), array( 'title' => __('Display Position', 'wc-tier-package-prices'), 'desc' => __('Choose where to display the pricing table on product pages.', 'wc-tier-package-prices'), 'id' => 'wc_tpp_display_position', 'default' => 'after_add_to_cart', 'type' => 'select', 'class' => 'wc-enhanced-select', 'css' => 'min-width:300px;', 'desc_tip' => true, 'options' => array( 'before_add_to_cart' => __('Before Add to Cart Button', 'wc-tier-package-prices'), 'after_add_to_cart' => __('After Add to Cart Button', 'wc-tier-package-prices'), 'after_price' => __('After Price', 'wc-tier-package-prices'), ), ), array( 'title' => __('Restrict to Package Quantities', 'wc-tier-package-prices'), 'desc' => __('Limit quantities to defined package sizes only', 'wc-tier-package-prices'), 'id' => 'wc_tpp_restrict_package_quantities', 'default' => 'no', 'type' => 'checkbox', 'desc_tip' => __('When enabled, customers can only purchase products in the exact quantities defined in packages. The quantity input field will be hidden and replaced with package selection buttons.', 'wc-tier-package-prices'), ), array( 'type' => 'sectionend', 'id' => 'wc_tpp_settings', ), ); } /** * Get settings for the License section * * @return array */ protected function get_settings_for_license_section() { return array( array( 'title' => __('License Management', 'wc-tier-package-prices'), 'type' => 'title', 'desc' => __('Enter your license key to receive updates and support.', 'wc-tier-package-prices'), 'id' => 'wc_tpp_license_settings', ), array( 'title' => __('License Server URL', 'wc-tier-package-prices'), 'desc' => __('The URL of the license server.', 'wc-tier-package-prices'), 'id' => 'wc_tpp_license_server_url', 'type' => 'url', 'default' => '', 'css' => 'min-width:400px;', 'desc_tip' => true, ), array( 'title' => __('License Key', 'wc-tier-package-prices'), 'desc' => __('Your license key for this plugin.', 'wc-tier-package-prices'), 'id' => 'wc_tpp_license_key', 'type' => 'text', 'default' => '', 'css' => 'min-width:400px;', 'desc_tip' => true, ), array( 'title' => __('License Status', 'wc-tier-package-prices'), 'type' => 'wc_tpp_license_status', 'id' => 'wc_tpp_license_status_display', ), array( 'type' => 'sectionend', 'id' => 'wc_tpp_license_settings', ), ); } /** * Get cached license status * * @return array|false */ private function get_cached_license_status() { return get_transient('wc_tpp_license_status'); } /** * AJAX handler for license validation */ public function ajax_validate_license() { check_ajax_referer('wc_tpp_license_nonce', 'nonce'); if (!current_user_can('manage_woocommerce')) { wp_send_json_error(array('message' => __('Permission denied.', 'wc-tier-package-prices'))); } $license_key = sanitize_text_field(wp_unslash($_POST['license_key'] ?? '')); $server_url = esc_url_raw(wp_unslash($_POST['server_url'] ?? '')); if (empty($license_key) || empty($server_url)) { wp_send_json_error(array('message' => __('License key and server URL are required.', 'wc-tier-package-prices'))); } try { $client = $this->get_license_client($server_url); $domain = $this->get_current_domain(); $result = $client->validate($license_key, $domain); // Cache the status set_transient('wc_tpp_license_status', array( 'valid' => true, 'product_id' => $result->productId, 'expires_at' => $result->expiresAt?->format('Y-m-d H:i:s'), 'is_lifetime' => $result->isLifetime(), 'checked_at' => current_time('mysql'), ), DAY_IN_SECONDS); wp_send_json_success(array( 'message' => __('License is valid!', 'wc-tier-package-prices'), 'status' => $this->get_cached_license_status(), )); } catch (\Magdev\WcLicensedProductClient\Exception\LicenseException $e) { delete_transient('wc_tpp_license_status'); wp_send_json_error(array( 'message' => $e->getMessage(), 'code' => $e->errorCode ?? 'unknown', )); } catch (\Exception $e) { delete_transient('wc_tpp_license_status'); wp_send_json_error(array( 'message' => $e->getMessage(), 'code' => 'exception', )); } } /** * AJAX handler for license activation */ public function ajax_activate_license() { check_ajax_referer('wc_tpp_license_nonce', 'nonce'); if (!current_user_can('manage_woocommerce')) { wp_send_json_error(array('message' => __('Permission denied.', 'wc-tier-package-prices'))); } $license_key = sanitize_text_field(wp_unslash($_POST['license_key'] ?? '')); $server_url = esc_url_raw(wp_unslash($_POST['server_url'] ?? '')); if (empty($license_key) || empty($server_url)) { wp_send_json_error(array('message' => __('License key and server URL are required.', 'wc-tier-package-prices'))); } try { $client = $this->get_license_client($server_url); $domain = $this->get_current_domain(); $result = $client->activate($license_key, $domain); if ($result->success) { // Validate to get full status after activation $validate_result = $client->validate($license_key, $domain); set_transient('wc_tpp_license_status', array( 'valid' => true, 'product_id' => $validate_result->productId, 'expires_at' => $validate_result->expiresAt?->format('Y-m-d H:i:s'), 'is_lifetime' => $validate_result->isLifetime(), 'checked_at' => current_time('mysql'), ), DAY_IN_SECONDS); wp_send_json_success(array( 'message' => __('License activated successfully!', 'wc-tier-package-prices'), 'status' => $this->get_cached_license_status(), )); } wp_send_json_error(array('message' => $result->message)); } catch (\Magdev\WcLicensedProductClient\Exception\LicenseException $e) { wp_send_json_error(array( 'message' => $e->getMessage(), 'code' => $e->errorCode ?? 'unknown', )); } catch (\Exception $e) { wp_send_json_error(array( 'message' => $e->getMessage(), 'code' => 'exception', )); } } /** * Get license client instance * * @param string $server_url License server URL. * @return \Magdev\WcLicensedProductClient\LicenseClientInterface */ private function get_license_client(string $server_url): \Magdev\WcLicensedProductClient\LicenseClientInterface { $httpClient = \Symfony\Component\HttpClient\HttpClient::create(); return new \Magdev\WcLicensedProductClient\LicenseClient( httpClient: $httpClient, baseUrl: $server_url, ); } /** * Get current domain for license validation * * @return string */ private function get_current_domain(): string { return wp_parse_url(home_url(), PHP_URL_HOST); } /** * Output the settings */ public function output() { global $current_section; // Register custom field type for license status display add_action('woocommerce_admin_field_wc_tpp_license_status', array($this, 'output_license_status_field')); parent::output(); // Add JavaScript for license section if ('license' === $current_section) { $this->output_license_scripts(); } } /** * Output license status custom field * * @param array $value Field configuration. */ public function output_license_status_field($value) { $status = $this->get_cached_license_status(); ?>