'number', 'default' => 0 );
$args['attributes']['visigateRules'] = array( 'type' => 'object' );
return $args;
}
private static function has_rules( $block ) {
$a = $block['attrs'] ?? array();
return ! empty( $a['visigateSet'] ) || ! empty( $a['visigateRules'] );
}
private static function in_editor_context() {
if ( is_admin() ) {
return true;
}
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
return defined( 'REST_REQUEST' ) && REST_REQUEST && isset( $_GET['context'] ) && 'edit' === $_GET['context'];
}
public static function preview_enabled() {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
return Visigate_Admin::opt( 'admin_preview' ) && isset( $_GET['visigate_preview'] ) && current_user_can( visigate_capability() );
}
private static function block_visible( $block ) {
$a = $block['attrs'] ?? array();
if ( ! empty( $a['visigateSet'] ) && ! Visigate_Engine::set_visible( (int) $a['visigateSet'] ) ) {
return false;
}
if ( ! empty( $a['visigateRules'] ) && is_array( $a['visigateRules'] ) && ! Visigate_Engine::visible( $a['visigateRules'] ) ) {
return false;
}
return true;
}
public static function pre_render( $pre, $block ) {
if ( null !== $pre || ! self::has_rules( $block ) || self::in_editor_context() || self::preview_enabled() ) {
return $pre;
}
return self::block_visible( $block ) ? $pre : self::hidden_block_output( $block );
}
/**
* What a hidden block renders as. Empty by default; add-ons can return replacement ("fallback") HTML.
*
* @param array $block Parsed block.
*/
private static function hidden_block_output( $block ) {
$out = apply_filters( 'visigate_hidden_block_output', '', $block );
return is_string( $out ) ? $out : '';
}
/**
* What a hidden [visigate] shortcode renders as. Empty by default.
*
* @param array $atts Raw shortcode attributes (including any unknown ones, e.g. from add-ons).
*/
private static function hidden_shortcode_output( $atts ) {
$out = apply_filters( 'visigate_hidden_shortcode_output', '', (array) $atts );
return is_string( $out ) ? $out : '';
}
/**
* Admin preview: show hidden content faded and outlined in red instead of removing it.
*
* @param string $html Content that is hidden from the current visitor.
*/
private static function preview_wrap( $html ) {
return '
' . $html . '
';
}
/**
* Output for a [visigate] shortcode whose content is hidden: the fallback, or the
* revealed content while an administrator is using admin preview.
*
* @param array $atts Raw shortcode attributes.
* @param string $content Shortcode content.
*/
private static function hidden_shortcode( $atts, $content ) {
if ( self::preview_enabled() ) {
return self::preview_wrap( do_shortcode( (string) $content ) );
}
return self::hidden_shortcode_output( $atts );
}
public static function render_block( $content, $block ) {
if ( ! self::has_rules( $block ) || self::in_editor_context() ) {
return $content;
}
$visible = self::block_visible( $block );
if ( self::preview_enabled() ) {
return $visible ? $content : self::preview_wrap( $content );
}
return $visible ? $content : self::hidden_block_output( $block );
}
/** [visigate set="12" logged_in="yes" roles="customer,subscriber" device="mobile" bought="45,46" bought_days="30" hide="no"]…[/visigate] */
public static function shortcode( $atts, $content = '' ) {
$a = shortcode_atts(
array( 'set' => '', 'logged_in' => '', 'roles' => '', 'device' => '', 'bought' => '', 'bought_days' => '0', 'hide' => 'no' ),
$atts,
'visigate'
);
if ( '' !== $a['set'] && ! Visigate_Engine::set_visible( (int) $a['set'] ) ) {
return self::hidden_shortcode( $atts, $content );
}
$csv = function ( $s ) {
return array_values( array_filter( array_map( 'trim', explode( ',', (string) $s ) ) ) );
};
$conds = array();
if ( '' !== $a['logged_in'] ) {
$conds[] = array( 'type' => 'logged_in', 'op' => in_array( strtolower( $a['logged_in'] ), array( 'yes', '1', 'true' ), true ) ? 'is' : 'is_not', 'value' => null );
}
if ( $csv( $a['roles'] ) ) {
$conds[] = array( 'type' => 'user_role', 'op' => 'is_any', 'value' => $csv( $a['roles'] ) );
}
if ( $csv( $a['device'] ) ) {
$conds[] = array( 'type' => 'device', 'op' => 'is_any', 'value' => $csv( $a['device'] ) );
}
if ( $csv( $a['bought'] ) ) {
$conds[] = array( 'type' => 'woo_bought_product', 'op' => 'bought', 'value' => array_map( 'absint', $csv( $a['bought'] ) ), 'days' => (int) $a['bought_days'] );
}
if ( $conds ) {
$rules = array( 'action' => 'yes' === $a['hide'] ? 'hide' : 'show', 'groups' => array( array( 'conditions' => $conds ) ) );
if ( ! Visigate_Engine::visible( $rules ) ) {
return self::hidden_shortcode( $atts, $content );
}
}
return do_shortcode( $content );
}
/** Admin-bar toggle: preview what is being hidden on the current page. */
public static function admin_bar( $bar ) {
if ( is_admin() || ! current_user_can( visigate_capability() ) || ! Visigate_Admin::opt( 'admin_preview' ) ) {
return;
}
$on = self::preview_enabled();
$bar->add_node(
array(
'id' => 'visigate-preview',
/* translators: %s: plugin name */
'title' => sprintf( $on ? __( '%s: hide hidden content', 'visigate' ) : __( '%s: reveal hidden content', 'visigate' ), visigate_brand() ),
'href' => $on ? remove_query_arg( 'visigate_preview' ) : add_query_arg( 'visigate_preview', '1' ),
)
);
}
}