diff --git a/includes/block-override-functions.php b/includes/block-override-functions.php
index a2a6b0a..2ca503f 100644
--- a/includes/block-override-functions.php
+++ b/includes/block-override-functions.php
@@ -3,6 +3,8 @@
* Implements common functions used in block overrides
*
*/
+require_once __DIR__ . '/class-block-recursion-control.php';
+
/**
* Overrides a core block's render_callback method, if required.
@@ -26,40 +28,15 @@ function fizzie_maybe_override_block( $args, $blockname, $render_callback ) {
return $args;
}
-
/**
* Determines whether or not to process this content.
*
* @param string|integer Unique ID for the content
* @return bool - true if the post has not been processed. false otherwise
*/
-function fizzie_process_this_content( $id ) {
- global $fizzie_processed_content;
- // Use this rather than context['postId']
- global $post;
- $fizzie_processed = bw_array_get( $fizzie_processed_content, $id, false );
-
- /*
- if ( empty( $fizzie_processed_content ) ) {
- $global_id = isset( $post ) ? $post->ID : null;
- if ( $global_id ) {
- $fizzie_processed_content[ $global_id ] = $global_id;
- }
- }
- */
-
-
- if ( !$fizzie_processed ) {
- $fizzie_processed_content[$id] = $id ;
- }
-
- /** Stop when it looks highly likely we've missed something */
- if ( count( $fizzie_processed_content ) > 10 ) {
- $fizzie_processed = true;
-
- }
- bw_trace2( $fizzie_processed_content, "processed posts", true, BW_TRACE_DEBUG );
- return( !$fizzie_processed );
+function fizzie_process_this_content( $id ) {
+ $recursion_control = Fizzie_Block_Recursion_Control::get_instance();
+ return $recursion_control->process_this_content( $id );
}
/**
@@ -74,15 +51,12 @@ function fizzie_process_this_content( $id ) {
* - core/block - possibly
*
* Note: The top level is within the template, which loads the template parts and/or queries.
+ *
+ * @param string|integer $id
*/
function fizzie_clear_processed_content( $id=null ) {
- global $fizzie_processed_content;
- if ( $id ) {
- array_pop( $fizzie_processed_content );
- } else {
- $fizzie_processed_content = array();
- }
- bw_trace2( $fizzie_processed_content, "cleared", false, BW_TRACE_DEBUG );
+ $recursion_control = Fizzie_Block_Recursion_Control::get_instance();
+ $recursion_control->clear_processed_content( $id );
}
/**
@@ -92,102 +66,11 @@ function fizzie_clear_processed_content( $id=null ) {
*
* @param $id string|integer recursive ID detected
* @param $type string content type
- * @return string
+ * @return string HTML reporting the error to the user
*/
function fizzie_report_recursion_error( $id, $type='core/post-content') {
- bw_trace2();
- bw_backtrace();
- global $bad_id, $bad_fizzie_processed_content, $fizzie_processed_content;
- $bad_id = $id;
- $bad_fizzie_processed_content = $fizzie_processed_content;
-
- $content = array();
- $content[] = '
';
- switch ( $type ) {
- case 'core/post-content':
- $content[] = __( 'Content not available; already processed.', 'fizzie' );
- break;
- case 'core/template-part':
- $content[] = __( 'Template part not processed to avoid infinite recursion', 'fizzie');
- break;
- case 'core/block':
- $content[] = __( 'Reusable block not processed to avoid infinite recursion', 'fizzie');
- fizzie_add_filter_rest_prepare_wp_block();
- break;
- default:
- $content[] = __( 'Infinite recursion error prevented', 'fizzie');
- }
- if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
- $content[] = "";
- $content[] = '
';
- $content[] = $id;
- $content[] = '
';
- $content[] = $type;
- $content[] = '
';
- global $fizzie_processed_content;
- $content[] = implode( ',', $fizzie_processed_content );
- $content[] = '';
- }
- $content[] = '
';
- $content = implode( " \n", $content);
- return $content;
-}
-
-function fizzie_add_filter_rest_prepare_wp_block() {
- // We only need to do this in REST API processing
- // But this will only be called in REST API processing
- // So no need to check
- add_filter('rest_prepare_wp_block', 'fizzie_rest_prepare_wp_block', 10, 3);
+ $recursion_control = Fizzie_Block_Recursion_Control::get_instance();
+ $html = $recursion_control->report_recursion_error($id, $type);
+ return $html;
}
-/**
- *
- * Fiddle with the raw content to remove the wp:block block.
- *
- * [raw] =>
-This is reusable block 21117
-
-
-
- * @param $response
- * @param $post
- * @param $request
- * @return mixed#
- */
-function fizzie_rest_prepare_wp_block( $response, $post, $request ) {
- bw_trace2();
- bw_backtrace();
- global $bad_id;
- global $bad_fizzie_processed_content;
- $content = $response->data['content']['raw'];
- $content = fizzie_replace_bad( $content, $bad_id );
- foreach ( $bad_fizzie_processed_content as $id ) {
- $content = fizzie_replace_bad( $content, $id );
- }
- // Convert any remaining to a missing block
- $content = str_replace( "wp:block {", "missing {", $content );
-
- $response->data['content']['raw'] = $content;
- bw_trace2( $response, "response", false );
- return $response;
-}
-
-function fizzie_replace_bad( $content, $bad_id ) {
- $replacement_block = "";
- $replacement_block .= sprintf(__('Error: Recursion was detected while loading the reusable block with post ID %1$s. '), $bad_id);
- $replacement_block .= fizzie_title_link($bad_id);
- $replacement_block .= '
';
- $replacement_block .= "Recommendation: Please delete this block.";
- $replacement_block .= "";
- $content = str_replace("", $replacement_block, $content);
- return $content;
-}
-
-
-function fizzie_title_link( $id ) {
- $link = sprintf( '%s', esc_url( get_permalink( $id ) ), esc_html( get_the_title( $id ) ) );
- return $link;
-}
-
-
-
diff --git a/includes/block-overrides.php b/includes/block-overrides.php
index 05f19ac..4d52f4d 100644
--- a/includes/block-overrides.php
+++ b/includes/block-overrides.php
@@ -4,13 +4,14 @@
*
*/
require_once __DIR__ . '/block-override-functions.php';
+require_once __DIR__ . '/class-block-recursion-control.php';
/**
* Here we include the blocks we want to override.
*
* Either comment out the ones that aren't needed any more - when Gutenberg/core's
* satisfies the requirement
- * or find another way of automatically determining whether or not to include the file.
+ * or find another way to automatically determine whether or not to include the file.
*/
require_once __DIR__ . '/query-pagination.php';
require_once __DIR__ . '/query-loop.php';
@@ -27,7 +28,6 @@
*/
add_filter( 'register_block_type_args', 'fizzie_register_block_type_args', 9 );
-
/**
* Implements overrides for core blocks which we need to improve.
*
diff --git a/includes/class-block-recursion-control.php b/includes/class-block-recursion-control.php
new file mode 100644
index 0000000..52acf25
--- /dev/null
+++ b/includes/class-block-recursion-control.php
@@ -0,0 +1,223 @@
+processed_content[ $id ] );
+ if ( !$processed ) {
+ $this->processed_content[$id] = $id ;
+ }
+
+ /** Stop when it looks highly likely we've missed something */
+ if ( count( $this->processed_content ) > 10 ) {
+ $processed = true;
+
+ }
+ bw_trace2( $this->processed_content, "processed posts", true, BW_TRACE_DEBUG );
+ return( !$processed );
+ }
+
+ /**
+ * Pops or clears the array of processed content.
+ *
+ * As we return to the previous level we can clear the processed content.
+ * Basically this is something we have to do while processing certain inner blocks:
+ *
+ * - core/post-content
+ * - core/template-part
+ * - core/post-excerpt - possibly
+ * - core/block - possibly
+ *
+ * Note: The top level is within the template, which loads the template parts and/or queries.
+ */
+ function clear_processed_content( $id=null ) {
+ if ( $id ) {
+ array_pop( $this->processed_content );
+ } else {
+ $this->processed_content = array();
+ }
+ bw_trace2( $this->processed_content, "cleared", false, BW_TRACE_DEBUG );
+ }
+
+ /**
+ * Reports a recursion error to the user.
+ *
+ * If WP_DEBUG is true then additional information is displayed.
+ *
+ * @param $id string|integer recursive ID detected
+ * @param $type string content type
+ * @return string
+ */
+ function report_recursion_error( $id, $type='core/post-content') {
+ bw_trace2();
+ bw_backtrace();
+
+ $this->bad_id = $id;
+ $this->bad_processed_content = $this->processed_content;
+ // $content = $this->create_basic_error();
+
+ $content = array();
+ $content[] = '';
+ switch ( $type ) {
+ case 'core/post-content':
+ $content[] = __( 'Content not available; already processed.', 'fizzie' );
+ break;
+ case 'core/template-part':
+ $content[] = __( 'Template part not processed to avoid infinite recursion', 'fizzie');
+ break;
+ case 'core/block':
+ $content[] = __( 'Reusable block not processed to avoid infinite recursion', 'fizzie');
+ $this->add_filter_rest_prepare_wp_block();
+ break;
+ default:
+ $content[] = __( 'Infinite recursion error prevented', 'fizzie');
+ }
+ if ( defined( 'WP_DEBUG' ) && WP_DEBUG ) {
+ $content[] = "";
+ $content[] = '
';
+ $content[] = $id;
+ $content[] = '
';
+ $content[] = $type;
+ $content[] = '
';
+
+ $content[] = implode( ',', $this->processed_content );
+ $content[] = '';
+ }
+ $content[] = '
';
+ $content = implode( " \n", $content);
+ return $content;
+ }
+
+ /**
+ * Adds a filter hook to alter the response for wp_block.
+ *
+ * There's no need to check if it is REST API processing.
+ * The hook function won't get called if it isn't.
+ */
+ function add_filter_rest_prepare_wp_block() {
+ add_filter( 'rest_prepare_wp_block', [ $this, 'rest_prepare_wp_block' ], 10, 3 );
+ }
+
+ /**
+ * Fiddles with the raw content to remove `wp:block` blocks.
+ * `
+ * [raw] =>
+ * This is reusable block 21117
+ *
+ *
+ * `
+ * @param $response
+ * @param $post
+ * @param $request
+ * @return mixed
+ */
+ function rest_prepare_wp_block( $response, $post, $request ) {
+ bw_trace2();
+ bw_backtrace();
+
+ $content = $response->data['content']['raw'];
+ $content = $this->replace_bad( $content, $this->bad_id );
+ foreach ( $this->processed_content as $id ) {
+ $content = $this->replace_bad( $content, $id );
+ }
+ // Convert any remaining `wp:block` values to a `missing` block.
+ $content = str_replace( "wp:block {", "missing {", $content );
+
+ $response->data['content']['raw'] = $content;
+ bw_trace2( $response, "response", false );
+ return $response;
+ }
+
+ /**
+ * Replaces wp:block for ref:bad_id with a paragraph.
+ *
+ * @param $content
+ * @param $bad_id
+ * @return string|string[]
+ */
+ function replace_bad( $content, $bad_id ) {
+ $replacement_block = "";
+ $replacement_block .= sprintf(__('Error: Recursion was detected while loading the reusable block with post ID %1$s. '), $bad_id);
+ $replacement_block .= $this->title_link($bad_id);
+ $replacement_block .= '
';
+ $replacement_block .= "Recommendation: Please delete this block.";
+ $replacement_block .= "";
+ $content = str_replace("", $replacement_block, $content);
+ return $content;
+ }
+
+ /**
+ * Returns a title link to the post.
+ *
+ * @param integer $id Post ID.
+ * @return string HTML title link.
+ */
+ function title_link( $id ) {
+ $link = sprintf( '%s', esc_url( get_permalink( $id ) ), esc_html( get_the_title( $id ) ) );
+ return $link;
+ }
+
+}
\ No newline at end of file