<?php
/**
 * Readabler
 * Web accessibility for Your WordPress site.
 * Exclusively on https://1.envato.market/readabler
 *
 * @encoding        UTF-8
 * @version         2.0.12
 * @copyright       (C) 2018-2025 Merkulove ( https://merkulov.design/ ). All rights reserved.
 * @license         Envato License https://1.envato.market/KYbje
 * @contributors    Dmytro Merkulov (dmitry@merkulov.design)
 * @support         help@merkulov.design
 **/

namespace Merkulove\Readabler\Unity;

/** Exit if accessed directly. */
if (!defined('ABSPATH')) {
    header('Status: 403 Forbidden');
    header('HTTP/1.1 403 Forbidden');
    exit;
}

use stdClass;
use WP_Error;

/**
 * PluginUpdaterV2 class used to control plugin updates.
 */
final class PluginUpdaterV2
{

    /**
     * The one true PluginUpdater.
     *
     * @since 1.0.0
     * @access private
     * @var PluginUpdaterV2
     **/
    private static $instance;

    private function __construct()
    {

        /** Disable if plugin don't have Envato ID. */
        if (!defined('READABLER') || !isset(READABLER['envato_id'])) {
            return;
        }

        // Check for updates
        add_filter('site_transient_update_plugins', [$this, 'update_plugins']);
        add_filter('transient_update_plugins', [$this, 'update_plugins']);

        /** Show a custom update message. */
	    add_action( 'in_plugin_update_message-readabler/readabler.php', [$this, 'show_plugin_update_message' ], 10, 2 );

        /** Add plugin info to View details popup.  */
        add_filter('plugins_api', [$this, 'plugin_info'], 20, 3);

    }

    /**
     * Check do we have a new version?
     * @param $update_plugins
     * @return mixed
     */
    public function update_plugins($update_plugins)
    {
        // Reset temporary cache
        $this->force_check();

        // Do nothing if this is not about getting plugin information.
        if (!is_object($update_plugins)) {
            return $update_plugins;
        }

        // Do nothing if it is not our plugin.
        if (!isset($update_plugins->response) || !is_array($update_plugins->response)) {
            $update_plugins->response = [];
        }

        /** This method runs multiple times, so we use short time cache.  */

        // Get plugin information from cache or remote.
	    $plugin_info = EnvatoItem::plugin_info();
        if (empty($plugin_info)) {
            return $update_plugins;
        }

        /** Show plugin update if the latest version is newer. */
        return $this->compare_with_new($plugin_info, $update_plugins);
    }

    /**
     * Show plugin update if the latest version is newer.
     * @param $plugin_info
     * @param $update_plugins
     * @return mixed
     */
    private function compare_with_new($plugin_info, $update_plugins)
    {
        global $wp_version;

        $latest_version = $plugin_info['version'];
        $package = $plugin_info['package'] ?? null;

        // If the latest version is newer, show an update version. */
        if (version_compare($latest_version, Plugin::get_version()) > 0) {

	        $update_plugins->response['readabler/readabler.php'] = (object)[
		        'slug' => 'readabler',
		        'plugin' => 'readabler/readabler.php',
                'new_version' => $latest_version, // The newest version
                'url' => $plugin_info['homepage'],
                'package' => $package,
                'requires' => Plugin::requires_wp(),
                'tested' => $wp_version,
                'requires_php' => Plugin::requires_php(),
                'icons' => [
                    '2x' => Plugin::get_url() . 'images/logo-color.svg',
                    '1x' => Plugin::get_url() . 'images/logo-color.svg',
                ],

            ];

        }

        return $update_plugins;
    }

    /**
     * Prepare plugin info.
     *
     * @param $res
     * @param $action
     * @param $args
     * @return bool|stdClass
     **@since 1.0.0
     * @access public
     *
     */
    public function plugin_info($res, $action, $args)
    {
        global $wp_version;

        // Do nothing if this is not about getting plugin information
        if ($action !== 'plugin_information') {
            return false;
        }

        // Do nothing if it is not our plugin
        if (Plugin::get_slug() !== $args->slug) {
            return false;
        }

        // Reset temporary cache
        $this->force_check();

        // Trying to get from cache first.
	    $plugin_information = EnvatoItem::plugin_info();

        if (!empty($plugin_information)) {

            $res = (object) $plugin_information;

            $res->tested = $wp_version; // Tested up to WordPress version.
            $res->requires = Plugin::requires_wp(); // Requires an at least WordPress version.
            $res->requires_php = Plugin::requires_php(); // Requires at least PHP version.

            return $res;

        }

        return false;

    }

    /**
     * Reset temporary options on Force update check.
     * @return void
     */
    public function force_check(): void
    {
	    // Reset cache only once per session.
	    static $called = false;
	    if ($called) {
		    return;
	    }
	    $called = true;

	    // Do nothing if we don't have a force check request.
	    if (isset($_GET['force-check']) && $_GET['force-check'] === '1') {
		    EnvatoItem::get_remote_plugin_info();
		    EnvatoItem::get_remote_plugin_changelog();
	    }
    }

    /**
     * Show custom update messages on plugins page.
     *
     * @param $plugin_data - An array of plugin metadata.
     * @param $r - An array of metadata about the available plugin update.
     *
     * @return void
     **@since 1.0.0
     * @access public
     *
     */
    public function show_plugin_update_message($plugin_data, $r)
    {
        /** Message for non-activated users. */
        if (!Activator::status()) {
            echo '<br /><span class="mdp-line">&nbsp;</span>';
            esc_html_e('Your plugin license is ', 'readabler');
            echo '<strong style="color: #ff495c">';
            esc_html_e('not activated', 'readabler');
            echo '.</strong> ';
            esc_html_e('Please activate the license to receive automatic updates in one click, or visit the plugin page on the Envato market to ', 'readabler');
	        echo ' <a href="https://1.envato.market/cc-downloads" target="_blank">';
            esc_html_e('download ', 'readabler');
            echo '</a> ';
            esc_html_e('the latest version.', 'readabler');
        }

    }

    /**
     * Retrieve the singleton instance of the class.
     * If the instance does not exist, it will create and return a new instance of the class.
     * @return self The single instance of the class.
     */
    public static function get_instance()
    {
        if (!isset(self::$instance) && !(self::$instance instanceof self)) {
            self::$instance = new self;
        }
        return self::$instance;
    }

}
