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

Lock blocks from the back-end to prevent unwanted edits #127

Open
zaguiini opened this issue Sep 5, 2024 · 3 comments
Open

Lock blocks from the back-end to prevent unwanted edits #127

zaguiini opened this issue Sep 5, 2024 · 3 comments
Assignees
Labels
enhancement New feature or request

Comments

@zaguiini
Copy link
Contributor

zaguiini commented Sep 5, 2024

During our prototype we've added a content locking mechanism to prevent the users from modifying the template when entering data.

We're doing it from the front-end, which creates unwanted edits and prevents the user from leaving the screen if there are no changes to the post.

Let's do it from the back-end to prevent these edits. After we move, we can safely delete the useContentLocking hook and references to it.

Proposed implementation

Fill in the TODO: lock blocks here. part.

diff --git a/includes/runtime/class-content-model-block.php b/includes/runtime/class-content-model-block.php
index 7511bb4..e159127 100644
--- a/includes/runtime/class-content-model-block.php
+++ b/includes/runtime/class-content-model-block.php
@@ -217,7 +217,7 @@ final class Content_Model_Block {
 		remove_filter( 'pre_render_block', array( $this, 'render_group_variation' ), 99 );
 
 		// Accessing index zero because we've passed an array with one element above.
-		$result = render_block( $hydrator->hydrate()[0] );
+		$result = render_block( $hydrator->hydrate_groups()[0] );
 
 		add_filter( 'pre_render_block', array( $this, 'render_group_variation' ), 99, 2 );
 
diff --git a/includes/runtime/class-content-model-data-hydrator.php b/includes/runtime/class-content-model-data-hydrator.php
index 0b6dfdd..57fcf92 100644
--- a/includes/runtime/class-content-model-data-hydrator.php
+++ b/includes/runtime/class-content-model-data-hydrator.php
@@ -43,7 +43,7 @@ class Content_Model_Data_Hydrator {
 	 *
 	 * @return array The template blocks, filled with data.
 	 */
-	public function hydrate() {
+	public function hydrate_groups() {
 		return content_model_block_walker(
 			$this->blocks,
 			array( $this, 'hydrate_block' )
diff --git a/includes/runtime/class-content-model.php b/includes/runtime/class-content-model.php
index c66d75b..c38e177 100644
--- a/includes/runtime/class-content-model.php
+++ b/includes/runtime/class-content-model.php
@@ -97,7 +97,7 @@ final class Content_Model {
 		 *
 		 * The Editor reads the whole post, while the front-end reads only the post content.
 		 */
-		add_action( 'the_post', array( $this, 'hydrate_bound_groups' ) );
+		add_action( 'the_post', array( $this, 'inject_and_hydrate_template' ) );
 		add_filter( 'the_content', array( $this, 'swap_post_content_with_hydrated_template' ) );
 
 		add_filter( 'get_post_metadata', array( $this, 'cast_meta_field_types' ), 10, 3 );
@@ -483,41 +483,38 @@ final class Content_Model {
 	}
 
 	/**
-	 * In the editor, display the template and fill bound Groups with data.
+	 * Hydrate the template with data.
 	 * Blocks using the supported Bindings API attributes will be filled automatically.
 	 *
 	 * @param WP_Post $post The current post.
 	 */
-	public function hydrate_bound_groups( $post ) {
+	public function inject_and_hydrate_template( $post ) {
 		if ( $this->slug !== $post->post_type ) {
 			return;
 		}
 
 		$editor_blocks = $this->template;
-		$editor_blocks = ( new Content_Model_Data_Hydrator( $editor_blocks, false ) )->hydrate();
-		$editor_blocks = content_model_block_walker( $editor_blocks, array( $this, 'add_fallback_value_placeholder' ) );
 
-		$post->post_content = serialize_blocks( $editor_blocks );
-	}
+		$editor_blocks = ( new Content_Model_Data_Hydrator( $editor_blocks, false ) )->hydrate_groups();
 
-	/**
-	 * If a block has bindings modify the placeholder text.
-	 *
-	 * @param array $block The original block.
-	 *
-	 * @return array The modified block.
-	 */
-	public function add_fallback_value_placeholder( $block ) {
-		$tentative_block = new Content_Model_Block( $block );
+		$editor_blocks = content_model_block_walker(
+			$editor_blocks,
+			function ( $block ) {
+				$tentative_block = new Content_Model_Block( $block );
 
-		if ( ! empty( $tentative_block->get_bindings() ) ) {
-			// translators: %s is the block variation name.
-			$block['attrs']['placeholder'] = sprintf( __( 'Enter a value for %s' ), $tentative_block->get_block_variation_name() );
+				// If a block has bindings modify the placeholder text.
+				if ( ! empty( $tentative_block->get_bindings() ) ) {
+					// translators: %s is the block variation name.
+					$block['attrs']['placeholder'] = sprintf( __( 'Enter a value for %s' ), $tentative_block->get_block_variation_name() );
+				}
 
-			return $block;
-		}
+				// TODO: lock blocks here.
 
-		return $block;
+				return $block;
+			}
+		);
+
+		$post->post_content = serialize_blocks( $editor_blocks );
 	}
 
 	/**
@zaguiini zaguiini added the enhancement New feature or request label Sep 5, 2024
@bacoords
Copy link
Collaborator

bacoords commented Sep 5, 2024

I'm not sure this is feasible. Currently we're using setBlockEditingMode which is something that changes the state in the block editor, but not an actual attribute on the block that we can pass server-side (as far as I'm aware). Might need to be addressed upstream in GB?

@zaguiini
Copy link
Contributor Author

zaguiini commented Sep 6, 2024

Isn't it the same as setting contentOnly as a block attribute, @bacoords?

@bacoords
Copy link
Collaborator

No it's more of an editor state, but they're reworking it now. This comment gives a lot of context of where it's going: WordPress/gutenberg#60021 (comment)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

2 participants