<?php
/**
 * Plugin Name:       Pay4All Pro
 * Description:       Adds Categories, Brands, Tickets (QR codes), Abandoned cart recovery, Product filter widget, Excel (XLSX) export, colour customisation and multilingual support on top of Pay4All Shop. Distributed outside WordPress.org from Pay4All.net — includes a one-month free trial.
 * Version:           2.6.1
 * Requires at least: 5.9
 * Requires PHP:      7.4
 * Author:            Pay4All
 * Author URI:        https://pay4all.net/
 * Update URI:        https://pay4all.net/api/v1/plugins/pay4all-pro/update-check
 * Text Domain:       pay4all-pro
 * Domain Path:       /languages
 * License:           GPL-2.0-or-later
 * License URI:       https://www.gnu.org/licenses/gpl-2.0.html
 */

// Note on `Update URI:` header
// -----------------------------
// Plugin Check flags this header as `plugin_updater_detected` — an ERROR that
// blocks WordPress.org submissions. This is intentional : pay4all-pro is
// distributed EXCLUSIVELY from https://pay4all.net/ (paid plugin, one-month
// free trial), NEVER through wordpress.org/plugins/. The Update URI header is
// how WordPress core discovers where to fetch updates — removing it would
// break every install's update mechanism.
//
// This false positive can be safely ignored on Plugin Check reports for this
// plugin. If we ever needed a WP.org-hosted counterpart, we would need a
// separate free companion + strip this header from that variant.

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

// P4ALL_PRO_VERSION is the shared « any Pay4All Pro-tier plugin is active » flag
// consumed by the free Pay4All Shop plugin's Integrations\Pro::is_active(). Other
// pay4all-family Pro plugins (pay4all-for-twint historically) also define it.
// Guard the define but DON'T return — we still need to register our autoloader,
// activation hook and Plugin::boot listener regardless of which Pro-tier plugin
// booted first. Returning here on the collision was the reason activating
// pay4all-for-twint appeared to deactivate pay4all-pro : the autoloader never
// got a chance to register, and the next request hitting a Pro class fataled.
if ( ! defined( 'P4ALL_PRO_VERSION' ) ) {
	define( 'P4ALL_PRO_VERSION', '2.6.1' );
}
define( 'P4ALL_PRO_FILE',     __FILE__ );
define( 'P4ALL_PRO_PATH',     plugin_dir_path( __FILE__ ) );
define( 'P4ALL_PRO_URL',      plugin_dir_url( __FILE__ ) );
define( 'P4ALL_PRO_BASENAME', plugin_basename( __FILE__ ) );

spl_autoload_register( static function ( $class ) {
	$prefix = 'Pay4All\\Pro\\';
	if ( strncmp( $class, $prefix, strlen( $prefix ) ) !== 0 ) {
		return;
	}
	$relative = substr( $class, strlen( $prefix ) );
	$file     = P4ALL_PRO_PATH . 'src/' . str_replace( '\\', '/', $relative ) . '.php';
	if ( is_file( $file ) ) {
		require $file;
	}
} );

// Composer-managed dependencies (Dompdf + its transitive libs) live under
// vendor/. Loaded here so classes like \Dompdf\Dompdf become available for
// the free plugin's `Services\PdfGenerator` — the free version deliberately
// SHIPS NO VENDOR : PDF invoice generation is a Pro-tier feature. Guarded
// with is_file() so a partial deploy doesn't fatal.
$p4all_pro_composer_autoload = P4ALL_PRO_PATH . 'vendor/autoload.php';
if ( is_file( $p4all_pro_composer_autoload ) ) {
	require_once $p4all_pro_composer_autoload;
}
unset( $p4all_pro_composer_autoload );

register_activation_hook( __FILE__, [ 'Pay4All\\Pro\\Activator', 'activate' ] );
register_deactivation_hook( __FILE__, [ 'Pay4All\\Pro\\Activator', 'deactivate' ] );

// Row-level action link on wp-admin/plugins.php → jumps straight to the
// Licences admin page (auto-triggers a fresh SaaS check on open, see
// AdminPage::render). Prepended so it lands before Deactivate.
add_filter( 'plugin_action_links_' . P4ALL_PRO_BASENAME, static function ( $links ) : array {
	$licence_url = admin_url( 'admin.php?page=pay4all-pro' );
	$link = '<a href="' . esc_url( $licence_url ) . '">'
		. esc_html__( 'Licence', 'pay4all-pro' )
		. '</a>';
	array_unshift( $links, $link );
	return $links;
} );

// HPOS + Checkout Blocks compat declaration — must run BEFORE woocommerce_init.
// pay4all-pro now hosts the WooCommerce integration for pay4all-age and
// pay4all-for-twint, so it declares the compatibility flags on their behalf.
add_action( 'before_woocommerce_init', static function () : void {
	if ( ! class_exists( \Automattic\WooCommerce\Utilities\FeaturesUtil::class ) ) {
		return;
	}
	\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', __FILE__, true );
	\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'cart_checkout_blocks', __FILE__, true );

	// Declare on behalf of the free companion `pay4all-for-twint` when it is
	// installed. Its main file no longer wires the WooCommerce integration
	// itself (all WC runtime now lives inside pay4all-pro).
	$twint_file = dirname( __DIR__ ) . '/pay4all-for-twint/pay4all-for-twint.php';
	if ( file_exists( $twint_file ) ) {
		\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'custom_order_tables', $twint_file, true );
		\Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility( 'cart_checkout_blocks', $twint_file, true );
	}
} );

// Boot after pay4all-form so the Domain namespace we hook into is loaded.
// Priority 11 keeps us right after pay4all-form (which boots at plugins_loaded
// with default priority 10). If the free plugin is missing we still register
// our own PostTypes so the Licences page and Add-ons entry remain reachable.
add_action( 'plugins_loaded', static function () {
	\Pay4All\Pro\Plugin::instance()->boot();
}, 11 );

// -----------------------------------------------------------------------------
// WooCommerce Blocks payment-method registration.
//
// `woocommerce_blocks_loaded` fires during `woocommerce_loaded`, which is
// dispatched by WooCommerce itself at `plugins_loaded:0`. Our `Plugin::boot()`
// callback runs at `plugins_loaded:11` — i.e. AFTER `woocommerce_blocks_loaded`
// has already fired. Hooking the blocks listener from there is a no-op :
// WooCommerce Blocks never sees us and the TWINT payment method is silently
// absent from `<!-- wp:woocommerce/checkout -->` (visible only in Elementor's
// classic-shortcode checkout, which is what surfaced the bug).
//
// Register the listener here, at plugin file-parse time, so it's in place
// well before WC fires the hook. The callback itself re-checks companion
// classes ; if pay4all-for-twint or WooCommerce is missing, it becomes a
// no-op.
// -----------------------------------------------------------------------------
add_action( 'woocommerce_blocks_loaded', static function () : void {
	if ( class_exists( '\\Pay4All\\Pro\\Integrations\\Twint\\Bootstrap' ) ) {
		\Pay4All\Pro\Integrations\Twint\Bootstrap::register_blocks_payment_method();
	}
} );
