forked from elementor/elementor
-
Notifications
You must be signed in to change notification settings - Fork 1
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Internal: REST API for Elementor post meta, user meta and settings
- Loading branch information
Showing
9 changed files
with
532 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
<?php | ||
|
||
namespace Elementor\Modules\Ai\SitePlannerConnect; | ||
|
||
defined( 'ABSPATH' ) || exit; | ||
|
||
class Module { | ||
|
||
public function __construct() { | ||
add_action( 'rest_api_init', [ $this, 'on_rest_init' ] ); | ||
add_action( 'admin_menu', [ $this, 'register_menu_page' ], 100 ); | ||
add_filter('rest_prepare_application_password', function ( $response, $item, $request ) { | ||
if ( $request->get_route() === '/wp/v2/users/me/application-passwords' && is_user_logged_in() ) { | ||
$user = wp_get_current_user(); | ||
$response->data['user_login'] = $user->user_login; | ||
} | ||
return $response; | ||
}, 10, 3); | ||
} | ||
|
||
public function on_rest_init(): void { | ||
( new WpRestApi() )->register(); | ||
} | ||
|
||
public function register_menu_page() { | ||
add_submenu_page( | ||
null, // Hidden page | ||
'App Password Generator', | ||
'App Password', | ||
'manage_options', | ||
'site-planner-password-generator', | ||
[ $this, 'render_menu_page' ] | ||
); | ||
} | ||
|
||
public function render_menu_page() { | ||
$root_url = 'https://planner.elementor.com'; | ||
$root_url = 'http://localhost:4000'; | ||
|
||
ob_start(); | ||
require_once __DIR__ . '/view.php'; | ||
$content = ob_get_clean(); | ||
$vars = [ | ||
'%root_url%' => $root_url, | ||
'%domain%' => isset( $_SERVER['HTTP_HOST'] ) ? sanitize_key( $_SERVER['HTTP_HOST'] ) : '', | ||
]; | ||
|
||
// phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped | ||
echo strtr( $content, $vars ); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,170 @@ | ||
<?php | ||
|
||
namespace Elementor\Modules\Ai\SitePlannerConnect; | ||
|
||
defined( 'ABSPATH' ) || exit; | ||
?> | ||
<link rel="preconnect" href="https://fonts.googleapis.com"> | ||
<link rel="preconnect" href="https://fonts.gstatic.com" crossorigin> | ||
<link | ||
href="https://fonts.googleapis.com/css2?family=Roboto:ital,wght@0,100;0,300;0,400;0,500;0,700;0,900;1,100;1,300;1,400;1,500;1,700;1,900&family=Source+Serif+4:ital,opsz,wght@0,8..60,200..900;1,8..60,200..900&display=swap" | ||
rel="stylesheet"> | ||
<style> | ||
#wpwrap { | ||
display: none; | ||
} | ||
|
||
.site-planner-consent { | ||
position: fixed; | ||
top: 0; | ||
left: 0; | ||
z-index: 99999; /* above admin top bar */ | ||
width: 100%; | ||
background-color: #fff; | ||
display: flex; | ||
flex-direction: column; | ||
align-items: center; | ||
justify-content: center; | ||
height: 100vh; | ||
} | ||
|
||
.site-planner-consent-title { | ||
color: #0C0D0E; | ||
text-align: center; | ||
/* typography/h4 */ | ||
font-family: Roboto, sans-serif; | ||
font-size: 32px; | ||
font-style: normal; | ||
font-weight: 700; | ||
line-height: 123.5%; | ||
letter-spacing: 0.25px; | ||
} | ||
|
||
.site-planner-consent-description { | ||
width: 393px; | ||
color: #69727D; | ||
text-align: center; | ||
/* typography/body1 */ | ||
font-family: Roboto, sans-serif; | ||
font-size: 16px; | ||
font-style: normal; | ||
font-weight: 400; | ||
line-height: 150%; /* 24px */ | ||
letter-spacing: 0.15px; | ||
} | ||
|
||
.site-planner-consent-connect-names { | ||
display: flex; | ||
flex-direction: row; | ||
justify-content: space-between; | ||
width: 500px; | ||
} | ||
|
||
.site-planner-consent-connect-names div { | ||
width: 50%; | ||
text-align: center; | ||
} | ||
|
||
.site-planner-consent button { | ||
cursor: pointer; | ||
border: none; | ||
display: flex; | ||
width: 387px; | ||
padding: 8px 22px; | ||
flex-direction: column; | ||
justify-content: center; | ||
align-items: center; | ||
border-radius: 4px; | ||
background: #F0ABFC; | ||
color: #0C0D0E; | ||
font-feature-settings: 'liga' off, 'clig' off; | ||
|
||
/* components/button/button-large */ | ||
font-family: Roboto, sans-serif; | ||
font-size: 16px; | ||
font-style: normal; | ||
font-weight: 500; | ||
line-height: 26px; /* 162.5% */ | ||
letter-spacing: 0.46px; | ||
} | ||
</style> | ||
<div class="site-planner-consent"> | ||
<h1 class="site-planner-consent-title">Connect to Site Planner</h1> | ||
<div style="height: 20px"></div> | ||
<p class="site-planner-consent-description">To connect to Site Planner, you need to generate an application | ||
password.</p> | ||
<div style="height: 40px"></div> | ||
<svg width="287" height="40" viewBox="0 0 287 40" fill="none" xmlns="http://www.w3.org/2000/svg"> | ||
<line x1="16.5" y1="22.5" x2="271.5" y2="22.5" stroke="#69727D" stroke-linecap="round" stroke-linejoin="round" | ||
stroke-dasharray="2 4"/> | ||
<circle cx="145.623" cy="22" r="11.5" fill="white" stroke="#69727D"/> | ||
<path fill-rule="evenodd" clip-rule="evenodd" | ||
d="M147.977 19.6467C148.172 19.842 148.172 20.1586 147.977 20.3538L143.977 24.3538C143.782 24.5491 143.465 24.5491 143.27 24.3538C143.074 24.1586 143.074 23.842 143.27 23.6467L147.27 19.6467C147.465 19.4515 147.782 19.4515 147.977 19.6467Z" | ||
fill="#69727D"/> | ||
<path | ||
d="M149.691 18.1948L149.402 17.9058C148.377 16.8804 146.714 16.8804 145.689 17.9058L145.002 18.5922C144.807 18.7875 144.491 18.7875 144.295 18.5922C144.1 18.397 144.1 18.0804 144.295 17.8851L144.982 17.1987C146.398 15.7827 148.693 15.7827 150.109 17.1987L150.398 17.4877C151.814 18.9036 151.814 21.1993 150.398 22.6153L149.712 23.3017C149.517 23.497 149.2 23.497 149.005 23.3017C148.81 23.1065 148.81 22.7899 149.005 22.5946L149.691 21.9082C150.717 20.8828 150.717 19.2202 149.691 18.1948Z" | ||
fill="#69727D"/> | ||
<path | ||
d="M141.529 22.0658C140.503 23.0912 140.503 24.7538 141.529 25.7792L141.818 26.0682C142.843 27.0936 144.506 27.0936 145.531 26.0682L146.218 25.3818C146.413 25.1865 146.73 25.1865 146.925 25.3818C147.12 25.577 147.12 25.8936 146.925 26.0889L146.238 26.7753C144.822 28.1913 142.527 28.1913 141.111 26.7753L140.822 26.4863C139.406 25.0704 139.406 22.7747 140.822 21.3587L141.508 20.6723C141.703 20.477 142.02 20.477 142.215 20.6723C142.411 20.8675 142.411 21.1841 142.215 21.3794L141.529 22.0658Z" | ||
fill="#69727D"/> | ||
<rect x="247" width="40" height="40" rx="20" fill="#F3F3F4"/> | ||
<g clip-path="url(#clip0_7635_41076)"> | ||
<path fill-rule="evenodd" clip-rule="evenodd" | ||
d="M257.022 26.6668C255.704 24.6934 255 22.3734 255 20C255 16.8174 256.264 13.7652 258.515 11.5147C260.765 9.26428 263.817 8 267 8C269.373 8 271.693 8.70379 273.667 10.0224C275.64 11.3409 277.178 13.2151 278.087 15.4078C278.995 17.6005 279.232 20.0133 278.769 22.3411C278.306 24.6688 277.164 26.807 275.485 28.4853C273.807 30.1635 271.669 31.3064 269.341 31.7694C267.013 32.2324 264.601 31.9948 262.408 31.0865C260.215 30.1783 258.341 28.6402 257.022 26.6668ZM264 14.9996H262.001V24.9999H264V14.9996ZM271.999 14.9996H266V16.9993H271.999V14.9996ZM271.999 18.999H266V20.9987H271.999V18.999ZM271.999 23.0002H266V24.9999H271.999V23.0002Z" | ||
fill="#0C0D0E"/> | ||
</g> | ||
<rect width="40" height="40" rx="20" fill="#F3F3F4"/> | ||
<path fill-rule="evenodd" clip-rule="evenodd" | ||
d="M20.0004 10.0156C14.4944 10.0156 10.0156 14.494 10.0156 19.9996C10.0156 25.5053 14.4944 29.9844 20.0004 29.9844C25.5056 29.9844 29.9844 25.5053 29.9844 19.9996C29.9844 14.4947 25.5056 10.0156 20.0004 10.0156ZM11.1616 19.9996C11.1616 18.7184 11.4367 17.5017 11.927 16.4031L16.1431 27.9539C13.1948 26.5215 11.1616 23.4984 11.1616 19.9996ZM20.0004 28.8387C19.1327 28.8387 18.2954 28.7106 17.5032 28.4785L20.1549 20.7731L22.8725 28.2154C22.8898 28.2589 22.9115 28.2992 22.9353 28.3372C22.0167 28.6607 21.0292 28.8387 20.0004 28.8387ZM21.218 15.856C21.7501 15.8279 22.2293 15.7715 22.2293 15.7715C22.7058 15.7153 22.65 15.0158 22.1733 15.0438C22.1733 15.0438 20.7415 15.156 19.8176 15.156C18.9495 15.156 17.4894 15.0438 17.4894 15.0438C17.0133 15.0158 16.9579 15.744 17.4336 15.7715C17.4336 15.7715 17.8845 15.8277 18.3602 15.856L19.7373 19.6286L17.8034 25.4297L14.5851 15.8564C15.1178 15.8283 15.5968 15.7721 15.5968 15.7721C16.0725 15.7159 16.0169 15.016 15.54 15.0445C15.54 15.0445 14.1088 15.1564 13.1843 15.1564C13.0178 15.1564 12.823 15.1521 12.6157 15.1457C14.1954 12.7459 16.9123 11.1617 20.0004 11.1617C22.3018 11.1617 24.3964 12.0416 25.9689 13.4816C25.9302 13.4797 25.8937 13.4748 25.854 13.4748C24.9861 13.4748 24.3695 14.2309 24.3695 15.0434C24.3695 15.7715 24.789 16.388 25.2377 17.1159C25.5741 17.7051 25.9662 18.4613 25.9662 19.5537C25.9662 20.3102 25.6758 21.1882 25.2936 22.4107L24.4121 25.3566L21.218 15.856ZM24.4435 27.6389L27.1431 19.8337C27.6481 18.573 27.8152 17.5647 27.8152 16.6679C27.8152 16.343 27.7937 16.0404 27.7557 15.7591C28.4466 17.018 28.8391 18.4629 28.8386 19.9998C28.8386 23.2602 27.0708 26.1068 24.4435 27.6389Z" | ||
fill="#0C0D0E"/> | ||
<defs> | ||
<clipPath id="clip0_7635_41076"> | ||
<rect width="24" height="24" fill="white" transform="translate(255 8)"/> | ||
</clipPath> | ||
</defs> | ||
</svg> | ||
|
||
<div class="site-planner-consent-connect-names"> | ||
<div>%domain%</div> | ||
<div>Site Planner</div> | ||
</div> | ||
<div style="height: 40px"></div> | ||
|
||
<button class="site-planner-consent-button" onclick="sendPassword()"> | ||
Approve & Connect | ||
</button> | ||
</div> | ||
<script> | ||
// Move the consent dialog to the body | ||
document.body.append(document.querySelector(".site-planner-consent")) | ||
const rootUrl = "%root_url%"; | ||
const urlObject = new URL(rootUrl); | ||
const sendPassword = () => { | ||
fetch(wpApiSettings.root + "wp/v2/users/me/application-passwords", { | ||
method: "POST", | ||
headers: { | ||
"Content-Type": "application/json", | ||
"X-WP-Nonce": wpApiSettings.nonce, | ||
}, | ||
body: JSON.stringify({ | ||
name: "Site Planner Connect" | ||
}) | ||
}) | ||
.then(response => response.json()) | ||
.then(data => { | ||
window.opener.postMessage({ | ||
type: "app_password", | ||
details: { | ||
userLogin: data.user_login, | ||
appPassword: data.password, | ||
uuid: data.uuid, | ||
created: data.created | ||
} | ||
}, urlObject.origin); | ||
window.close(); | ||
}) | ||
.catch(error => { | ||
console.error("Error:", error); | ||
}); | ||
} | ||
</script> |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
<?php | ||
|
||
namespace Elementor\Modules\Ai\SitePlannerConnect; | ||
|
||
defined( 'ABSPATH' ) || exit; | ||
|
||
/** | ||
* Just a simple rest api to validate new Site Planner Connect feature is exist. | ||
*/ | ||
class WpRestApi { | ||
|
||
public function register(): void { | ||
register_rest_route('elementor-ai/v1', 'permissions', [ | ||
[ | ||
'methods' => \WP_REST_Server::READABLE, | ||
'permission_callback' => function () { | ||
return current_user_can( 'manage_options' ); | ||
}, | ||
'callback' => function ( $request ) { | ||
try { | ||
wp_send_json_success( [ | ||
'SitePlannerConnect' => true, | ||
] ); | ||
} catch ( \Exception $e ) { | ||
wp_send_json_error( [ | ||
'message' => $e->getMessage(), | ||
] ); | ||
} | ||
}, | ||
], | ||
] ); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,111 @@ | ||
<?php | ||
|
||
namespace Elementor\Modules\WpRest\Classes; | ||
|
||
use Elementor\Plugin; | ||
use Elementor\Utils; | ||
|
||
defined( 'ABSPATH' ) || exit; | ||
|
||
class ElementorPostMeta { | ||
|
||
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', [ | ||
'type' => 'string', | ||
'label' => 'Elementor edit mode', | ||
'description' => 'Elementor edit mode, `builder` is required for Elementor editing', | ||
'default' => 'builder', | ||
'single' => true, | ||
'show_in_rest' => true, | ||
'auth_callback' => [ $this, 'check_edit_permission' ], | ||
]); | ||
|
||
$document_types = Plugin::$instance->documents->get_document_types(); | ||
|
||
register_meta($post_type, '_elementor_template_type', [ | ||
'type' => 'string', | ||
'label' => 'Elementor template type', | ||
'single' => true, | ||
'show_in_rest' => [ | ||
'schema' => [ | ||
'description' => 'Elementor document type', | ||
'type' => 'string', | ||
'enum' => array_keys( $document_types ), | ||
'context' => [ 'view', 'edit' ], | ||
], | ||
], | ||
'auth_callback' => [ $this, 'check_edit_permission' ], | ||
]); | ||
|
||
register_meta($post_type, '_elementor_data', [ | ||
'single' => true, | ||
'show_in_rest' => [ | ||
'schema' => [ | ||
'description' => 'Elementor JSON as a string', | ||
'type' => 'string', | ||
'context' => [ 'view', 'edit' ], | ||
], | ||
], | ||
'auth_callback' => [ $this, 'check_edit_permission' ], | ||
]); | ||
|
||
register_meta($post_type, '_elementor_page_settings', [ | ||
'type' => 'object', | ||
'title' => 'Elementor page settings', | ||
'description' => 'Elementor page level settings', | ||
'single' => true, | ||
'show_in_rest' => [ | ||
'schema' => [ | ||
'description' => 'Elementor page level settings', | ||
'type' => 'object', | ||
'properties' => [ | ||
'hide_title' => [ | ||
'type' => 'string', | ||
'enum' => [ 'yes', 'no' ], | ||
], | ||
], | ||
'additionalProperties' => true, | ||
'context' => [ 'view', '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, | ||
'context' => [ 'view', '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_built_with_elementor() && $document->is_editable_by_current_user(); | ||
} | ||
} |
Oops, something went wrong.