<?php
/**
 * Backend-editor live preview.
 *
 * WPBakery's backend editor shows elements as plain grey blocks, so setting
 * changes (layout, rating, colors) are invisible until the page is previewed.
 * This AJAX endpoint renders one of our elements server-side from its current
 * params; the editor script injects the HTML into the element's block.
 *
 * @package CraftAddonsForWPBakery
 */

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

/**
 * Class CAFW_Preview
 */
class CAFW_Preview {

	/**
	 * Register the AJAX endpoint (logged-in users only - the backend editor).
	 *
	 * @return void
	 */
	public static function init() {
		add_action( 'wp_ajax_cafw_render_preview', array( __CLASS__, 'render' ) );
	}

	/**
	 * Render an element from posted params and return its HTML.
	 *
	 * Only this plugin's own, currently enabled elements are renderable, and
	 * every value still passes through the element's normal sanitization in
	 * render() - the same path a saved page takes.
	 *
	 * @return void
	 */
	public static function render() {
		check_ajax_referer( 'cafw_preview', 'nonce' );

		if ( ! current_user_can( 'edit_posts' ) ) {
			wp_send_json_error( null, 403 );
		}

		$tag    = isset( $_POST['tag'] ) ? sanitize_key( wp_unslash( $_POST['tag'] ) ) : '';
		$params = isset( $_POST['params'] ) ? json_decode( wp_unslash( $_POST['params'] ), true ) : null; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- decoded values sanitized below.
		if ( ! is_array( $params ) ) {
			$params = array();
		}

		$element = null;
		foreach ( cafw()->get_loader()->get_elements() as $slug => $candidate ) {
			if ( $candidate->get_shortcode_tag() === $tag && CAFW_Settings::is_element_enabled( $slug ) ) {
				$element = $candidate;
				break;
			}
		}
		if ( null === $element ) {
			wp_send_json_error( null, 400 );
		}

		$atts = array();
		foreach ( $params as $key => $value ) {
			if ( is_scalar( $value ) ) {
				$atts[ sanitize_key( $key ) ] = (string) $value;
			}
		}

		wp_send_json_success( $element->shortcode( $atts, null ) );
	}
}
