HEX
Server: Apache
System: Linux andromeda.lojoweb.com 4.18.0-372.26.1.el8_6.x86_64 #1 SMP Tue Sep 13 06:07:14 EDT 2022 x86_64
User: nakedfoamlojoweb (1056)
PHP: 8.0.30
Disabled: exec,passthru,shell_exec,system
Upload Files
File: //proc/self/cwd/wp-content/plugins/woocommerce-square/includes/Framework/Admin_Notice_Handler.php
<?php
/**
 * WooCommerce Plugin Framework
 *
 * This source file is subject to the GNU General Public License v3.0
 * that is bundled with this package in the file license.txt.
 * It is also available through the world-wide-web at this URL:
 * http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0 or later
 * If you did not receive a copy of the license and are unable to
 * obtain it through the world-wide-web, please send an email
 * to license@skyverge.com so we can send you a copy immediately.
 *
 * @since     3.0.0
 * @author    WooCommerce / SkyVerge
 * @copyright Copyright (c) 2013-2019, SkyVerge, Inc.
 * @license   http://www.gnu.org/licenses/gpl-3.0.html GNU General Public License v3.0 or later
 *
 * Modified by WooCommerce on 01 December 2021.
 */

namespace WooCommerce\Square\Framework;

defined( 'ABSPATH' ) || exit;

/**
 * Admin Notice Handler Class
 *
 * The purpose of this class is to provide a facility for displaying
 * conditional (often dismissible) admin notices during a single page
 * request
 *
 * @since 3.0.0
 */
class Admin_Notice_Handler {


	/** @var Plugin the plugin */
	private $plugin;

	/** @var array associative array of id to notice text */
	private $admin_notices = array();

	/** @var boolean static member to enforce a single rendering of the admin notice placeholder element */
	private static $admin_notice_placeholder_rendered = false;

	/** @var boolean static member to enforce a single rendering of the admin notice javascript */
	private static $admin_notice_js_rendered = false;


	/**
	 * Initialize and setup the Admin Notice Handler
	 *
	 * @since 3.0.0
	 */
	public function __construct( $plugin ) {

		$this->plugin = $plugin;

		// render any admin notices, delayed notices, and
		add_action( 'admin_notices', array( $this, 'render_admin_notices' ), 15 );
		add_action( 'admin_footer', array( $this, 'render_delayed_admin_notices' ), 15 );
		add_action( 'admin_footer', array( $this, 'render_admin_notice_js' ), 20 );

		// AJAX handler to dismiss any warning/error notices
		add_action( 'wp_ajax_wc_plugin_framework_square_dismiss_notice', array( $this, 'handle_dismiss_notice' ) );
	}


	/**
	 * Adds the given $message as a dismissible notice identified by $message_id,
	 * unless the notice has been dismissed, or we're on the plugin settings page
	 *
	 * @since 3.0.0
	 * @param string $message the notice message to display
	 * @param string $message_id the message id
	 * @param array $params {
	 *     Optional parameters.
	 *
	 *     @type bool $dismissible             If the notice should be dismissible
	 *     @type bool $always_show_on_settings If the notice should be forced to display on the
	 *                                         plugin settings page, regardless of `$dismissible`.
	 *     @type string $notice_class          Additional classes for the notice.
	 * }
	 */
	public function add_admin_notice( $message, $message_id, $params = array() ) {

		$params = wp_parse_args(
			$params,
			array(
				'dismissible'             => true,
				'always_show_on_settings' => true,
				'notice_class'            => 'updated',
			)
		);

		if ( $this->should_display_notice( $message_id, $params ) ) {
			$this->admin_notices[ $message_id ] = array(
				'message'  => $message,
				'rendered' => false,
				'params'   => $params,
			);
		}
	}


	/**
	 * Returns true if the identified notice hasn't been cleared, or we're on
	 * the plugin settings page (where notices are always displayed)
	 *
	 * @since 3.0.0
	 * @param string $message_id the message id
	 * @param array $params {
	 *     Optional parameters.
	 *
	 *     @type bool $dismissible             If the notice should be dismissible
	 *     @type bool $always_show_on_settings If the notice should be forced to display on the
	 *                                         plugin settings page, regardless of `$dismissible`.
	 * }
	 * @return bool
	 */
	public function should_display_notice( $message_id, $params = array() ) {

		// bail out if user is not a shop manager
		if ( ! current_user_can( 'manage_woocommerce' ) ) {
			return false;
		}

		$params = wp_parse_args(
			$params,
			array(
				'dismissible'             => true,
				'always_show_on_settings' => true,
			)
		);

		// if the notice is always shown on the settings page, and we're on the settings page
		if ( $params['always_show_on_settings'] && $this->get_plugin()->is_plugin_settings() ) {
			return true;
		}

		// non-dismissible, always display
		if ( ! $params['dismissible'] ) {
			return true;
		}

		// dismissible: display if notice has not been dismissed
		return ! $this->is_notice_dismissed( $message_id );
	}


