PluginProbe
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot / 4.5.5
BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot v4.5.5
4.9.1 4.9.0 4.8.2 4.8.1 4.8.0 4.7.0 4.6.2 4.6.1 4.6.0 4.5.6 4.5.5 4.5.4 4.5.3 4.5.2 4.5.1 4.5.0 4.4.1 4.4.0 3.3.4 3.4.0 3.4.1 3.4.2 3.5.0 3.5.1 3.5.2 All 199 releases
betterdocs / includes / Editors / BlockEditor / StyleHandler.php

StyleHandler.php in BetterDocs – AI Documentation, Knowledge Base, MCP Server, Docs, Wikis, FAQ & Chatbot 4.5.5, at includes/Editors/BlockEditor/StyleHandler.php

243 lines 7.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 namespace WPDeveloper\BetterDocs\Editors\BlockEditor;
3
4 if ( ! defined( 'ABSPATH' ) ) {
5 exit; // Exit if accessed directly.
6 }
7
8 use WPDeveloper\BetterDocs\Utils\Base;
9
10 final class StyleHandler extends Base {
11 private $media_desktop = [
12 'name' => 'desktop',
13 'screen_size' => ''
14 ];
15
16 private $media_hover_desktop = [
17 'name' => 'desktopHover',
18 'screen_size' => ''
19 ];
20
21 private $media_tab = [
22 'name' => 'tab',
23 'screen_size' => 1024
24 ];
25
26 private $media_hover_tab = [
27 'name' => 'tabHover',
28 'screen_size' => 1024
29 ];
30
31 private $media_mobile = [
32 'name' => 'mobile',
33 'screen_size' => 767
34 ];
35
36 private $media_hover_mobile = [
37 'name' => 'mobileHover',
38 'screen_size' => 767
39 ];
40
41 private $extra_styles = [
42 'name' => 'extraStyles',
43 'screen_size' => ''
44 ];
45
46 public function __construct() {
47 add_action( 'admin_enqueue_scripts', [ $this, 'betterdocs_blocks_edit_post' ] );
48 // add_action( 'wp_ajax_betterdocs_write_block_css', [$this, 'write_block_css'] );
49 }
50
51 /**
52 * Enqueue a script in the WordPress admin on edit.php.
53 * @param int $hook Hook suffix for the current admin page.
54 */
55 public function betterdocs_blocks_edit_post( $hook ) {
56 if ( 'widgets.php' === $hook ) {
57 return;
58 }
59
60 if ( $hook != 'post.php' && $hook != 'post-new.php' && $hook != 'site-editor.php' ) {
61 return;
62 }
63
64 $_style_handler_deps = [
65 'lodash',
66 'wp-i18n',
67 'wp-element',
68 'wp-hooks',
69 'wp-util',
70 'wp-components',
71 'wp-blocks',
72 'wp-editor',
73 'wp-block-editor'
74 ];
75
76 $current_screen = get_current_screen();
77
78 $_style_handler_object = [
79 'sth_nonce' => wp_create_nonce( 'betterdocs_style_handler_nonce' ),
80 'editor_type' => 'edit-site'
81 ];
82
83 if ( $hook == 'post-new.php' && $current_screen->is_block_editor || $hook == 'post.php' && $current_screen->is_block_editor ) {
84 $_style_handler_deps[] = 'wp-edit-post';
85 $_style_handler_object['editor_type'] = 'edit-post';
86 } elseif ( $hook == 'site-editor.php' ) {
87 $_style_handler_deps[] = 'wp-edit-site';
88 $_style_handler_object['editor_type'] = 'edit-site';
89 }
90
91 betterdocs()->assets->enqueue( 'betterdocs-blocks-style-handler', 'vendor/js/style-handler.js', $_style_handler_deps );
92 betterdocs()->assets->localize( 'betterdocs-blocks-style-handler', 'betterdocs_style_handler', $_style_handler_object );
93 }
94
95 /**
96 * Ajax callback to write css in upload directory
97 * @retun void
98 * @since 1.0.2
99 */
100 public function write_block_css() {
101 $nonce = isset( $_POST['nonce'] ) ? sanitize_text_field( wp_unslash( $_POST['nonce'] ) ) : '';
102 if ( ! wp_verify_nonce( $nonce, 'betterdocs_style_handler_nonce' ) || ! current_user_can( 'manage_options' ) ) {
103 echo 'Invalid request';
104 wp_die();
105 }
106
107 $raw_data = isset( $_POST['data'] ) ? wp_unslash( $_POST['data'] ) : ''; // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized -- decoded JSON; values are sanitized in build_css().
108 $block_styles = (array) json_decode( $raw_data );
109
110 $editor_type = isset( $_POST['editorType'] ) ? sanitize_key( wp_unslash( $_POST['editorType'] ) ) : '';
111 if ( 'edit-site' === $editor_type ) {
112 $upload_dir = wp_upload_dir()['basedir'] . '/betterdocs-style/';
113 $editSiteCssPath = $upload_dir . 'betterdocs-style-' . $editor_type . '.min.css';
114 if ( file_exists( $editSiteCssPath ) ) {
115 $existingCss = file_get_contents( $editSiteCssPath );
116 $pattern = '~\/\*(.*?)\*\/~';
117 preg_match_all( $pattern, $existingCss, $result, PREG_PATTERN_ORDER );
118 $allComments = $result[0];
119 $seperatedIds = [];
120 foreach ( $allComments as $comment ) {
121 $id = preg_replace( '/[^A-Za-z0-9\-]|Ends|Starts/', '', $comment );
122
123 if ( strpos( $comment, 'Starts' ) ) {
124 $seperatedIds[ $id ]['start'] = $comment;
125 } elseif ( strpos( $comment, 'Ends' ) ) {
126 $seperatedIds[ $id ]['end'] = $comment;
127 }
128 }
129
130 $seperateStyles = [];
131 foreach ( $seperatedIds as $key => $ids ) {
132 $data = $this->get_between_data( $existingCss, $ids['start'], $ids['end'] );
133 $seperateStyles[ $key ] = $data;
134 }
135
136 $finalCSSArray = array_merge( $seperateStyles, $block_styles );
137
138 if ( ! empty( $css = $this->build_css( $finalCSSArray ) ) ) {
139 $upload_dir = wp_upload_dir()['basedir'] . '/betterdocs-style/';
140 if ( ! file_exists( $upload_dir ) ) {
141 wp_mkdir_p( $upload_dir );
142 }
143
144 file_put_contents( $editSiteCssPath, $css );
145 }
146 } elseif ( ! empty( $css = $this->build_css( $block_styles ) ) ) {
147 $upload_dir = wp_upload_dir()['basedir'] . '/betterdocs-style/';
148 if ( ! file_exists( $upload_dir ) ) {
149 wp_mkdir_p( $upload_dir );
150 }
151
152 file_put_contents( $editSiteCssPath, $css );
153 }
154 } elseif ( ! empty( $css = $this->build_css( $block_styles ) ) ) {
155 $upload_dir = wp_upload_dir()['basedir'] . '/betterdocs-style/';
156 if ( ! file_exists( $upload_dir ) ) {
157 wp_mkdir_p( $upload_dir );
158 }
159 $post_id = isset( $_POST['id'] ) ? absint( wp_unslash( $_POST['id'] ) ) : 0;
160 file_put_contents( $upload_dir . 'betterdocs-style-' . $post_id . '.min.css', $css );
161 }
162
163 wp_send_json_success( 'done' );
164 }
165
166 /**
167 * Enqueue frontend css for post if have one
168 * @param array
169 * @return string
170 * @since 1.0.2
171 */
172 private function build_css( $style_object ) {
173 // $block_styles = (array)json_decode(stripslashes($style_object));
174 $block_styles = $style_object;
175
176 $css = '';
177 foreach ( $block_styles as $block_style_key => $block_style ) {
178 if ( ! empty( $block_css = (array) $block_style ) ) {
179 $css .= sprintf(
180 '/* %1$s Starts */',
181 $block_style_key
182 );
183 foreach ( $block_css as $media => $style ) {
184 switch ( $media ) {
185 case $this->media_desktop['name']:
186 $css .= preg_replace( '/\s+/', ' ', $style );
187 break;
188 case $this->media_hover_desktop['name']:
189 $css .= preg_replace( '/\s+/', ' ', $style );
190 break;
191 case $this->media_tab['name']:
192 $css .= ' @media(max-width: 1024px){';
193 $css .= preg_replace( '/\s+/', ' ', $style );
194 $css .= '}';
195 break;
196 case $this->media_hover_tab['name']:
197 $css .= ' @media(max-width: 1024px){';
198 $css .= preg_replace( '/\s+/', ' ', $style );
199 $css .= '}';
200 break;
201 case $this->media_mobile['name']:
202 $css .= ' @media(max-width: 767px){';
203 $css .= preg_replace( '/\s+/', ' ', $style );
204 $css .= '}';
205 break;
206 case $this->media_hover_mobile['name']:
207 $css .= ' @media(max-width: 767px){';
208 $css .= preg_replace( '/\s+/', ' ', $style );
209 $css .= '}';
210 break;
211 case $this->extra_styles['name']:
212 $css .= preg_replace( '/\s+/', ' ', $style );
213 break;
214 }
215 }
216 $css .= sprintf(
217 '/* =%1$s= Ends */',
218 $block_style_key
219 );
220 }
221 }
222 return trim( $css );
223 }
224
225 /**
226 * Helper function to get string between 2 string
227 * @since 3.3.0
228 */
229 private function get_between_data( $string, $start, $end ) {
230 $pos_string = stripos( $string, $start );
231 $substr_data = substr( $string, $pos_string );
232 $string_two = substr( $substr_data, strlen( $start ) );
233 $second_pos = stripos( $string_two, $end );
234 $string_three = substr( $string_two, 0, $second_pos );
235
236 // remove whitespaces from result
237 $result_unit = trim( $string_three );
238
239 // return result_unit
240 return $result_unit;
241 }
242 }
243