<?php
/**
 * Deprecation warnings suppressor for vendor libraries.
 *
 * This helper suppresses PHP 8.4+ deprecation warnings for "implicit nullable parameters"
 * that come from vendor libraries (specifically PHP-DI) which cannot be updated due to
 * PHP 7.4 compatibility requirements.
 *
 * @package Awesomemotive\Rewardswp\Helpers
 * @since 1.1.1
 */

namespace Awesomemotive\Rewardswp\Helpers;

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

/**
 * Deprecation Suppressor.
 *
 * Filters out E_DEPRECATED warnings from vendor libraries that cannot be updated.
 *
 * @since 1.1.1
 */
class DeprecationSuppressor {

	/**
	 * Register the custom error handler.
	 *
	 * Only registers on PHP 8.4+ where implicit nullable parameter deprecation warnings appear.
	 *
	 * @since 1.1.1
	 *
	 * @return void
	 */
	public static function register(): void {
		// Only needed on PHP 8.4+.
		if ( PHP_VERSION_ID < 80400 ) {
			return;
		}

		// phpcs:ignore WordPress.PHP.DevelopmentFunctions.error_log_set_error_handler -- Intentionally suppress vendor E_DEPRECATED warnings on PHP 8.4+ only.
		set_error_handler( [ self::class, 'handle_deprecation' ], E_DEPRECATED );
	}

	/**
	 * Custom error handler that filters vendor library deprecations.
	 *
	 * @since 1.1.1
	 *
	 * @param int    $errno   The level of the error raised.
	 * @param string $errstr  The error message.
	 * @param string $errfile The filename that the error was raised in.
	 *
	 * @return bool True if the error was handled (suppressed), false to use the default handler.
	 */
	public static function handle_deprecation( int $errno, string $errstr, string $errfile ): bool {
		// Only handle E_DEPRECATED.
		if ( E_DEPRECATED !== $errno ) {
			return false;
		}

		// Suppress PHP-DI implicit nullable parameter warnings.
		if ( self::is_php_di_deprecation( $errfile, $errstr ) ) {
			return true;
		}

		// Suppress Laravel Serializable Closure warnings (PHP-DI dependency).
		if ( self::is_laravel_closure_deprecation( $errfile, $errstr ) ) {
			return true;
		}

		// Let the default error handler process other deprecation warnings.
		return false;
	}

	/**
	 * Check if the deprecation is from PHP-DI library.
	 *
	 * @since 1.1.1
	 *
	 * @param string $errfile The filename that the error was raised in.
	 * @param string $errstr  The error message.
	 *
	 * @return bool True if this is a PHP-DI deprecation that should be suppressed.
	 */
	private static function is_php_di_deprecation( string $errfile, string $errstr ): bool {
		return false !== strpos( $errfile, 'php-di' )
			&& false !== strpos( $errstr, 'Implicitly marking parameter' );
	}

	/**
	 * Check if the deprecation is from Laravel Serializable Closure library.
	 *
	 * @since 1.1.1
	 *
	 * @param string $errfile The filename that the error was raised in.
	 * @param string $errstr  The error message.
	 *
	 * @return bool True if this is a Laravel closure deprecation that should be suppressed.
	 */
	private static function is_laravel_closure_deprecation( string $errfile, string $errstr ): bool {
		return false !== strpos( $errfile, 'laravel' )
			&& false !== strpos( $errfile, 'serializable-closure' )
			&& false !== strpos( $errstr, 'Implicitly marking parameter' );
	}
}

