Skip to content

Commit

Permalink
Revert "Fix: REST API implementation prevents saving different post t…
Browse files Browse the repository at this point in the history
…ypes via the Block Editor [ED-17886] (elementor#30005)"

This reverts commit 8cd6a6e.
  • Loading branch information
matipojo committed Jan 26, 2025
1 parent c28d164 commit 49b02e7
Show file tree
Hide file tree
Showing 4 changed files with 253 additions and 0 deletions.
121 changes: 121 additions & 0 deletions modules/wp-rest/classes/elementor-post-meta.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
<?php

namespace Elementor\Modules\WpRest\Classes;

use Elementor\Plugin;
use Elementor\Utils;

if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}

class Elementor_Post_Meta {

public function register(): void {
$post_types = get_post_types_by_support( 'elementor' );

foreach ( $post_types as $post_type ) {
register_meta( $post_type, '_elementor_edit_mode', [
'single' => true,
'show_in_rest' => [
'schema' => [
'title' => 'Elementor edit mode',
'description' => 'Elementor edit mode, `builder` is required for Elementor editing',
'type' => 'string',
'enum' => [ '', 'builder' ],
'default' => '',
'context' => [ 'edit' ],
],
],
'auth_callback' => [ $this, 'check_edit_permission' ],
]);

$document_types = Plugin::$instance->documents->get_document_types();

register_meta( $post_type, '_elementor_template_type', [
'single' => true,
'show_in_rest' => [
'schema' => [
'title' => 'Elementor template type',
'description' => 'Elementor document type',
'type' => 'string',
'enum' => array_merge( array_keys( $document_types ), [ '' ] ),
'default' => '',
'context' => [ 'edit' ],
],
],
'auth_callback' => [ $this, 'check_edit_permission' ],
]);

register_meta( $post_type, '_elementor_data', [
'single' => true,
'show_in_rest' => [
'schema' => [
'title' => 'Elementor data',
'description' => 'Elementor JSON as a string',
'type' => 'string',
'default' => '',
'context' => [ 'edit' ],
],
],
'auth_callback' => [ $this, 'check_edit_permission' ],
]);

register_meta( $post_type, '_elementor_page_settings', [
'single' => true,
'show_in_rest' => [
'schema' => [
'title' => 'Elementor page settings',
'description' => 'Elementor page level settings',
'type' => 'object',
'properties' => [
'hide_title' => [
'type' => 'string',
'enum' => [ 'yes', 'no' ],
'default' => '',
],
],
'default' => '{}',
'additionalProperties' => true,
'context' => [ 'edit' ],
],
],
'auth_callback' => [ $this, 'check_edit_permission' ],
]);

if ( Utils::has_pro() ) {
register_meta( $post_type, '_elementor_conditions', [
'type' => 'object',
'title' => 'Elementor conditions',
'description' => 'Elementor conditions',
'single' => true,
'show_in_rest' => [
'schema' => [
'description' => 'Elementor conditions',
'type' => 'array',
'additionalProperties' => true,
'default' => [],
'context' => [ 'edit' ],
],
],
'auth_callback' => [ $this, 'check_edit_permission' ],
]);
}
}
}

/**
* Check if current user has permission to edit the specific post with elementor
*
* @param bool $allowed Whether the user can add the post meta. Default false.
* @param string $meta_key The meta key.
* @param int $post_id Post ID.
* @return bool
* @since 3.27.0
*/
public function check_edit_permission( bool $allowed, string $meta_key, int $post_id ): bool {
$document = Plugin::$instance->documents->get( $post_id );

return $document && $document->is_editable_by_current_user();
}
}
2 changes: 2 additions & 0 deletions modules/wp-rest/module.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
namespace Elementor\Modules\WpRest;

use Elementor\Core\Base\Module as BaseModule;
use Elementor\Modules\WpRest\Classes\Elementor_Post_Meta;
use Elementor\Modules\WpRest\Classes\Elementor_Settings;
use Elementor\Modules\WpRest\Classes\Elementor_User_Meta;

