PluginProbe
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar / 3.3.1
NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar v3.3.1
3.3.1 3.3.0 3.2.14 3.2.13 3.2.12 3.2.11 3.2.10 3.2.9 3.2.8 3.2.7 trunk 0.2.5.5 0.2.5.6 0.2.5.7 1.0.0 1.0.1 1.0.2 1.0.3 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.2.0 1.2.1 All 156 releases
notificationx / blocks / style-handler / style-handler.php

style-handler.php in NotificationX – FOMO, Live Sales Notification, WooCommerce Sales Popup, GDPR, Social Proof, Announcement Banner & Floating Notification Bar 3.3.1, at blocks/style-handler/style-handler.php

292 lines 12.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace NotificationX\Blocks;
4
5 use NotificationX\GetInstance;
6
7 /**
8 *
9 * @method static StyleHandler get_instance($args = null)
10 */
11 final class StyleHandler {
12 /**
13 * Instance of NotificationX
14 *
15 * @var StyleHandler
16 */
17 use GetInstance;
18
19 private $media_desktop = [
20 'name' => 'desktop',
21 'screen_size' => '',
22 ];
23 private $media_tab = [
24 'name' => 'tab',
25 'screen_size' => 1024,
26 ];
27 private $media_mobile = [
28 'name' => 'mobile',
29 'screen_size' => 767,
30 ];
31 private $eb_prefix = 'eb-style';
32
33 public function __construct() {
34 add_action( 'admin_enqueue_scripts', [ $this, 'notificationx_pro_blocks_edit_post' ] );
35 add_action( 'wp_ajax_notificationx_pro_write_block_css', [ $this, 'write_block_css' ] );
36 add_action( 'wp_enqueue_scripts', [ $this, 'enqueue_frontend_css' ] );
37 }
38
39 /**
40 * Enqueue a script in the WordPress admin on edit.php.
41 *
42 * @param int $hook Hook suffix for the current admin page.
43 */
44 public function notificationx_pro_blocks_edit_post( $hook ) {
45 $current_screen = get_current_screen();
46 $post_type = !empty( $current_screen->post_type ) ? $current_screen->post_type : '';
47 $dir = dirname( __FILE__ );
48 if ( ($hook == 'post-new.php' || $hook == 'post.php') && $post_type == 'nx_bar_eb' ) {
49 wp_enqueue_script(
50 'notificationx-pro-blocks-edit-post',
51 NOTIFICATIONX_URL . 'blocks/style-handler/style-handler.js',
52 array(
53 'lodash',
54 'wp-i18n',
55 'wp-element',
56 'wp-hooks',
57 'wp-util',
58 'wp-components',
59 'wp-blocks',
60 'wp-editor',
61 'wp-block-editor',
62 'wp-edit-post',
63 ),
64 filemtime( NOTIFICATIONX_PATH . 'blocks/style-handler/style-handler.js' ),
65 true
66 );
67 wp_localize_script('notificationx-pro-blocks-edit-post', 'nx_style_handler', [
68 'sth_nonce' => wp_create_nonce( 'nx_style_handler_nonce' ),
69 'editor_type' => 'edit-post',
70 ]
71 );
72 } elseif ( $hook == 'site-editor.php' ) {
73 wp_enqueue_script(
74 'notificationx-pro-blocks-edit-post',
75 NOTIFICATIONX_URL . 'blocks/style-handler/style-handler.js',
76 array(
77 'lodash',
78 'wp-i18n',
79 'wp-element',
80 'wp-hooks',
81 'wp-util',
82 'wp-components',
83 'wp-blocks',
84 'wp-editor',
85 'wp-block-editor',
86 'wp-edit-site',
87 ),
88 filemtime( NOTIFICATIONX_PATH . 'blocks/style-handler/style-handler.js' ),
89 true
90 );
91 wp_localize_script('notificationx-pro-blocks-edit-post', 'nx_style_handler', [
92 'sth_nonce' => wp_create_nonce( 'nx_style_handler_nonce' ),
93 'editor_type' => 'edit-site',
94 ]
95 );
96 // Override the default 'edit-post' global (set on the controls handle
97 // in Blocks.php) so the inline block reads the core/edit-site store
98 // when used inside the Full Site Editor.
99 wp_localize_script('notificationx-block-controls', 'nx_style_handler', [
100 'sth_nonce' => wp_create_nonce( 'nx_style_handler_nonce' ),
101 'editor_type' => 'edit-site',
102 ]
103 );
104 }
105 }
106
107 /**
108 * Ajax callback to write css in upload directory
109 *
110 * @retun void
111 * @since 1.0.2
112 */
113 public function write_block_css() {
114 if ( ! isset( $_POST['nonce'] ) || ! wp_verify_nonce( sanitize_text_field( wp_unslash( $_POST['nonce'] ) ), 'nx_style_handler_nonce' ) || ! current_user_can( 'manage_options' ) ) {
115 echo 'Invalid request';
116 wp_die();
117 }
118
119 // The payload is a JSON blob of block styles, so it cannot be run through a
120 // scalar sanitiser without destroying it. It is decoded structurally below and
121 // this endpoint is already gated on a nonce plus manage_options above.
122 // phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
123 $block_styles = isset( $_POST['data'] ) ? (array) json_decode( wp_unslash( $_POST['data'] ) ) : array();
124
125 $editor_type = isset( $_POST['editorType'] ) ? sanitize_key( wp_unslash( $_POST['editorType'] ) ) : '';
126 if ( $editor_type === 'edit-site' ) {
127 $upload_dir = wp_upload_dir()['basedir'] . '/nx-style/';
128 $editSiteCssPath = $upload_dir . 'nx-style-' . $editor_type . '.min.css';
129 if ( file_exists( $editSiteCssPath ) ) {
130 $existingCss = file_get_contents( $editSiteCssPath );
131 $pattern = '~\/\*(.*?)\*\/~';
132 preg_match_all( $pattern, $existingCss, $result, PREG_PATTERN_ORDER );
133 $allComments = $result[0];
134 $seperatedIds = array();
135 foreach ( $allComments as $comment ) {
136 $id = preg_replace( '/[^A-Za-z0-9\-]|Ends|Starts/', '', $comment );
137
138 if ( strpos( $comment, 'Starts' ) ) {
139 $seperatedIds[ $id ]['start'] = $comment;
140 } elseif ( strpos( $comment, 'Ends' ) ) {
141 $seperatedIds[ $id ]['end'] = $comment;
142 }
143 }
144
145 $seperateStyles = array();
146 foreach ( $seperatedIds as $key => $ids ) {
147 $data = $this->get_between_data( $existingCss, $ids['start'], $ids['end'] );
148 $seperateStyles[ $key ] = $data;
149 }
150
151 $finalCSSArray = array_merge( $seperateStyles, $block_styles );
152
153 if ( ! empty( $css = $this->build_css( $finalCSSArray ) ) ) {
154 $upload_dir = wp_upload_dir()['basedir'] . '/nx-style/';
155 if ( ! file_exists( $upload_dir ) ) {
156 wp_mkdir_p( $upload_dir );
157 }
158
159 file_put_contents( $editSiteCssPath, $css );
160 }
161 } else {
162 if ( ! empty( $css = $this->build_css( $block_styles ) ) ) {
163 $upload_dir = wp_upload_dir()['basedir'] . '/nx-style/';
164 if ( ! file_exists( $upload_dir ) ) {
165 wp_mkdir_p( $upload_dir );
166 }
167
168 file_put_contents( $editSiteCssPath, $css );
169 }
170 }
171 } else {
172 if ( ! empty( $css = $this->build_css( $block_styles ) ) ) {
173 $upload_dir = wp_upload_dir()['basedir'] . '/nx-style/';
174 if ( ! file_exists( $upload_dir ) ) {
175 wp_mkdir_p( $upload_dir );
176 }
177 $style_id = isset( $_POST['id'] ) ? absint( wp_unslash( $_POST['id'] ) ) : 0;
178 file_put_contents( $upload_dir . 'nx-style-' . $style_id . '.min.css', $css );
179 }
180 }
181
182 wp_die();
183 }
184
185 /**
186 * Enqueue frontend css for post if have one
187 *
188 * @return void
189 * @since 1.0.2
190 */
191 public function enqueue_frontend_css() {
192 global $post;
193 if ( ! empty( $post ) && ! empty( $post->ID ) ) {
194 $upload_dir = wp_upload_dir();
195 $args = [ 'enabled' => true, 'source' => 'press_bar', 'updated_at' => ['<=', current_time('mysql') ] ];
196 $pressbar_notifications = \NotificationX\Core\PostType::get_instance()->get_posts($args);
197 foreach ($pressbar_notifications as $pressbar) {
198 if( !empty( $pressbar['gutenberg_id'] ) ) {
199 $style_file = $upload_dir['basedir'] . DIRECTORY_SEPARATOR . 'eb-style' . DIRECTORY_SEPARATOR . $this->eb_prefix . '-' . $pressbar['gutenberg_id'] . '.min.css';
200 $style_url = set_url_scheme($upload_dir['baseurl']) . '/' . 'eb-style' . '/' . $this->eb_prefix . '-' . $pressbar['gutenberg_id'] . '.min.css';
201 if (file_exists($style_file)) {
202 wp_enqueue_style(
203 'nx-style-' . $pressbar['gutenberg_id'], // Handle based only on post ID
204 $style_url,
205 [],
206 filemtime($style_file) // Cache busting with last modified time
207 );
208 }
209 }
210
211 }
212
213 if ( file_exists( $upload_dir['basedir'] . '/nx-style/nx-style-' . $post->ID . '.min.css' ) ) {
214 wp_enqueue_style( 'nx-block-style-' . $post->ID, $upload_dir['baseurl'] . '/nx-style/nx-style-' . $post->ID . '.min.css', [], substr( md5( microtime( true ) ), 0, 10 ) );
215 } elseif ( function_exists( 'icl_object_id' ) ) {
216 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context.
217 $default_language = apply_filters( 'wpml_default_language', null );
218 $english_version = icl_object_id( $post->ID, 'post', false, $default_language );
219 if ( file_exists( $upload_dir['basedir'] . '/nx-style/nx-style-' . $english_version . '.min.css' ) ) {
220 wp_enqueue_style( 'nx-block-style-' . $english_version, $upload_dir['baseurl'] . '/nx-style/nx-style-' . $english_version . '.min.css', [], substr( md5( microtime( true ) ), 0, 10 ) );
221 }
222 }
223 if ( function_exists( 'wp_is_block_theme' ) && wp_is_block_theme() && file_exists( $upload_dir['basedir'] . '/nx-style/nx-style-edit-site.min.css' ) ) {
224 wp_enqueue_style( 'nx-fullsite-style', $upload_dir['baseurl'] . '/nx-style/nx-style-edit-site.min.css', [], substr( md5( microtime( true ) ), 0, 10 ) );
225 }
226 }
227 }
228
229 /**
230 * Enqueue frontend css for post if have one
231 *
232 * @param string
233 * @return string
234 * @since 1.0.2
235 */
236 private function build_css( $style_object ) {
237 // $block_styles = (array)json_decode(stripslashes($style_object));
238 $block_styles = $style_object;
239
240 $css = '';
241 foreach ( $block_styles as $block_style_key => $block_style ) {
242 if ( ! empty( $block_css = (array) $block_style ) ) {
243 $css .= sprintf(
244 '/* %1$s Starts */',
245 $block_style_key
246 );
247 foreach ( $block_css as $media => $style ) {
248 switch ( $media ) {
249 case $this->media_desktop['name']:
250 $css .= preg_replace( '/\s+/', ' ', $style );
251 break;
252 case $this->media_tab['name']:
253 $css .= ' @media(max-width: 1024px){';
254 $css .= preg_replace( '/\s+/', ' ', $style );
255 $css .= '}';
256 break;
257 case $this->media_mobile['name']:
258 $css .= ' @media(max-width: 767px){';
259 $css .= preg_replace( '/\s+/', ' ', $style );
260 $css .= '}';
261 break;
262 }
263 }
264 $css .= sprintf(
265 '/* =%1$s= Ends */',
266 $block_style_key
267 );
268 }
269 }
270 return trim( $css );
271 }
272
273 /**
274 * Helper function to get string between 2 string
275 *
276 * @since 3.3.0
277 */
278 private function get_between_data( $string, $start, $end ) {
279 $pos_string = stripos( $string, $start );
280 $substr_data = substr( $string, $pos_string );
281 $string_two = substr( $substr_data, strlen( $start ) );
282 $second_pos = stripos( $string_two, $end );
283 $string_three = substr( $string_two, 0, $second_pos );
284
285 // remove whitespaces from result
286 $result_unit = trim( $string_three );
287
288 // return result_unit
289 return $result_unit;
290 }
291 }
292