Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Itinerary Block and Pattern #340

Merged
merged 9 commits into from
Sep 13, 2024
28 changes: 28 additions & 0 deletions assets/js/blocks/variations.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@

wp.domReady(() => {
wp.blocks.registerBlockVariation('core/group', {
name: 'lsx/itinerary',
title: 'Itinerary',
attributes: {
metadata: {
name: 'Itinerary',
bindings: {
content: {
source: 'lsx/tour-itinerary'
}
}
},
align: 'wide',
layout: {
type: 'constrained'
}
},
innerBlocks: [
['core/paragraph', {
placeholder: 'Insert your Itinerary pattern here.',
align: 'center'
}]
],
isDefault: false
});
});
195 changes: 184 additions & 11 deletions includes/classes/blocks/class-bindings.php
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,7 @@ class Bindings {
*/
public function __construct() {
add_action( 'init', array( $this, 'register_block_bindings' ) );
add_filter( 'render_block', array( $this, 'render_itinerary_block' ), 10, 3 );
}

/**
Expand Down Expand Up @@ -62,13 +63,21 @@ public function register_block_bindings() {
)
);

/*register_block_bindings_source(
register_block_bindings_source(
'lsx/tour-itinerary',
array(
'label' => __( 'Tour Itinerary', 'lsx-wetu-importer' ),
'get_value_callback' => array( $this, 'lsx_wetu_bindings_itinerary_callback' )
'get_value_callback' => array( $this, 'itinerary_callback' )
)
);*/
);

register_block_bindings_source(
'lsx/itinerary-field',
array(
'label' => __( 'Itinerary Field', 'lsx-wetu-importer' ),
'get_value_callback' => array( $this, 'itinerary_field_callback' )
)
);
}

