cacheDuration = defined('AD_BLOCK_GUARD_DEBUG') && AD_BLOCK_GUARD_DEBUG ? HOUR_IN_SECONDS : DAY_IN_SECONDS; // Private constructor to prevent direct instantiation if ($licenseKey) { $this->licenseKey = $licenseKey; update_option('ad_block_guard_license_key', $licenseKey); } else { $this->licenseKey = get_option('ad_block_guard_license_key', ''); } $this->registerPluginRowMeta(); $this->initializeUpdater(); $this->setupUpdateTransientsClear(); $this->scheduleCrons(); } public static function getInstance($licenseKey = null) { if (self::$instance === null) { self::$instance = new self($licenseKey); } return self::$instance; } public function getProductId() { return $this->productId; } public function getStoreUrl() { return $this->storeUrl; } public function getLicenseKey() { return $this->licenseKey; } public function setLicenseKey($licenseKey) { $this->licenseKey = $licenseKey; update_option('ad_block_guard_license_key', $licenseKey); } public function activateLicense() { $api_params = array( 'edd_action' => 'activate_license', 'license' => $this->licenseKey, 'item_id' => $this->getProductId(), 'url' => home_url(), ); $response = wp_remote_post($this->getStoreUrl(), array('body' => $api_params)); if (is_wp_error($response)) { return array('success' => false, 'error' => $response->get_error_message()); } $license_data = json_decode(wp_remote_retrieve_body($response)); if ($license_data->license === 'valid') { $this->updateLicenseStatus('valid', $license_data->expires); return array('success' => true, 'expires' => $license_data->expires); } else { $this->updateLicenseStatus('invalid'); return array('success' => false, 'error' => $license_data->error); } } public function deactivateLicense() { $api_params = array( 'edd_action' => 'deactivate_license', 'license' => $this->licenseKey, 'item_id' => $this->getProductId(), 'url' => home_url(), ); $response = wp_remote_post($this->getStoreUrl(), array('body' => $api_params)); if (is_wp_error($response)) { $error_message = $response->get_error_message(); if (AD_BLOCK_GUARD_DEBUG) error_log("Ad Block Guard: Deactivate License - WP Error: " . $error_message); return array('success' => false, 'error' => $error_message); } $license_data = json_decode(wp_remote_retrieve_body($response)); if ($license_data && isset($license_data->license) && $license_data->license === 'deactivated') { $this->clearLicenseData(); return array('success' => true); } else { $error_message = isset($license_data->error) ? $license_data->error : __('An unknown error occurred during license deactivation.', 'ad-block-guard'); // Log the full API response for further diagnosis if (AD_BLOCK_GUARD_DEBUG) error_log("Ad Block Guard: Deactivate License - Full Response: " . print_r($license_data, true)); return array('success' => false, 'error' => $error_message); } } public function registerPluginRowMeta() { // Ensure filters are only added once if (has_filter('plugin_row_meta', [$this, 'pluginRowMeta']) === false) { add_filter('plugin_row_meta', [$this, 'pluginRowMeta'], 10, 2); } if (has_filter('plugin_action_links_ad-block-guard/ad-block-guard.php', [$this, 'pluginActionLinks']) === false) { add_filter('plugin_action_links_ad-block-guard/ad-block-guard.php', [$this, 'pluginActionLinks'], 10, 2); } } public function pluginRowMeta($plugin_meta, $plugin_file) { if ($plugin_file === 'ad-block-guard/ad-block-guard.php') { $licenseStatus = get_option('ad_block_guard_license_status', 'inactive'); // Clear previous meta if duplicated $plugin_meta = array_unique($plugin_meta); if ($licenseStatus === 'invalid') { $plugin_meta[] = sprintf( // Translators: %1$s is the URL to the license activation page. __('There is a new version of Ad Block Guard available. Activate your license for automatic updates.', 'ad-block-guard'), esc_url(admin_url('admin.php?page=ad_block_guard_license_key')) ); } elseif ($licenseStatus === 'valid' && $this->isUpdateAvailable()) { $plugin_meta[] = sprintf( // Translators: %1$s is the URL to the update page in the WordPress admin. __('There is a new version of Ad Block Guard available. Update now.', 'ad-block-guard'), esc_url(admin_url('update-core.php')) ); } } return $plugin_meta; } public function pluginActionLinks($links, $plugin_file) { if ($plugin_file === 'ad-block-guard/ad-block-guard.php') { $links = array_unique($links); // Clear previous links if duplicated if ($this->isLicenseValid()) { $links[] = '' . __('Manage License', 'ad-block-guard') . ''; } else { $links[] = '' . __('Activate License', 'ad-block-guard') . ''; $links[] = '' . __('Get Ad Block Guard Pro', 'ad-block-guard') . ''; } } return $links; } public function isLicenseValid() { // Check the transient for last license check time $lastCheck = get_transient(AD_BLOCK_GUARD_LICENSE_LAST_CHECK); if ($lastCheck && $lastCheck > time()) { // Transient exists and is still valid, use cached license status $licenseStatus = get_option('ad_block_guard_license_status', 'inactive'); return $licenseStatus === 'valid'; } // If the transient has expired, check the license status with the remote server $result = $this->checkLicenseValidity(); return $result['success'] && $result['status'] === 'valid'; } public function isUpdateAvailable() { // Here you would check the current installed version against the available version on the server. $current_version = AD_BLOCK_GUARD_VERSION; $latest_version = get_transient('ad_block_guard_latest_version'); if (!$latest_version) { $response = wp_remote_get($this->getStoreUrl() . '/edd-api/products/?product=' . $this->getProductId()); if (!is_wp_error($response)) { $data = json_decode(wp_remote_retrieve_body($response)); $latest_version = $data->products[0]->info->version ?? $current_version; set_transient('ad_block_guard_latest_version', $latest_version, DAY_IN_SECONDS); } } return version_compare($current_version, $latest_version, '<'); } public function initializeUpdater() { if (is_admin()) { $edd_updater = new EDD_SL_Plugin_Updater($this->getStoreUrl(), AD_BLOCK_GUARD_PLUGIN_FILE, array( 'version' => AD_BLOCK_GUARD_VERSION, 'license' => $this->getLicenseKey(), 'item_id' => $this->getProductId(), 'author' => 'Wutime', 'url' => home_url(), 'beta' => false, 'automatic' => true, // This enables auto-updates )); } } public function setupUpdateTransientsClear() { add_action('upgrader_process_complete', function ($upgrader_object, $options) { if ($options['action'] == 'update' && $options['type'] == 'plugin') { if (isset($options['plugins']) && in_array(plugin_basename(__FILE__), $options['plugins'])) { // Clear only the transients related to your plugin delete_transient('ad_block_guard_latest_version'); delete_transient('ad_block_guard_product_details'); delete_option('ad_block_guard_license_status'); delete_option('ad_block_guard_license_expires'); } } }, 10, 2); } public function scheduleCrons() { if (!wp_next_scheduled('ad_block_guard_update_product_details')) { wp_schedule_event(time(), 'weekly', 'ad_block_guard_update_product_details'); } $hook = 'ad_block_guard_license_check'; $interval = AD_BLOCK_GUARD_DEBUG ? 'hourly' : 'daily'; $timestamp = wp_next_scheduled($hook); if ($timestamp) { wp_unschedule_event($timestamp, $hook); } if (!wp_next_scheduled($hook)) { wp_schedule_event(time(), $interval, $hook); } add_action('ad_block_guard_license_check', [$this, 'validateLicenseCron']); } public function clearScheduledCrons() { wp_clear_scheduled_hook('ad_block_guard_update_product_details'); wp_clear_scheduled_hook('ad_block_guard_license_check'); } public function updateProductDetails() { $this->getProductDetails(); } public function checkLicense() { $this->checkLicenseValidity(); } public function getProductDetails() { $transient_name = 'ad_block_guard_product_details'; $product_details = get_transient($transient_name); if ($product_details === false) { $download_id = $this->getProductId(); $url = $this->getStoreUrl(); $productApiUrl = $url . '/edd-api/products/?product=' . $download_id; $response = wp_remote_get($productApiUrl); if (is_wp_error($response)) { return false; } $body = wp_remote_retrieve_body($response); $data = json_decode($body); if (isset($data->products[0]->info)) { $info = $data->products[0]->info; $licensing = $data->products[0]->licensing; $product_details = [ 'permalink' => $info->permalink, 'title' => $info->title, 'price' => wp_strip_all_tags($info->price), 'version' => $licensing->version, // Ensure we store the latest version ]; set_transient($transient_name, $product_details, WEEK_IN_SECONDS); set_transient('ad_block_guard_latest_version', $licensing->version, WEEK_IN_SECONDS); // Cache the latest version } else { return false; } } return $product_details; } public function checkLicenseValidity($forceCheck = false) { $lastCheck = get_transient(AD_BLOCK_GUARD_LICENSE_LAST_CHECK); if (!$forceCheck && $lastCheck) { // Transient exists, return cached status $licenseStatus = get_option('ad_block_guard_license_status', 'inactive'); return [ 'success' => $licenseStatus === 'valid', 'status' => $licenseStatus, 'expires' => get_option('ad_block_guard_license_expires', ''), 'cached' => true ]; } // Prepare the API request parameters $api_params = array( 'edd_action' => 'check_license', 'license' => $this->getLicenseKey(), 'item_id' => $this->getProductId(), 'url' => home_url(), ); // Send the request to the EDD store $response = wp_remote_post($this->getStoreUrl(), array('body' => $api_params)); if (is_wp_error($response)) { if (AD_BLOCK_GUARD_DEBUG) error_log("Ad Block Guard: Check License Validity - WP Error: " . $response->get_error_message()); return array('success' => false, 'error' => $response->get_error_message()); } $license_data = json_decode(wp_remote_retrieve_body($response)); if ($license_data && isset($license_data->license)) { $this->updateLicenseStatus($license_data->license, $license_data->expires ?? null); return [ 'success' => $license_data->license === 'valid', 'status' => $license_data->license, 'expires' => $license_data->expires ?? '', 'cached' => false ]; } else { if (AD_BLOCK_GUARD_DEBUG) error_log('Ad Block Guard License Check Error: Invalid response from license server.'); return [ 'success' => false, 'status' => 'error', 'error' => __('Invalid response from license server.', 'ad-block-guard') ]; } } public function validateLicenseCron() { // Force a license check and update cached data $this->checkLicenseValidity(true); } private function updateLicenseStatus($status, $expires = null) { update_option('ad_block_guard_license_status', $status); set_transient(AD_BLOCK_GUARD_LICENSE_LAST_CHECK, time() + $this->cacheDuration, $this->cacheDuration); if ($expires) { update_option('ad_block_guard_license_expires', $expires); } } private function clearLicenseData() { delete_transient(AD_BLOCK_GUARD_LICENSE_LAST_CHECK); delete_option('ad_block_guard_license_key'); delete_option('ad_block_guard_license_status'); delete_option('ad_block_guard_license_expires'); } public function getUpgradeLink() { $productDetails = $this->getProductDetails(); return $productDetails['permalink'] . '?utm_source=WordPress&utm_medium=all-plugins&utm_campaign=liteplugin&utm_locale=' . get_locale() . '&utm_content=' . rawurlencode(__('Get Ad Block Guard Pro', 'ad-block-guard')); } }