<?php
/**
 * Plugin Name: RedirectZen – 301 Redirect Manager & 404 Fixer
 * Plugin URI:  https://wordpress.org/plugins/redirectzen-301-redirect-manager/
 * Description: Verified 301 redirects and 404 fixing. Every redirect is checked end-to-end so it actually works — local, unlimited, no account, no ads.
 * Version:     1.0.0
 * Author:      Zen Plugins
 * Author URI:  https://zenplugins.org/
 * License:     GPLv2 or later
 * License URI: https://www.gnu.org/licenses/gpl-2.0.html
 * Text Domain: redirectzen-301-redirect-manager
 * Domain Path: /languages
 * Requires at least: 5.8
 * Requires PHP: 7.2
 *
 * RedirectZen is free software: you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published by the
 * Free Software Foundation, either version 2 of the License, or any later
 * version.
 *
 * RedirectZen is distributed in the hope that it will be useful, but
 * WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General
 * Public License for more details.
 */

if ( ! defined( 'ABSPATH' ) ) {
	exit;
}

define( 'RDZ_VERSION', '1.0.0' );
define( 'RDZ_PLUGIN_FILE', __FILE__ );
define( 'RDZ_PLUGIN_DIR', plugin_dir_path( __FILE__ ) );
define( 'RDZ_PLUGIN_URL', plugin_dir_url( __FILE__ ) );
define( 'RDZ_PLUGIN_BASENAME', plugin_basename( __FILE__ ) );

/**
 * Freemius integration.
 *
 * Product: RedirectZen (ID 33515), store: Zen Plugins (17664).
 * Plans: Free 55115 / PRO 55116. Lifetime-only pricing IDs:
 * 72689 ($39/1 site), 72690 ($59/5), 72691 ($99/25). Coupon: ZENLAUNCH (30%).
 *
 * While the public key below is empty the plugin falls back to a local stub
 * and every feature check reports the free plan, so the plugin stays fully
 * functional either way.
 */
if ( ! defined( 'RDZ_FREEMIUS_ID' ) ) {
	define( 'RDZ_FREEMIUS_ID', 33515 );
}
if ( ! defined( 'RDZ_FREEMIUS_PUBLIC_KEY' ) ) {
	define( 'RDZ_FREEMIUS_PUBLIC_KEY', 'pk_60c057b9ffd4ddf73cbea64ea28e5' );
}

if ( ! function_exists( 'rdz_fs' ) ) {
	/**
	 * Returns the Freemius instance, or a stub when Freemius is not configured.
	 *
	 * @return object
	 */
	function rdz_fs() {
		global $rdz_fs;

		if ( isset( $rdz_fs ) ) {
			return $rdz_fs;
		}

		if ( RDZ_FREEMIUS_ID && RDZ_FREEMIUS_PUBLIC_KEY && file_exists( RDZ_PLUGIN_DIR . 'freemius/start.php' ) ) {
			require_once RDZ_PLUGIN_DIR . 'freemius/start.php';

			$rdz_fs = fs_dynamic_init(
				array(
					'id'             => (string) RDZ_FREEMIUS_ID,
					'slug'           => 'redirectzen-301-redirect-manager',
					'type'           => 'plugin',
					'public_key'     => RDZ_FREEMIUS_PUBLIC_KEY,
					'is_premium'     => false,
					'has_addons'     => false,
					'has_paid_plans' => true,
					// No opt-in wizard between "Activate" and value: activation
					// lands straight on the dashboard. Checkout still works —
					// Freemius collects the email at purchase.
					'anonymous_mode' => true,
					'menu'           => array(
						'slug'    => 'redirectzen',
						'support' => false,
						'pricing' => false,
						'contact' => false,
					),
				)
			);
		} else {
			require_once RDZ_PLUGIN_DIR . 'includes/class-rdz-freemius-stub.php';
			$rdz_fs = new RDZ_Freemius_Stub();
		}

		return $rdz_fs;
	}

	rdz_fs();
	do_action( 'rdz_fs_loaded' );
}

/**
 * Whether premium (Pro) code may run.
 *
 * @return bool
 */
function rdz_can_use_premium() {
	$fs = rdz_fs();

	return method_exists( $fs, 'can_use_premium_code' ) && $fs->can_use_premium_code();
}

/**
 * Removes all RedirectZen data for the current site.
 *
 * Data removal is the default (a top complaint against incumbents is
 * redirects persisting after uninstall) but respects the "keep data"
 * setting for owners who plan to reinstall.
 */