public function post_connections_callback( $source_args, $block_instance ) {
Expand Down Expand Up @@ -133,24 +142,32 @@ public function post_meta_callback( $source_args, $block_instance ) {
return $value;
}

public function lsx_wetu_bindings_itinerary_callback( $source_args, $block_instance ) {
public function itinerary_callback( $source_args, $block_instance ) {
if ( 'core/paragraph' === $block_instance->parsed_block['blockName'] ) {

return 'bindings';
}
}

public function itinerary_field_callback( $source_args, $block_instance ) {
if ( 'core/image' === $block_instance->parsed_block['blockName'] ) {
$value = 'test_image';
} elseif ( 'core/paragraph' === $block_instance->parsed_block['blockName'] || 'core/heading' === $block_instance->parsed_block['blockName'] ) {
$value = 'itin_field';
}
return $value;
}

//add_filter( 'render_block', 'lsx_wetu_render_block', 10, 3 );
function lsx_wetu_render_block( $block_content, $parsed_block, $block_obj ) {

public function render_itinerary_block( $block_content, $parsed_block, $block_obj ) {
// Determine if this is the custom block variation.
if ( ! isset( $parsed_block['blockName'] ) || ! isset( $parsed_block['attrs'] ) ) {
return $block_content;
}
$allowed_blocks = array(
'core/paragraph'
'core/group'
);
$allowed_sources = array(
'core/post-meta',
'lsx/post-connection'
'lsx/tour-itinerary'
);
if ( ! in_array( $parsed_block['blockName'], $allowed_blocks, true ) ) {
return $block_content;
Expand All @@ -164,16 +181,172 @@ function lsx_wetu_render_block( $block_content, $parsed_block, $block_obj ) {
return $block_content;
}

$pattern = $block_content;
$group = array();

// Iterate through and build our itinerary from the block content template.
if ( lsx_to_has_itinerary() ) {
$itinerary_count = 1;
while ( lsx_to_itinerary_loop() ) {
lsx_to_itinerary_loop_item();
$build = $pattern;
$build = $this->build_itinerary_field( $build, 'title' );
$build = $this->build_itinerary_field( $build, 'description' );
$build = $this->build_itinerary_field( $build, 'location' );
$build = $this->build_itinerary_field( $build, 'accommodation' );
$build = $this->build_itinerary_field( $build, 'type' );
$build = $this->build_itinerary_field( $build, 'drinks' );
$build = $this->build_itinerary_field( $build, 'room' );
$build = $this->build_itinerary_image( $build );
$group[] = $build;

$itinerary_count++;
}
}

$block_content = implode( '', $group );
return $block_content;
}
}

/**
* Modifies the HTML content by updating the innerHTML of any heading tag (h1-h6)
* that has the class "itinerary-title" with the result of the lsx_to_itinerary_title function.
*
* @param string $build The original HTML content to be modified. Default is an empty string.
* @param string $field The field to build.
* @return string The modified HTML content where the specified heading tags have updated innerHTML.
*/
public function build_itinerary_field( $build = '', $field = '' ) {
$pattern = '';
$replacement = '';
switch ( $field ) {
case 'title':
// Regular expression to match any heading tag (h1-h6) with class "itinerary-title"
$pattern = '/(<h[1-6]\s+[^>]*\bclass="[^"]*\bitinerary-title\b[^"]*"[^>]*>).*?(<\/h[1-6]>)/is';

// Replacement pattern to insert "test" as the new innerHTML
$replacement = '$1' . lsx_to_itinerary_title( false ) . '$2';
break;

case 'description':
// Maintain any formatting set of the parent tag.
$classes = $this->find_description_classes( $build );
if ( '' !== $classes ) {
// Regular expression to replace any paragraph with class "itinerary-description"
$pattern = '/<p\s+[^>]*\bclass="[^"]*\bitinerary-description\b[^"]*"[^>]*>.*?<\/p>/is';
// Replacement pattern to insert "test" as the new innerHTML
$replacement = '$1<div class="' . $classes . '"/>' . lsx_to_itinerary_description( false ) . '</div>$2';
}
break;

case 'location':
// Regular expression to match any paragraph tag with class "itinerary-location"
$pattern = '/(<p\s+[^>]*\bclass="[^"]*\bitinerary-location\b[^"]*"[^>]*>).*?(<\/p>)/is';

// Replacement pattern to insert "test" as the new innerHTML
$replacement = '$1' . lsx_to_itinerary_destinations( '', '', false ) . '$2';
break;

case 'accommodation':
// Regular expression to match any paragraph tag with class "itinerary-accommodation"
$pattern = '/(<p\s+[^>]*\bclass="[^"]*\bitinerary-accommodation\b[^"]*"[^>]*>).*?(<\/p>)/is';

// Replacement pattern to insert "test" as the new innerHTML
$replacement = '$1' . lsx_to_itinerary_accommodation( '', '', false ) . '$2';
break;

case 'type':
// Regular expression to match any paragraph tag with class "itinerary-accommodation"
$pattern = '/(<p\s+[^>]*\bclass="[^"]*\bitinerary-type\b[^"]*"[^>]*>).*?(<\/p>)/is';

// Replacement pattern to insert "test" as the new innerHTML
$replacement = '$1' . lsx_to_itinerary_accommodation_type( '', '', false ) . '$2';
break;

case 'drinks':
// Regular expression to match any paragraph tag with class "itinerary-accommodation"
$pattern = '/(<p\s+[^>]*\bclass="[^"]*\bitinerary-drinks\b[^"]*"[^>]*>).*?(<\/p>)/is';

// Replacement pattern to insert "test" as the new innerHTML
$replacement = '$1' . lsx_to_itinerary_drinks_basis( '', '', false ) . '$2';
break;

case 'room':
// Regular expression to match any paragraph tag with class "itinerary-accommodation"
$pattern = '/(<p\s+[^>]*\bclass="[^"]*\bitinerary-room\b[^"]*"[^>]*>).*?(<\/p>)/is';

// Replacement pattern to insert "test" as the new innerHTML
$replacement = '$1' . lsx_to_itinerary_room_basis( '', '', false ) . '$2';
break;

default:
break;
}

// Perform the replacement if the pattern is not empty
if ( '' !== $pattern ) {
$build = preg_replace($pattern, $replacement, $build);
}
return $build;
}

/**
* Modifies the HTML content by updating the innerHTML of any heading tag (h1-h6)
* that has the class "itinerary-title" with the result of the lsx_to_itinerary_title function.
*
* @param string $build The original HTML content to be modified. Default is an empty string.
* @param string $field The field to build.
* @return string The modified HTML content where the specified heading tags have updated innerHTML.
*/
public function build_itinerary_image( $build = '' ) {

//Create our tag manager object so we can inject the itinerary content.
$tags = new \WP_HTML_Tag_Processor( $build );
if ( $tags->next_tag( array( 'class_name' => 'itinerary-image' ) ) ) {
if ( $tags->next_tag( array( 'tag_name' => 'img' ) ) ) {
$img_src = lsx_to_itinerary_thumbnail();
$tags->set_attribute( 'src', $img_src );
$build = $tags->get_updated_html();
}
}

return $build;
}

/**
* Finds all class names of the <p> tag that includes the class "itinerary-description".
*
* @param string $content The original HTML content.
* @return string An string containing class names found with "itinerary-description".
*/
public function find_description_classes( $content ) {
$classes = '';

// Regular expression to match any <p> tag with class "itinerary-description" among other classes
$pattern = '/<p\s+[^>]*\bclass="([^"]*\bitinerary-description\b[^"]*)"/is';
// Array to hold the matches
$matches = [];
// Perform the matching
$match_count = preg_match_all( $pattern, $content, $matches );
// $matches[1] contains the matched class attribute values

if ( 0 < $match_count ) {
$classes = implode( '', $matches[1] );
}
return $classes;
}

/**
* Removes all "class" attributes from a given HTML content.
*
* @param string $content The original HTML content.
* @return string The HTML content without any "class" attributes.
*/
function purge_class_attribute( $content ) {
// Regular expression to match class attributes
$pattern = '/\s*class="[^"]*"/i';
// Replace matched class attributes with an empty string
$result = preg_replace($pattern, '', $content);
return $result;
}
}
Loading
Loading