	/**
	 * Render any admin notices, as well as the admin notice placeholder
	 *
	 * @since 3.0.0
	 * @param boolean $is_visible true if the notices should be immediately visible, false otherwise
	 */
	public function render_admin_notices( $is_visible = true ) {

		// default for actions
		if ( ! is_bool( $is_visible ) ) {
			$is_visible = true;
		}

		foreach ( $this->admin_notices as $message_id => $message_data ) {
			if ( ! $message_data['rendered'] ) {
				$message_data['params']['is_visible'] = $is_visible;
				$this->render_admin_notice( $message_data['message'], $message_id, $message_data['params'] );
				$this->admin_notices[ $message_id ]['rendered'] = true;
			}
		}

		if ( $is_visible && ! self::$admin_notice_placeholder_rendered ) {
			// placeholder for moving delayed notices up into place
			echo '<div class="js-wc-' . esc_attr( $this->get_plugin()->get_id_dasherized() ) . '-admin-notice-placeholder"></div>';
			self::$admin_notice_placeholder_rendered = true;
		}

	}


	/**
	 * Render any delayed admin notices, which have not yet already been rendered
	 *
	 * @since 3.0.0
	 */
	public function render_delayed_admin_notices() {
		$this->render_admin_notices( false );
	}


	/**
	 * Render a single admin notice
	 *
	 * @since 3.0.0
	 * @param string $message the notice message to display
	 * @param string $message_id the message id
	 * @param array $params {
	 *     Optional parameters.
	 *
	 *     @type bool $dismissible             If the notice should be dismissible
	 *     @type bool $is_visible              If the notice should be immediately visible
	 *     @type bool $always_show_on_settings If the notice should be forced to display on the
	 *                                         plugin settings page, regardless of `$dismissible`.
	 *     @type string $notice_class          Additional classes for the notice.
	 * }
	 */
	public function render_admin_notice( $message, $message_id, $params = array() ) {

		$params = wp_parse_args(
			$params,
			array(
				'dismissible'             => true,
				'is_visible'              => true,
				'always_show_on_settings' => true,
				'notice_class'            => 'updated',
			)
		);

		$classes = array(
			'notice',
			'js-wc-plugin-framework-admin-notice',
			$params['notice_class'],
		);

		// maybe make this notice dismissible
		// uses a WP core class which handles the markup and styling
		if ( $params['dismissible'] && ( ! $params['always_show_on_settings'] || ! $this->get_plugin()->is_plugin_settings() ) ) {
			$classes[] = 'is-dismissible';
		}

		$style = ! $params['is_visible'] ? 'style="display:none"' : '';

		echo sprintf(
			'<div class="%1$s" data-plugin-id="%2$s" data-message-id="%3$s" %4$s><p>%5$s</p></div>',
			esc_attr( implode( ' ', $classes ) ),
			esc_attr( 'square' ),
			esc_attr( $message_id ),
			esc_attr( $style ),
			wp_kses_post( $message )
		);
	}


