<?php
/**
 * Please see weepie-framework.php for more details.
 */

namespace WpieFw\Helpers;

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

/**
 * WpieAjaxHelper class
 *
 * Helper class for AJAX processes
 *
 * @author $Author: Vincent Weber <weepie-plugins@outlook.com> $
 * @since 1.0
 */
final class WpieAjaxHelper
{
	/**
	 * String for the global param
	 *
	 * @var string
	 */
	const WPIE_DOING_AJAX_STR = 'WPIE_DOING_AJAX';

	/**
	 * Validate ajax return data
	 *
	 * Data is valid to return when no errors, false values, empty values etc are found
	 *
	 * @access public
	 *
	 * @param mixed $data
	 * @param bool 	$allowFalse, if set to true, $data can be bool FALSE
	 *
	 * @since 1.0
	 *
	 * @return number 1 if valid else 0
	 */
	public static function isValidData( $data = false, $allowFalse = false )
	{
		if( $allowFalse )
			return ( self::hasWpError( $data ) || empty( $data ) ) ? 0 : 1;
		else
			return ( !$data || self::hasWpError( $data ) || empty( $data ) || ( is_array( $data ) && in_array( false, $data, true ) ) ) ? 0 : 1;
	}

	/**
	 * Determine if ajax return data contains a WP_Error object
	 *
	 * @access public
	 *
	 * @param mixed $data
	 *
	 * @uses WP_Error::is_wp_error()
	 *
	 * @since 1.0.8
	 *
	 * @return bool true or false
	 */
	public static function hasWpError( $data )
	{
		if( is_wp_error( $data ) ) {
			return true;
		}
		elseif( is_array( $data ) ) {

			foreach ( $data as $entry ) {

				if( is_wp_error( $entry ) )
					return true;
			}
		}
	}

	/**
	 * Retrieve WP_Error messages found in ajax return data
	 *
	 * @access public
	 *
	 * @param mixed $data
	 *
	 * @uses WP_Error::is_wp_error()
	 * @uses WP_Error::get_error_messages()
	 *
	 * @since 1.0.8
	 *
	 * @return array empty if no errors are found, otherwise array
	 */
	public static function getWpErrors( $data )
	{
		$msg = [];

		if( is_wp_error( $data ) ) {
			$msg = $data->get_error_messages();
		}
		elseif( is_array( $data ) ) {

			foreach ( $data as $entry ) {

				if( is_wp_error( $entry ) ) {
					$msg = $entry->get_error_messages();
					break;
				}
			}
		}

		return $msg;
	}

	/**
	 * Check if WPIE_BYPASS_AJAX_CHECK is defined
	 *
	 * @since 1.4.0
	 *
	 * @return boolean
	 */
	public static function needBypass()
	{
		return ( defined( 'WPIE_BYPASS_AJAX_CHECK' ) && true === WPIE_BYPASS_AJAX_CHECK );
	}

	/**
	 * Check if DOING_AJAX is defined
	 *
	 * @since 1.4.0
	 *
	 * @return boolean
	 */
	public static function doingAjax()
	{
		return ( defined( 'DOING_AJAX' ) && true === DOING_AJAX );
	}

	/**
	 * Check if doing Heartbeat
	 *
	 * @since 1.4.0
	 *
	 * @return boolean
	 */
	public static function doingHeartbeat()
	{
		if( self::doingAjax() && isset( $_REQUEST['action'] ) && 'heartbeat' === $_REQUEST['action'] ) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Check if request is a REST request
	 *
	 * @param $ns optional the plugin namespace
	 *
	 * @uses rest_get_url_prefix()
	 *
	 * @since 2.0.14
	 *
	 * @return boolean
	 */
	public static function doingRestRequest( $ns = '' )
	{
		if ( empty( $_SERVER['REQUEST_URI'] ) ) {
			return false;
		}

		$restPrefix = trailingslashit( rest_get_url_prefix() );

		if( $ns !== '' ) {
			$restPrefix = "$restPrefix/$ns/";
		}

		return strpos( $_SERVER['REQUEST_URI'], $restPrefix ) !== false;
	}

	/**
	 * Check if doing AJAX but no WeePie Ajax Action
	 *
	 * @since 1.4.0
	 *
	 * @return boolean
	 */
	public static function doingWithoutWpieAction()
	{
	    if( self::doingAjax() && !isset( $_REQUEST['action'] )) {
			return true;
		} elseif( self::doingAjax() && isset( $_REQUEST['action'] ) && 'wpie-action' !== $_REQUEST['action'] ) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * Check if doing WeePie Ajax Action
	 *
	 * @since 1.4.0
	 *
	 * @return boolean
	 */
	public static function doingWpieAction()
	{
	    if( self::doingAjax() && isset( $_REQUEST['action'] ) && 'wpie-action' === $_REQUEST['action'] ) {
			return true;
		} else {
			return false;
		}
	}

	/**
	 * If not yet done, define doing WeePie Ajax
	 *
	 * @since 1.4.0
	 */
	public static function maybeSetWpieAjaxGlobal()
	{
		if( self::doingWpieAction() && !defined( self::WPIE_DOING_AJAX_STR ) ) {
			define( self::WPIE_DOING_AJAX_STR, true );
		}
	}

	/**
	 * Determine if WeePie Framework should not continue in the current AJAX request
	 *
	 * @access public
	 *
	 * @uses self::needBypass()
	 * @uses self::doingHeartbeat()
	 * @uses self::doingWithoutWpieAction()
	 * @uses self::doingWpieAction()
	 * @uses self::maybeSetWpieAjaxGlobal()
	 *
	 * @since 1.4.0
	 */
	public static function maybeQuitForAjax()
	{
		if( !self::needBypass() ) {
			// Prevent plugins from executing during WP heartbeat AJAX calls
			if( self::doingHeartbeat() ) {
				return true;
			} elseif( self::doingWithoutWpieAction() ) {
				// only allow WeePie Framework AJAX calls
				return true;
			}
		}

		return false;
	}
}