asset_data_registry->add( 'needsRefreshForInteractivityAPI', true );
}
/**
* Enqueue assets used for rendering the block in editor context.
*
* This is needed if a block is not yet within the post content--`render` and `enqueue_assets` may not have ran.
*/
public function enqueue_block_assets() {
// Ensures frontend styles for blocks exist in the site editor iframe.
if ( class_exists( 'WC_Frontend_Scripts' ) && is_admin() ) {
$frontend_scripts = new WC_Frontend_Scripts();
$styles = $frontend_scripts::get_styles();
foreach ( $styles as $handle => $style ) {
wp_enqueue_style(
$handle,
set_url_scheme( $style['src'] ),
$style['deps'],
$style['version'],
$style['media']
);
}
}
}
/**
* Render method for the Classic Template block. This method will determine which template to render.
*
* @param array $attributes Block attributes.
* @param string $content Block content.
* @param WP_Block $block Block instance.
* @return string | void Rendered block type output.
*/
protected function render( $attributes, $content, $block ) {
if ( ! isset( $attributes['template'] ) ) {
return;
}
/**
* We need to load the scripts here because when using block templates wp_head() gets run after the block
* template. As a result we are trying to enqueue required scripts before we have even registered them.
*
* @see https://github.com/woocommerce/woocommerce-gutenberg-products-block/issues/5328#issuecomment-989013447
*/
if ( class_exists( 'WC_Frontend_Scripts' ) ) {
$frontend_scripts = new WC_Frontend_Scripts();
$frontend_scripts::load_scripts();
}
if ( OrderConfirmationTemplate::SLUG === $attributes['template'] ) {
return $this->render_order_received();
}
if ( is_product() ) {
return $this->render_single_product();
}
$valid = false;
$archive_templates = array(
ProductCatalogTemplate::SLUG,
ProductCategoryTemplate::SLUG,
ProductTagTemplate::SLUG,
ProductAttributeTemplate::SLUG,
ProductSearchResultsTemplate::SLUG,
);
// Set selected template when we directly find template base slug.
if ( in_array( $attributes['template'], $archive_templates, true ) ) {
$valid = true;
}
// Set selected template when we find template base slug as prefix for a specific term.
foreach ( $archive_templates as $template ) {
if ( 0 === strpos( $attributes['template'], $template ) ) {
$valid = true;
}
}
if ( $valid ) {
// Set this so that our product filters can detect if it's a PHP template.
$this->asset_data_registry->add( 'isRenderingPhpTemplate', true );
// Set this so filter blocks being used as widgets know when to render.
$this->asset_data_registry->add( 'hasFilterableProducts', true );
$this->asset_data_registry->add(
'pageUrl',
html_entity_decode( get_pagenum_link() )
);
return $this->render_archive_product();
}
ob_start();
echo "You're using the ClassicTemplate block";
wp_reset_postdata();
return ob_get_clean();
}
/**
* Render method for rendering the order confirmation template.
*
* @return string Rendered block type output.
*/
protected function render_order_received() {
ob_start();
echo '
';
echo sprintf(
'<%1$s %2$s>%3$s%1$s>',
'h1',
get_block_wrapper_attributes(), // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped
esc_html__( 'Order confirmation', 'woocommerce' )
);
WC_Shortcode_Checkout::output( array() );
echo '
';
return ob_get_clean();
}
/**
* Render method for the single product template and parts.
*
* @return string Rendered block type output.
*/
protected function render_single_product() {
ob_start();
/**
* Hook: woocommerce_before_main_content
*
* Called before rendering the main content for a product.
*
* @see woocommerce_output_content_wrapper() Outputs opening DIV for the content (priority 10)
* @see woocommerce_breadcrumb() Outputs breadcrumb trail to the current product (priority 20)
* @see WC_Structured_Data::generate_website_data() Outputs schema markup (priority 30)
*
* @since 6.3.0
*/
do_action( 'woocommerce_before_main_content' );
$product_query = new \WP_Query(
array(
'post_type' => 'product',
'p' => get_the_ID(),
)
);
while ( $product_query->have_posts() ) :
$product_query->the_post();
wc_get_template_part( 'content', 'single-product' );
endwhile;
/**
* Hook: woocommerce_after_main_content
*
* Called after rendering the main content for a product.
*
* @see woocommerce_output_content_wrapper_end() Outputs closing DIV for the content (priority 10)
*
* @since 6.3.0
*/
do_action( 'woocommerce_after_main_content' );
wp_reset_postdata();
return ob_get_clean();
}
/**
* Render method for the archive product template and parts.
*
* @return string Rendered block type output.
*/
protected function render_archive_product() {
ob_start();
/**
* Hook: woocommerce_before_main_content
*
* Called before rendering the main content for a product.
*
* @see woocommerce_output_content_wrapper() Outputs opening DIV for the content (priority 10)
* @see woocommerce_breadcrumb() Outputs breadcrumb trail to the current product (priority 20)
* @see WC_Structured_Data::generate_website_data() Outputs schema markup (priority 30)
*
* @since 6.3.0
*/
do_action( 'woocommerce_before_main_content' );
?>
block_name ) !== $block['blockName'] ) {
return $content;
}
$attributes = (array) $block['attrs'];
// Set the default alignment to wide.
if ( ! isset( $attributes['align'] ) ) {
$attributes['align'] = 'wide';
}
$align_class_and_style = StyleAttributesUtils::get_align_class_and_style( $attributes );
if ( ! isset( $align_class_and_style['class'] ) ) {
return $content;
}
// Find the first tag.
$first_tag = '<[^<>]+>';
$matches = array();
preg_match( $first_tag, $content, $matches );
// If there is a tag, but it doesn't have a class attribute, add the class attribute.
if ( isset( $matches[0] ) && strpos( $matches[0], ' class=' ) === false ) {
$pattern_before_tag_closing = '/.+?(?=>)/';
return preg_replace( $pattern_before_tag_closing, '$0 class="' . $align_class_and_style['class'] . '"', $content, 1 );
}
// If there is a tag, and it has a class already, add the class attribute.
$pattern_get_class = '/(?<=class=\"|\')[^"|\']+(?=\"|\')/';
return preg_replace( $pattern_get_class, '$0 ' . $align_class_and_style['class'], $content, 1 );
}
/**
* Get the frontend style handle for this block type.
*
* @return null
*/
protected function get_block_type_style() {
return null;
}
}