'https://matrixaddons.com/plugins/easy-invoice/#pricing', LicensePlanResolver::PLAN_AGENCY => 'https://matrixaddons.com/plugins/easy-invoice/#pricing', ]; // License banner state — surfaced below the page header instead of via // wp-admin's global admin_notices (which would appear ABOVE the header). $license_banner = $this->resolveLicenseBanner($current_plan); include EASY_INVOICE_PLUGIN_DIR . 'templates/admin/addons-page.php'; } /** * Decide whether to show a contextual license banner inside the addons page. * * @return array{type:string,title:string,message:string,cta_label:string,cta_url:string}|null */ private function resolveLicenseBanner(string $current_plan): ?array { // No Pro plugin installed → encourage upgrade to unlock any addon. if (!function_exists('easy_invoice_has_pro') || !easy_invoice_has_pro()) { return [ 'type' => 'info', 'title' => __('You\'re on the Free version.', 'easy-invoice'), 'message' => __('These addons require Easy Invoice Pro. Install Pro to unlock Personal-tier addons — recurring invoices, client portal, reports, item library, partial payments, and more — included at no extra cost. Activate a license key to enable Professional and Agency tiers.', 'easy-invoice'), 'cta_label' => __('Get Easy Invoice Pro', 'easy-invoice'), 'cta_url' => 'https://matrixaddons.com/plugins/easy-invoice/#pricing', ]; } // Pro plugin is installed. Personal is granted without a license // (entry-level tier). A license unlocks Professional / Agency. $has_valid = class_exists('\\EasyInvoicePro\\Updater\\License') && \EasyInvoicePro\Updater\License::has_valid_license(); if (!$has_valid) { // Pro installed but no license — Personal-tier addons are // already usable. Surface an "Activate License" CTA so the // merchant knows higher tiers exist. return [ 'type' => 'info', 'title' => __('You\'re on the Personal plan.', 'easy-invoice'), 'message' => __('All Personal-tier addons are unlocked. Activate your Easy Invoice Pro license to enable Professional and Agency addons.', 'easy-invoice'), 'cta_label' => __('Activate License', 'easy-invoice'), 'cta_url' => admin_url('admin.php?page=easy-invoice-license'), ]; } // License is valid but a lower tier than the addons that exist — soft suggestion. if ($current_plan === LicensePlanResolver::PLAN_PROFESSIONAL) { return [ 'type' => 'info', 'title' => __('You\'re on the Professional plan.', 'easy-invoice'), 'message' => __('Upgrade to Agency to unlock Agency-tier addons like White-Label.', 'easy-invoice'), 'cta_label' => __('See Agency plan', 'easy-invoice'), 'cta_url' => 'https://matrixaddons.com/plugins/easy-invoice/#pricing', ]; } return null; // All good — no banner. } /** * AJAX: toggle a single addon on/off. * * Expects POST: addon_id (string), enabled (0|1), _nonce. */ public function ajaxToggleAddon(): void { check_ajax_referer(self::NONCE, '_nonce'); if (!current_user_can('manage_options')) { wp_send_json_error([ 'code' => 'forbidden', 'message' => __('Permission denied.', 'easy-invoice'), ], 403); } $addon_id = isset($_POST['addon_id']) ? sanitize_key($_POST['addon_id']) : ''; $enabled = !empty($_POST['enabled']); if ($addon_id === '') { wp_send_json_error([ 'code' => 'missing_addon_id', 'message' => __('Addon ID is required.', 'easy-invoice'), ], 400); } $result = $enabled ? AddonManager::enable($addon_id) : AddonManager::disable($addon_id); if (!$result['success']) { $payload = [ 'code' => $result['code'], 'message' => $result['message'], ]; if (!empty($result['required_plan'])) { $payload['required_plan'] = $result['required_plan']; $payload['required_plan_label'] = LicensePlanResolver::getPlanLabel($result['required_plan']); $payload['upgrade_url'] = $this->upgradeUrlFor($result['required_plan']); } wp_send_json_error($payload, 200); // 200 — payload tells client what to do } wp_send_json_success([ 'code' => $result['code'], 'message' => $result['message'], 'status' => AddonManager::statusFor($addon_id), ]); } private function upgradeUrlFor(string $plan): string { $base = 'https://matrixaddons.com/plugins/easy-invoice/#pricing'; return add_query_arg([ 'plan' => $plan, 'discount' => 'EIEARLYBIRD', 'utm_source' => 'easy-invoice-plugin', 'utm_medium' => 'addons-page', 'utm_campaign' => 'addon-upgrade', ], $base); } public function enqueueAssets(string $hook): void { $current_page = isset($_GET['page']) ? sanitize_text_field($_GET['page']) : ''; if ($current_page !== self::PAGE_SLUG) { return; } // Page chrome (sidebar, layout) comes from Easy Invoice's existing Tailwind UI; // we only need the toggle/upgrade JS for this page. wp_enqueue_script( 'easy-invoice-addons-page', EASY_INVOICE_PLUGIN_URL . 'assets/js/addons-page.js', ['jquery'], EASY_INVOICE_VERSION, true ); wp_localize_script('easy-invoice-addons-page', 'EasyInvoiceAddons', [ 'ajaxUrl' => admin_url('admin-ajax.php'), 'nonce' => wp_create_nonce(self::NONCE), 'strings' => [ 'enabling' => __('Enabling…', 'easy-invoice'), 'disabling' => __('Disabling…', 'easy-invoice'), 'enableError' => __('Could not enable this addon.', 'easy-invoice'), 'disableError' => __('Could not disable this addon.', 'easy-invoice'), 'genericError' => __('Something went wrong. Please try again.', 'easy-invoice'), ], ]); } }