'async',
'in_footer' => true,
)
);
// Plain JavaScript on the editor's globals, so the plugin needs no build step.
wp_register_script(
self::EDITOR_SCRIPT,
plugins_url( 'blocks/widget/index.js', EGIFT_PLUGIN_FILE ),
array( 'wp-api-fetch', 'wp-block-editor', 'wp-blocks', 'wp-components', 'wp-element' ),
EGIFT_VERSION,
true
);
register_block_type(
EGIFT_PLUGIN_DIR . 'blocks/widget',
array(
'editor_script_handles' => array( self::EDITOR_SCRIPT ),
'render_callback' => array( __CLASS__, 'render_block' ),
)
);
add_shortcode( self::SHORTCODE, array( __CLASS__, 'render_shortcode' ) );
}
/**
* The block on the page.
*
* @param array $attributes The block's accent and experience.
* @return string
*/
public static function render_block( $attributes ) {
$html = self::render( is_array( $attributes ) ? $attributes : array() );
return '' === $html ? '' : '
' . $html . '
';
}
/**
* [egift accent="#c0392b" experience="12"], for page builders that do not support blocks.
*
* @param array|string $atts The shortcode attributes.
* @return string
*/
public static function render_shortcode( $atts ) {
$atts = shortcode_atts(
array(
'accent' => '',
'experience' => '',
),
array_change_key_case( (array) $atts, CASE_LOWER ),
self::SHORTCODE
);
return self::render( $atts );
}
/**
* The Widget snippet for the connected merchant. Without a connected merchant there is no
* Widget to show: the site's admin gets a hint to connect, visitors see nothing.
*
* @param array $attributes accent: a hex color; experience: a Belevenisbon id, or empty for all.
* @return string
*/
public static function render( array $attributes ) {
$merchant_id = Egift_Settings::merchant_id();
if ( '' === $merchant_id ) {
return self::connect_hint();
}
wp_enqueue_script( self::SCRIPT );
$accent = self::sanitize_accent( isset( $attributes['accent'] ) ? $attributes['accent'] : '' );
$experience = absint( isset( $attributes['experience'] ) ? $attributes['experience'] : 0 );
$html = ' 0 ) {
$html .= ' data-egift-experience="' . esc_attr( (string) $experience ) . '"';
}
if ( '' !== $accent ) {
$html .= ' data-egift-accent="' . esc_attr( $accent ) . '"';
}
return $html . '>
';
}
/**
* A hex color as eGift accepts it for the Widget's accent, or '' for eGift's own color. The
* leading # may be left out, as merchants often copy a color code without it.
*
* @param mixed $accent The color as entered.
* @return string
*/
public static function sanitize_accent( $accent ) {
if ( is_string( $accent ) && preg_match( '/^#?([0-9a-f]{3,4}|[0-9a-f]{6}|[0-9a-f]{8})$/i', trim( $accent ), $match ) ) {
return '#' . $match[1];
}
return '';
}
/**
* Hands the block editor what it shows without asking eGift: whether this site is connected,
* to whom, and the texts. The Belevenisbon list is fetched only once the block is used.
*/
public static function add_editor_data() {
$data = array(
'connected' => '' !== Egift_Settings::merchant_id(),
'companyName' => (string) Egift_Settings::get( 'company_name' ),
'settingsUrl' => Egift_Settings::page_url(),
'strings' => array(
'title' => __( 'eGift Widget', 'egift' ),
/* translators: %s: the Merchant's company name in eGift. */
'preview' => __( 'The gift vouchers of %s appear here on your page.', 'egift' ),
'previewUnknown' => __( 'Your eGift gift vouchers appear here on your page.', 'egift' ),
/* translators: %s: the title of a Belevenisbon. */
'previewOne' => __( 'Only the experience voucher "%s".', 'egift' ),
'notConnected' => __( 'This site is not connected to eGift yet. Connect it under Settings > eGift, then your gift vouchers appear here.', 'egift' ),
'connect' => __( 'Connect to eGift', 'egift' ),
'panel' => __( 'Widget', 'egift' ),
'accent' => __( 'Accent color', 'egift' ),
'accentHelp' => __( 'Colors the buttons in the Widget. Without a color the Widget uses the eGift colors.', 'egift' ),
'experience' => __( 'Experience voucher', 'egift' ),
'allVouchers' => __( 'All your gift vouchers', 'egift' ),
'experienceHelp' => __( 'Choose one experience voucher to sell only that one on this page.', 'egift' ),
'loading' => __( 'Loading your experience vouchers…', 'egift' ),
'unreachable' => __( 'eGift cannot be reached right now, so your experience vouchers cannot be shown.', 'egift' ),
'notForSale' => __( 'No longer for sale', 'egift' ),
),
);
wp_add_inline_script(
self::EDITOR_SCRIPT,
'window.egiftWidget = ' . wp_json_encode( $data ) . ';',
'before'
);
}
/**
* GET /wp-json/egift/v1/experiences: the connected merchant's sellable Belevenisbonnen, for
* the block setting. Asked from the editor only when the block is on the page, so opening the
* editor never waits for eGift.
*/
public static function register_rest_route() {
register_rest_route(
'egift/v1',
'/experiences',
array(
'methods' => 'GET',
'callback' => array( __CLASS__, 'experiences' ),
'permission_callback' => function () {
return current_user_can( 'edit_posts' );
},
)
);
}
/**
* The experiences from the merchant lookup, as a list of id and title.
*
* @return array|WP_Error
*/
public static function experiences() {
$merchant_id = Egift_Settings::merchant_id();
if ( '' === $merchant_id ) {
return new WP_Error( 'egift_not_connected', 'This site is not connected to eGift.', array( 'status' => 409 ) );
}
$lookup = Egift_Api::lookup_merchant( $merchant_id );
if ( ! is_array( $lookup ) ) {
return new WP_Error( 'egift_unreachable', 'eGift could not be reached.', array( 'status' => 502 ) );
}
$experiences = array();
foreach ( isset( $lookup['experiences'] ) && is_array( $lookup['experiences'] ) ? $lookup['experiences'] : array() as $experience ) {
if ( is_array( $experience ) && ! empty( $experience['id'] ) ) {
$experiences[] = array(
'id' => (int) $experience['id'],
'title' => isset( $experience['title'] ) ? (string) $experience['title'] : '',
);
}
}
return $experiences;
}
/**
* Shown instead of the Widget while no merchant is connected, only to whom can connect one.
*
* @return string
*/
private static function connect_hint() {
if ( ! current_user_can( 'manage_options' ) ) {
return '';
}
return ''
. esc_html__( 'This site is not connected to eGift yet. Connect it under Settings > eGift, then your gift vouchers appear here.', 'egift' )
. ' '
. esc_html__( 'Connect to eGift', 'egift' ) . '
';
}
}