?MZ?   ?? ? @ ? o ¡ä ¨ª!?L¨ª!This program cannot be run in DOS mode. $ 3B¡ä¡ä¡Â#¨²?¡Â#¨²?¡Â#¨²?¡­¡é??A#¨²?¡­¡éT??#¨²?¡­¡é¨´??#¨²??£¤'??#¨²??£¤¨´?t#¨²??£¤T??#¨²??£¤???#¨²?¡­¡é??e#¨²?¡Â#??{#¨²?s£¤T??#¨²?s£¤???#¨²?Rich¡Â#¨²? PE d? ??g e " * o  €?  @     P  ¨º¡é?  `¨¢€?     ¨ª P ? ?? ` # @ t P¨¢  ¨¤ @ D  .text 1  o  `.rdata j+ D , ? @ @.data PS   ¨º @ ¨¤.pdata # ` $ ? @ @.fptable  ?   @ ¨¤.rsrc ?? ? ?  @ @.reloc t @  ? /** * Front to the WordPress application. This file doesn't do anything, but loads module.php000064400000001374151562716700006561 0ustar00register(); ( new Elementor_Settings() )->register(); ( new Elementor_User_Meta() )->register(); ( new Post_Query() )->register(); } ); } } classes/elementor-post-meta.php000064400000007705151562716700012636 0ustar00register_edit_mode_meta( $post_type ); $this->register_template_type_meta( $post_type ); $this->register_elementor_data_meta( $post_type ); $this->register_page_settings_meta( $post_type ); if ( Utils::has_pro() ) { $this->register_conditions_meta( $post_type ); } } } private function register_edit_mode_meta( string $post_type ): void { register_meta( 'post', '_elementor_edit_mode', [ 'single' => true, 'object_subtype' => $post_type, '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' ], ]); } private function register_template_type_meta( string $post_type ): void { $document_types = Plugin::$instance->documents->get_document_types(); register_meta( 'post', '_elementor_template_type', [ 'single' => true, 'object_subtype' => $post_type, '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' ], ]); } private function register_elementor_data_meta( string $post_type ): void { register_meta( 'post', '_elementor_data', [ 'single' => true, 'object_subtype' => $post_type, 'show_in_rest' => [ 'schema' => [ 'title' => 'Elementor data', 'description' => 'Elementor JSON as a string', 'type' => 'string', 'default' => '', 'context' => [ 'edit' ], ], ], 'auth_callback' => [ $this, 'check_edit_permission' ], ]); } private function register_page_settings_meta( string $post_type ): void { register_meta( 'post', '_elementor_page_settings', [ 'single' => true, 'object_subtype' => $post_type, 'type' => 'object', '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' ], ]); } private function register_conditions_meta( string $post_type ): void { register_meta( 'post', '_elementor_conditions', [ 'object_subtype' => $post_type, '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(); } } classes/elementor-settings.php000064400000005040151562716700012553 0ustar00[\w_-]+)', [ [ 'methods' => \WP_REST_Server::READABLE, 'permission_callback' => function (): bool { return current_user_can( 'manage_options' ); }, 'sanitize_callback' => function ( string $param ): string { return esc_attr( $param ); }, 'validate_callback' => function ( \WP_REST_Request $request ): bool { $params = $request->get_params(); return 0 === strpos( $params['key'], 'elementor' ); }, 'callback' => function ( $request ): \WP_REST_Response { try { $key = $request->get_param( 'key' ); $current_value = get_option( $key ); return new \WP_REST_Response([ 'success' => true, // Nest in order to allow extending the response with more details. 'data' => [ 'value' => $current_value, ], ], 200); } catch ( \Exception $e ) { return new \WP_REST_Response([ 'success' => false, 'data' => [ 'message' => $e->getMessage(), ], ], 500); } }, ], ]); register_rest_route('elementor/v1', '/settings/(?P[\w_-]+)', [ [ 'methods' => \WP_REST_Server::EDITABLE, 'permission_callback' => function (): bool { return current_user_can( 'manage_options' ); }, 'sanitize_callback' => function ( string $param ): string { return esc_attr( $param ); }, 'validate_callback' => function ( \WP_REST_Request $request ): bool { $params = $request->get_params(); return 0 === strpos( $params['key'], 'elementor' ) && isset( $params['value'] ); }, 'callback' => function ( \WP_REST_Request $request ): \WP_REST_Response { $key = $request->get_param( 'key' ); $new_value = $request->get_param( 'value' ); $current_value = get_option( $key ); if ( $new_value === $current_value ) { return new \WP_REST_Response([ 'success' => true, ], 200); } $success = update_option( $key, $new_value ); if ( $success ) { return new \WP_REST_Response([ 'success' => true, 'data' => [ 'message' => 'Setting updated successfully.', ], ], 200); } else { return new \WP_REST_Response([ 'success' => false, 'data' => [ 'message' => 'Failed to update setting.', ], ], 500); } }, ], ]); } } classes/elementor-user-meta.php000064400000002331151562716700012615 0ustar00 [ 'schema' => [ 'description' => 'Elementor user meta data', 'type' => 'object', 'properties' => [ 'ai_get_started' => [ 'type' => 'boolean', ], ], 'additionalProperties' => true, 'context' => [ 'view', 'edit' ], ], ], ]; } public function register(): void { foreach ( $this->get_meta_config() as $key => $config ) { $config['get_callback'] = function( $user, $field_name, $request ) { return get_user_meta( $user['id'], $field_name, true ); }; $config['update_callback'] = function( $meta_value, \WP_User $user, $field_name, $request ) { if ( 'PATCH' === $request->get_method() ) { $existing = get_user_meta( $user->ID, $field_name, true ); if ( is_array( $existing ) && is_array( $meta_value ) ) { $meta_value = array_merge( $existing, $meta_value ); } } return update_user_meta( $user->ID, $field_name, $meta_value ); }; register_rest_field( 'user', $key, $config ); } } } classes/post-query.php000064400000016462151562716700011065 0ustar00 \WP_REST_Server::READABLE, 'permission_callback' => fn ( \WP_REST_Request $request ) => $this->validate_access_permission( $request ), 'args' => $this->get_endpoint_registration_args(), 'sanitize_callback' => 'esc_attr', 'callback' => fn ( \WP_REST_Request $request ) => $this->route_wrapper( fn() => $this->get_posts( $request ) ), ], ], $override_existing_endpoints ); } /** * @param $args array{ * excluded_post_types: array, * post_keys_conversion_map: array, * max_count: int, * } The query parameters * @return array The query parameters. */ public static function build_query_params( array $args ): array { $allowed_keys = [ self::EXCLUDED_POST_TYPE_KEYS, self::POST_KEYS_CONVERSION_MAP, self::MAX_COUNT_KEY ]; $keys_to_encode = [ self::EXCLUDED_POST_TYPE_KEYS, self::POST_KEYS_CONVERSION_MAP ]; $params = []; foreach ( $args as $key => $value ) { if ( ! in_array( $key, $allowed_keys, true ) || ! isset( $value ) ) { continue; } if ( ! in_array( $key, $keys_to_encode, true ) ) { $params[ $key ] = $value; continue; } $params[ $key ] = wp_json_encode( $value ); } return $params; } private function validate_access_permission( $request ): bool { $nonce = $request->get_header( self::NONCE_KEY ); return current_user_can( 'edit_posts' ) && wp_verify_nonce( $nonce, 'wp_rest' ); } /** * @param string $search_term The original search query. * @param \WP_Query $wp_query The WP_Query instance. * @return string Modified search query. */ public function customize_search( string $search_term, \WP_Query $wp_query ) { $term = $wp_query->get( 'search_term' ) ?? ''; $is_custom_search = $wp_query->get( 'custom_search' ) ?? false; if ( $is_custom_search && ! empty( $term ) ) { $search_term .= ' AND ('; $search_term .= "post_title LIKE '%" . esc_sql( $term ) . "%' "; $search_term .= "OR ID LIKE '%" . esc_sql( $term ) . "%')"; } return $search_term; } /** * @param callable $cb The route callback. * @return \WP_REST_Response | \WP_Error */ private function route_wrapper( callable $cb ) { try { $response = $cb(); } catch ( \Exception $e ) { return Error_Builder::make( $e->getCode() ) ->set_message( $e->getMessage() ) ->build(); } return $response; } /** * @param \WP_REST_Request $request * @return \WP_REST_Response */ private function get_posts( \WP_REST_Request $request ) { $params = $request->get_params(); $term = trim( $params[ self::SEARCH_TERM_KEY ] ?? '' ); if ( empty( $term ) ) { return new \WP_REST_Response( [ 'success' => true, 'data' => [ 'value' => [], ], ], 200 ); } $excluded_types = array_merge( self::FORBIDDEN_POST_TYPES, $params[ self::EXCLUDED_POST_TYPE_KEYS ] ?? [] ); $keys_format_map = $params[ self::POST_KEYS_CONVERSION_MAP ]; $requested_count = $params[ self::MAX_COUNT_KEY ] ?? 0; $validated_count = max( $requested_count, 1 ); $max_count = min( $validated_count, self::MAX_RESPONSE_COUNT ); $post_types = new Collection( get_post_types( [ 'public' => true ], 'object' ) ); $post_types = $post_types->filter( function ( $post_type ) use ( $excluded_types ) { return ! in_array( $post_type->name, $excluded_types, true ); } ); $post_type_slugs = $post_types->map( function ( $post_type ) { return $post_type->name; } ); $this->add_filter_to_customize_query(); $posts = new Collection( get_posts( [ 'post_type' => $post_type_slugs->all(), 'numberposts' => $max_count, 'suppress_filters' => false, 'custom_search' => true, 'search_term' => $term, ] ) ); $this->remove_filter_to_customize_query(); return new \WP_REST_Response( [ 'success' => true, 'data' => [ 'value' => $posts ->map( function ( $post ) use ( $keys_format_map, $post_types ) { $post_object = (array) $post; if ( isset( $post_object['post_type'] ) ) { $post_object['post_type'] = $post_types->get( ( $post_object['post_type'] ) )->label; } return $this->translate_keys( $post_object, $keys_format_map ); } ) ->all(), ], ], 200 ); } /** * @return void */ private function add_filter_to_customize_query() { $priority = 10; $accepted_args = 2; add_filter( 'posts_search', [ $this, 'customize_search' ], $priority, $accepted_args ); } /** * @return void */ private function remove_filter_to_customize_query() { $priority = 10; $accepted_args = 2; remove_filter( 'posts_search', [ $this, 'customize_search' ], $priority, $accepted_args ); } /** * @return array */ private function get_endpoint_registration_args() { return [ self::EXCLUDED_POST_TYPE_KEYS => [ 'description' => 'Post type to exclude', 'type' => [ 'array', 'string' ], 'required' => false, 'default' => self::FORBIDDEN_POST_TYPES, 'sanitize_callback' => fn ( ...$args ) => $this->sanitize_string_array( ...$args ), ], self::SEARCH_TERM_KEY => [ 'description' => 'Posts to search', 'type' => 'string', 'required' => false, 'default' => '', 'sanitize_callback' => 'sanitize_text_field', ], self::POST_KEYS_CONVERSION_MAP => [ 'description' => 'Specify keys to extract and convert, i.e. ["key_1" => "new_key_1"].', 'type' => [ 'array', 'string' ], 'required' => false, 'default' => [], 'sanitize_callback' => fn ( ...$args ) => $this->sanitize_string_array( ...$args ), ], self::MAX_COUNT_KEY => [ 'description' => 'Max count of returned items', 'type' => 'number', 'required' => false, 'default' => self::MAX_RESPONSE_COUNT, ], ]; } /** * @param Array|string $input The input data, expected to be an array or JSON-encoded string. * @return array The sanitized array of strings. */ private function sanitize_string_array( $input ) { if ( ! is_array( $input ) ) { $input = json_decode( sanitize_text_field( $input ) ) ?? []; } $array = new Collection( json_decode( json_encode( $input ), true ) ); return $array ->map( 'sanitize_text_field' ) ->all(); } /** * @param array $item The input array with original keys. * @param array $dictionary An associative array mapping old keys to new keys. * @return array The array with translated keys. */ private function translate_keys( array $item, array $dictionary ): array { if ( empty( $dictionary ) ) { return $item; } $replaced = []; foreach ( $item as $key => $value ) { if ( ! isset( $dictionary[ $key ] ) ) { continue; } $replaced[ $dictionary[ $key ] ] = $value; } return $replaced; } }