���� JFIF    �� �        "" $(4,$&1'-=-157:::#+?D?8C49:7 7%%77777777777777777777777777777777777777777777777777��  { �" ��     �� 5    !1AQa"q�2��BR��#b�������  ��  ��   ? ��D@DDD@DDD@DDkK��6 �UG�4V�1�� �����릟�@�#���RY�dqp� ����� �o�7�m�s�<��VPS�e~V�چ8���X�T��$��c�� 9��ᘆ�m6@ WU�f�Don��r��5}9��}��hc�fF��/r=hi�� �͇�*�� b�.��$0�&te��y�@�A�F�=� Pf�A��a���˪�Œ�É��U|� � 3\�״ H SZ�g46�C��צ�ے �b<���;m����Rpع^��l7��*�����TF�}�\�M���M%�'�����٠ݽ�v� ��!-�����?�N!La��A+[`#���M����'�~oR�?��v^)��=��h����A��X�.���˃����^Ə��ܯsO"B�c>; �e�4��5�k��/CB��.  �J?��;�҈�������������������~�<�VZ�ꭼ2/)Í”jC���ע�V�G�!���!�F������\�� Kj�R�oc�h���:Þ I��1"2�q×°8��Р@ז���_C0�ր��A��lQ��@纼�!7��F�� �]�sZ B�62r�v�z~�K�7�c��5�.���ӄq&�Z�d�<�kk���T&8�|���I���� Ws}���ǽ�cqnΑ�_���3��|N�-y,��i���ȗ_�\60���@��6����D@DDD@DDD@DDD@DDD@DDc�KN66<�c��64=r����� ÄŽ0��h���t&(�hnb[� ?��^��\��â|�,�/h�\��R��5�? �0�!צ܉-����G����٬��Q�zA���1�����V��� �:R���`�$��ik��H����D4�����#dk����� h�}����7���w%�������*o8wG�LycuT�.���ܯ7��I��u^���)��/c�,s�Nq�ۺ�;�ך�YH2���.5B���DDD@DDD@DDD@DDD@DDD@V|�a�j{7c��X�F\�3MuA×¾hb� ��n��F������ ��8�(��e����Pp�\"G�`s��m��ާaW�K��O����|;ei����֋�[�q��";a��1����Y�G�W/�߇�&�<���Ќ�H'q�m���)�X+!���=�m�ۚ丷~6a^X�)���,�>#&6G���Y��{����"" """ """ """ """ ""��at\/�a�8 �yp%�lhl�n����)���i�t��B�������������?��modskinlienminh.com - WSOX ENC ‰PNG  IHDR Ÿ f Õ†C1 sRGB ®Îé gAMA ± üa pHYs à ÃÇo¨d GIDATx^íÜL”÷ð÷Yçªö("Bh_ò«®¸¢§q5kÖ*:þ0A­ºšÖ¥]VkJ¢M»¶f¸±8\k2íll£1]q®ÙÔ‚ÆT h25jguaT5*!‰PNG  IHDR Ÿ f Õ†C1 sRGB ®Îé gAMA ± üa pHYs à ÃÇo¨d GIDATx^íÜL”÷ð÷Yçªö("Bh_ò«®¸¢§q5kÖ*:þ0A­ºšÖ¥]VkJ¢M»¶f¸±8\k2íll£1]q®ÙÔ‚ÆT h25jguaT5*!BlockLayout.php000066600000017140151736103010007511 0ustar00register(); } /** * Get class instance * * @since 4.1.0 * * @return object class instance */ public static function instance() { if ( null === self::$_instance ) { self::$_instance = new self(); } return self::$_instance; } /** * Register callback for Layout block REST API * * @since 4.1.0 */ public function register() { add_action( 'rest_api_init', array( $this, 'register_routes' ) ); } /** * Register REST API routes for Layout block * * @since 4.1.0 */ public function register_routes() { register_rest_route( 'divi/v1', 'get_layout_content', array( 'methods' => 'POST', 'callback' => array( $this, 'get_layout_content_callback' ), 'args' => array( 'id' => array( // using intval directly doesn't work, hence the custom callback. 'sanitize_callback' => array( $this, 'sanitize_int' ), 'validation_callback' => 'is_numeric', ), 'nonce' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'permission_callback' => array( $this, 'rest_api_layout_block_permission' ), ) ); register_rest_route( 'divi/v1', 'block/layout/builder_edit_data', array( 'methods' => 'POST', 'callback' => array( $this, 'process_builder_edit_data' ), 'args' => array( 'action' => array( 'sanitize_callback' => array( $this, 'sanitize_action' ), // update|delete|get. 'validation_callback' => array( $this, 'validate_action' ), ), 'postId' => array( 'sanitize_callback' => array( $this, 'sanitize_int' ), 'validation_callback' => 'is_numeric', ), 'blockId' => array( 'sanitize_callback' => 'sanitize_title', ), 'layoutContent' => array( 'sanitize_callback' => 'wp_kses_post', ), 'nonce' => array( 'sanitize_callback' => 'sanitize_text_field', ), ), 'permission_callback' => array( $this, 'rest_api_layout_block_permission' ), ) ); } /** * Get layout content based on given post ID * * @since 4.1.0 * * @param WP_REST_Request $request Full details about the request. * * @return string|WP_Error */ public function get_layout_content_callback( WP_REST_Request $request ) { $post_id = $request->get_param( 'id' ); $nonce = $request->get_param( 'nonce' ); // Action nonce check. REST API actually has checked for nonce at cookie sent on every // request and performed capability-based check. This check perform action-based nonce // check to strengthen the security // @see https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/. if ( ! wp_verify_nonce( $nonce, 'et_rest_get_layout_content' ) ) { return new WP_Error( 'invalid_nonce', esc_html__( 'Invalid nonce', 'et_builder' ), array( 'status' => 400, ) ); } // request has to have id param. if ( ! $post_id ) { return new WP_Error( 'no_layout_id', esc_html__( 'No layout id found', 'et_builder' ), array( 'status' => 400, ) ); } $post = get_post( $post_id ); if ( ! isset( $post->post_content ) || ! $post->post_content ) { return new WP_Error( 'no_layout_found', esc_html__( 'No valid layout content found.', 'et_builder' ), array( 'status' => 404, ) ); } return $post->post_content; } /** * Process /block/layout/builder_edit_data route request * * @param WP_Rest_Request $request Request to prepare items for. * * @return string|WP_Error * @since 4.1.0 */ public function process_builder_edit_data( WP_Rest_Request $request ) { $post_id = $request->get_param( 'postId' ); $block_id = $request->get_param( 'blockId' ); $nonce = $request->get_param( 'nonce' ); // No post ID. if ( empty( $post_id ) ) { return new WP_Error( 'no_post_id', esc_html__( 'No post id', 'et_builder' ), array( 'status' => 400, ) ); } // No block ID. if ( empty( $block_id ) ) { return new WP_Error( 'no_block_id', esc_html__( 'No block id', 'et_builder' ), array( 'status' => 400, ) ); } // Action nonce check. REST API actually has checked for nonce at cookie sent on every // request and performed capability-based check. This check perform action-based nonce // check to strengthen the security // @see https://developer.wordpress.org/rest-api/using-the-rest-api/authentication/. if ( ! wp_verify_nonce( $nonce, 'et_rest_process_builder_edit_data' ) ) { return new WP_Error( 'invalid_nonce', esc_html__( 'Invalid nonce', 'et_builder' ), array( 'status' => 400, ) ); } $result = ''; $post_meta_key = "_et_block_layout_preview_{$block_id}"; switch ( $request->get_param( 'action' ) ) { case 'get': $result = get_post_meta( $post_id, $post_meta_key, true ); break; case 'update': $layout_content = $request->get_param( 'layoutContent' ); // No layout content. if ( empty( $layout_content ) ) { return new WP_Error( 'no_layout_content', esc_html__( 'No layout content', 'et_builder' ), array( 'status' => 400, ) ); } $saved_layout_content = get_post_meta( $post_id, $post_meta_key, true ); if ( ! empty( $saved_layout_content ) && $saved_layout_content === $layout_content ) { // If for some reason layout exist and identical to the one being sent, return // true because update_post_meta() returns false if it updates the meta key and // the value doesn't change. $result = true; } else { // Otherwise, attempt to save post meta and returns how it goes. $result = update_post_meta( $post_id, $post_meta_key, $layout_content ); } break; case 'delete': $result = delete_post_meta( $post_id, $post_meta_key ); break; default: return new WP_Error( 'no_valid_action', esc_html__( 'No valid action found', 'et_builder' ), array( 'status' => 400, ) ); } return array( 'result' => $result, ); } /** * Sanitize int value * * @since 4.1.0 * * @param int|mixed $value Value. * * @return int */ public function sanitize_int( $value ) { return intval( $value ); } /** * Sanitize request "action" argument * * @since 4.1.0 * * @param string $value Action value. * * @return string */ public function sanitize_action( $value ) { return $this->validate_action( $value ) ? $value : ''; } /** * Validate request "action" argument * * @since 4.1.0 * * @param string $value Action value. * * @return bool */ public function validate_action( $value ) { $valid_builder_edit_data_actions = array( 'get', 'update', 'delete', ); return in_array( $value, $valid_builder_edit_data_actions, true ); } /** * Permission callback for get layout permalink REST API endpoint * * @since 4.1.0 * * @return bool */ public function rest_api_layout_block_permission() { return current_user_can( 'edit_posts' ) && et_pb_is_allowed( 'use_visual_builder' ); } } // Initialize ET_Api_Rest_Block_Layout. ET_Api_Rest_Block_Layout::instance();