	/**
	 * Render the javascript to handle the notice "dismiss" functionality
	 *
	 * @since 3.0.0
	 */
	public function render_admin_notice_js() {

		// if there were no notices, or we've already rendered the js, there's nothing to do
		if ( empty( $this->admin_notices ) || self::$admin_notice_js_rendered ) {
			return;
		}

		$plugin_slug = $this->get_plugin()->get_id_dasherized();
		$ajax_url    = wp_nonce_url( admin_url( 'admin-ajax.php' ), 'notice_nonce', 'notice_nonce' );

		self::$admin_notice_js_rendered = true;

		ob_start();
		?>

		// Log dismissed notices
		$( '.js-wc-plugin-framework-admin-notice' ).on( 'click.wp-dismiss-notice', '.notice-dismiss', function( e ) {

			var $notice = $( this ).closest( '.js-wc-plugin-framework-admin-notice' );

			log_dismissed_notice(
				$( $notice ).data( 'plugin-id' ),
				$( $notice ).data( 'message-id' )
			);

		} );

		// Log and hide legacy notices
		$( 'a.js-wc-plugin-framework-notice-dismiss' ).click( function( e ) {

			e.preventDefault();

			var $notice = $( this ).closest( '.js-wc-plugin-framework-admin-notice' );

			log_dismissed_notice(
				$( $notice ).data( 'plugin-id' ),
				$( $notice ).data( 'message-id' )
			);

			$( $notice ).fadeOut();

		} );

		function log_dismissed_notice( pluginID, messageID ) {

			$.get(
				'<?php echo esc_url( $ajax_url ); ?>',
				{
					action:    'wc_plugin_framework_' + pluginID + '_dismiss_notice',
					messageid: messageID
				}
			);
		}

		// move any delayed notices up into position .show();
		$( '.js-wc-plugin-framework-admin-notice:hidden' ).insertAfter( '.js-wc-<?php echo esc_js( $plugin_slug ); ?>-admin-notice-placeholder' ).show();
		<?php
		$javascript = ob_get_clean();

		wc_enqueue_js( $javascript );
	}


	/**
	 * Marks the identified admin notice as dismissed for the given user
	 *
	 * @since 3.0.0
	 * @param string $message_id the message identifier
	 * @param int $user_id optional user identifier, defaults to current user
	 */
	public function dismiss_notice( $message_id, $user_id = null ) {

		if ( is_null( $user_id ) ) {
			$user_id = get_current_user_id();
		}

		$dismissed_notices = $this->get_dismissed_notices( $user_id );

		$dismissed_notices[ $message_id ] = true;

		update_user_meta( $user_id, '_wc_plugin_framework_square_dismissed_messages', $dismissed_notices );

		/**
		 * Admin Notice Dismissed Action.
		 *
		 * Fired when a user dismisses an admin notice.
		 *
		 * @since 3.0.0
		 * @param string $message_id notice identifier
		 * @param string|int $user_id
		 */
		do_action( 'wc_square_dismiss_notice', $message_id, $user_id );
	}

	/**
	 * Returns true if the identified admin notice has been dismissed for the
	 * given user
	 *
	 * @since 3.0.0
	 * @param string $message_id the message identifier
	 * @param int $user_id optional user identifier, defaults to current user
	 * @return boolean true if the message has been dismissed by the admin user
	 */
	public function is_notice_dismissed( $message_id, $user_id = null ) {

		$dismissed_notices = $this->get_dismissed_notices( $user_id );

		return isset( $dismissed_notices[ $message_id ] ) && $dismissed_notices[ $message_id ];
	}


	/**
	 * Returns the full set of dismissed notices for the user identified by
	 * $user_id, for this plugin
	 *
	 * @since 3.0.0
	 * @param int $user_id optional user identifier, defaults to current user
	 * @return array of message id to dismissed status (true or false)
	 */
	public function get_dismissed_notices( $user_id = null ) {

		if ( is_null( $user_id ) ) {
			$user_id = get_current_user_id();
		}

		$dismissed_notices = get_user_meta( $user_id, '_wc_plugin_framework_square_dismissed_messages', true );

		if ( empty( $dismissed_notices ) ) {
			return array();
		} else {
			return $dismissed_notices;
		}
	}


	/** AJAX methods ******************************************************/


	/**
	 * Dismiss the identified notice
	 *
	 * @since 3.0.0
	 */
	public function handle_dismiss_notice() {
		$message_id     = isset( $_REQUEST['messageid'] ) ? sanitize_text_field( wp_unslash( $_REQUEST['messageid'] ) ) : false;
		$is_nonce_valid = isset( $_GET['notice_nonce'] ) ? wp_verify_nonce( sanitize_text_field( wp_unslash( $_GET['notice_nonce'] ) ), 'notice_nonce' ) : false;

		if ( ! $is_nonce_valid ) {
			wp_send_json_error( esc_html__( 'Nonce verification failed.', 'woocommerce-square' ) );
		}

		if ( ! $message_id ) {
			wp_send_json_error( esc_html__( 'Message ID empty.', 'woocommerce-square' ) );
		}

		$this->dismiss_notice( $message_id );

		wp_send_json_success();
	}


	/** Getter methods ******************************************************/


	/**
	 * Get the plugin
	 *
	 * @since 3.0.0
	 * @return Plugin returns the plugin instance
	 */
	protected function get_plugin() {
		return $this->plugin;
	}
}