Expand All @@ -19,6 +20,7 @@ public function get_name() {
public function __construct() {
parent::__construct();
add_action( 'rest_api_init', function () {
( new Elementor_Post_Meta() )->register();
( new Elementor_Settings() )->register();
( new Elementor_User_Meta() )->register();
} );
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -256,6 +256,44 @@ public function test_cpt_rest_is_accessible_for_admin() {
$this->assertIsArray( $response->get_data() );
}

public function test_admin_can_save_template_via_wp_rest() {
// Arrange
do_action( 'rest_api_init' );
wp_set_current_user( $this->factory()->get_administrator_user()->ID );

$template_data = [
'title' => 'Test Template',
'status' => 'publish',
'meta' => [
'_elementor_template_type' => 'container',
'_elementor_edit_mode' => 'builder',
'_elementor_data' => wp_json_encode([
[
'id' => 'test-section',
'elType' => 'section',
'settings' => [],
'elements' => [],
'isInner' => false
]
])
]
];

$request = new \WP_REST_Request( 'POST', '/wp/v2/elementor_library' );
$request->set_body_params( $template_data );

// Act
$response = rest_do_request( $request );
$result = $response->get_data();

// Assert
$this->assertEquals( 201, $response->get_status() );
$this->assertArrayHasKey( 'id', $result );
$this->assertEquals( 'Test Template', $result['title']['rendered'] );
$this->assertEquals( 'container', get_post_meta( $result['id'], '_elementor_template_type', true ) );
$this->assertNotEmpty( get_post_meta( $result['id'], '_elementor_data', true ) );
}

/**
* The data managers are killing the rest server (@see `kill_server`), and removing the post type rest routes.
* This is a workaround to re-register the post type rest routes.
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
<?php

namespace Elementor\Testing\Modules\WpRest;

use Elementor\Modules\WpRest\Classes\Elementor_Post_Meta;
use Elementor\Plugin;
use ElementorEditorTesting\Elementor_Test_Base;

if ( ! defined( 'ABSPATH' ) ) {
exit; // Exit if accessed directly.
}

class Test_Elementor_Post_Meta extends Elementor_Test_Base {
protected Elementor_Post_Meta $post_meta;

protected int $post_id;

public function setUp(): void {
parent::setUp();

$this->post_meta = new Elementor_Post_Meta();
$this->post_id = $this->factory()->create_and_get_default_post()->ID;

$document = Plugin::$instance->documents->get( $this->post_id );
$document->set_is_built_with_elementor( true );

do_action( 'rest_api_init' );
}

public function test_register() {
// Arrange
$this->post_meta->register();

// Act
$request = new \WP_REST_Request( 'OPTIONS', '/wp/v2/posts' );
$response = rest_get_server()->dispatch( $request );
$data = $response->get_data();
$meta_schema = $data['schema']['properties']['meta']['properties'];

// Assert
$this->assertArrayHasKey( '_elementor_edit_mode', $meta_schema );
$this->assertArrayHasKey( '_elementor_template_type', $meta_schema );
$this->assertArrayHasKey( '_elementor_data', $meta_schema );
$this->assertArrayHasKey( '_elementor_page_settings', $meta_schema );
}

public function test_check_edit_permission_with_valid_user() {
// Arrange
$this->act_as_admin();

// Act
$has_permission = $this->post_meta->check_edit_permission( true, '_elementor_edit_mode', $this->post_id );

// Assert
$this->assertTrue( $has_permission );
}

public function test_check_edit_permission_with_invalid_user() {
// Arrange
$this->act_as_subscriber();

// Act
$has_permission = $this->post_meta->check_edit_permission( true, '_elementor_edit_mode', $this->post_id );

// Assert
$this->assertFalse( $has_permission );
}

public function test_check_edit_permission_with_non_elementor_post() {
// Arrange
$this->act_as_admin();
$non_elementor_post_id = $this->factory()->post->create();

// Act
$has_permission = $this->post_meta->check_edit_permission( true, '_elementor_edit_mode', $non_elementor_post_id );

// Assert
$this->assertTrue( $has_permission );
}

public function test_check_edit_permission_with_elementor_post_and_excluded_user_roles() {
// Arrange
$this->act_as_admin();
update_option( 'elementor_exclude_user_roles', [ 'administrator' ] );

// Act
$has_permission = $this->post_meta->check_edit_permission( true, '_elementor_edit_mode', $this->post_id );

// Assert
$this->assertFalse( $has_permission );
}
}

0 comments on commit 49b02e7

Please sign in to comment.