function rdz_uninstall_site_data() {
	global $wpdb;

	$settings = get_option( 'rdz_settings', array() );
	if ( is_array( $settings ) && ! empty( $settings['keep_data'] ) ) {
		return;
	}

	// phpcs:disable WordPress.DB.DirectDatabaseQuery.DirectQuery, WordPress.DB.DirectDatabaseQuery.SchemaChange, WordPress.DB.DirectDatabaseQuery.NoCaching
	$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}rdz_redirects" );
	$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}rdz_404_log" );
	$wpdb->query( "DROP TABLE IF EXISTS {$wpdb->prefix}rdz_backups" );
	// phpcs:enable

	delete_option( 'rdz_settings' );
	delete_option( 'rdz_db_version' );
	delete_option( 'rdz_activated_at' );
	delete_option( 'rdz_last_verify_cycle' );
	delete_option( 'rdz_last_grade' );
	delete_option( 'rdz_grade_improvement' );
	delete_option( 'rdz_optin' );
	delete_option( 'rdz_first_redirect_at' );
	delete_option( 'rdz_digest_last_sent' );

	wp_clear_scheduled_hook( 'rdz_verify_batch' );
	wp_clear_scheduled_hook( 'rdz_daily_maintenance' );
	wp_clear_scheduled_hook( 'rdz_weekly_digest' );
}

/**
 * Full uninstall cleanup, multisite-aware. Runs on uninstall only (via the
 * Freemius after_uninstall hook), never on deactivation.
 */
function rdz_uninstall_cleanup() {
	if ( is_multisite() ) {
		$rdz_site_ids = get_sites( array( 'fields' => 'ids', 'number' => 0 ) );
		foreach ( $rdz_site_ids as $rdz_site_id ) {
			switch_to_blog( $rdz_site_id );
			rdz_uninstall_site_data();
			restore_current_blog();
		}
	} else {
		rdz_uninstall_site_data();
	}
}

// Freemius owns the uninstall flow (no uninstall.php, per Freemius guidelines).
// If the SDK is ever absent (stub mode), fall back to WordPress's native
// uninstall hook so cleanup still runs.
if ( rdz_fs() instanceof RDZ_Freemius_Stub ) {
	register_uninstall_hook( __FILE__, 'rdz_uninstall_cleanup' );
} else {
	rdz_fs()->add_action( 'after_uninstall', 'rdz_uninstall_cleanup' );
}

require_once RDZ_PLUGIN_DIR . 'includes/class-rdz-settings.php';
require_once RDZ_PLUGIN_DIR . 'includes/class-rdz-activator.php';
require_once RDZ_PLUGIN_DIR . 'includes/class-rdz-redirects.php';
require_once RDZ_PLUGIN_DIR . 'includes/class-rdz-http-checker.php';
require_once RDZ_PLUGIN_DIR . 'includes/class-rdz-verifier.php';
require_once RDZ_PLUGIN_DIR . 'includes/class-rdz-grade.php';
require_once RDZ_PLUGIN_DIR . 'includes/class-rdz-404-log.php';
require_once RDZ_PLUGIN_DIR . 'includes/class-rdz-backups.php';
require_once RDZ_PLUGIN_DIR . 'includes/class-rdz-csv.php';
require_once RDZ_PLUGIN_DIR . 'includes/class-rdz-importers.php';
require_once RDZ_PLUGIN_DIR . 'includes/class-rdz-cron.php';
require_once RDZ_PLUGIN_DIR . 'includes/class-rdz-optin.php';

if ( is_admin() ) {
	require_once RDZ_PLUGIN_DIR . 'admin/class-rdz-admin.php';
	require_once RDZ_PLUGIN_DIR . 'admin/class-rdz-redirects-table.php';
	require_once RDZ_PLUGIN_DIR . 'admin/class-rdz-404-table.php';
	require_once RDZ_PLUGIN_DIR . 'admin/class-rdz-ajax.php';
}

// Pro-only modules; these files are absent from the free build.
foreach ( array( 'class-rdz-regex__premium_only.php', 'class-rdz-suggest__premium_only.php', 'class-rdz-pro-schedule__premium_only.php' ) as $rdz_pro_file ) {
	$rdz_pro_path = RDZ_PLUGIN_DIR . 'includes/' . $rdz_pro_file;
	if ( file_exists( $rdz_pro_path ) ) {
		require_once $rdz_pro_path;
	}
}
unset( $rdz_pro_file, $rdz_pro_path );

register_activation_hook( __FILE__, array( 'RDZ_Activator', 'activate' ) );
register_deactivation_hook( __FILE__, array( 'RDZ_Activator', 'deactivate' ) );

/**
 * Boots the plugin.
 */
function rdz_init() {
	// Translations for a wordpress.org-hosted plugin are loaded automatically
	// since WP 4.6 — no load_plugin_textdomain() call is needed.

	RDZ_Cron::init();
	RDZ_Redirects::init();
	RDZ_404_Log::init();
	RDZ_Backups::init();

	if ( is_admin() ) {
		RDZ_Admin::init();
		RDZ_Ajax::init();
		RDZ_Csv::init();
		RDZ_Importers::init();
	}

	if ( rdz_can_use_premium() ) {
		if ( class_exists( 'RDZ_Regex' ) ) {
			RDZ_Regex::init();
		}
		if ( class_exists( 'RDZ_Suggest' ) ) {
			RDZ_Suggest::init();
		}
		if ( class_exists( 'RDZ_Pro_Schedule' ) ) {
			RDZ_Pro_Schedule::init();
		}
	}
}
add_action( 'plugins_loaded', 'rdz_init' );
