| @@ -1,0 +1,1281 @@ | ||
| 1 | +<?php | |
| 2 | + | |
| 3 | +/** | |
| 4 | + * FrontEnd Class | |
| 5 | + * | |
| 6 | + * @package NotificationX\FrontEnd | |
| 7 | + */ | |
| 8 | + | |
| 9 | +namespace NotificationX\FrontEnd; | |
| 10 | + | |
| 11 | +use NotificationX\Admin\Entries; | |
| 12 | +use NotificationX\Admin\Settings; | |
| 13 | +use NotificationX\Core\Analytics; | |
| 14 | +use NotificationX\Core\Database; | |
| 15 | +use NotificationX\Core\GetData; | |
| 16 | +use NotificationX\NotificationX; | |
| 17 | +use NotificationX\Core\Locations; | |
| 18 | +use NotificationX\Core\PostType; | |
| 19 | +use NotificationX\Core\REST; | |
| 20 | +use NotificationX\GetInstance; | |
| 21 | +use NotificationX\Extensions\PressBar\PressBar; | |
| 22 | +use NotificationX\Core\Helper; | |
| 23 | +use NotificationX\Extensions\ExtensionFactory; | |
| 24 | +use NotificationX\Types\GDPR; | |
| 25 | + | |
| 26 | +/** | |
| 27 | + * This class is responsible for all Front-End actions. | |
| 28 | + * @method static FrontEnd get_instance($args = null) | |
| 29 | + */ | |
| 30 | +class FrontEnd { | |
| 31 | + /** | |
| 32 | + * Instance of FrontEnd | |
| 33 | + * | |
| 34 | + * @var FrontEnd | |
| 35 | + */ | |
| 36 | + use GetInstance; | |
| 37 | + /** | |
| 38 | + * Assets Path and URL | |
| 39 | + */ | |
| 40 | + const ASSET_URL = NOTIFICATIONX_ASSETS . 'public/'; | |
| 41 | + const ASSET_PATH = NOTIFICATIONX_ASSETS_PATH . 'public/'; | |
| 42 | + protected $notificationXArr = []; | |
| 43 | + | |
| 44 | + /** | |
| 45 | + * Block-editor bars whose block assets are already on this page, keyed by | |
| 46 | + * the bar's `gutenberg_id` (see enqueue_gutenberg_bar_assets()). | |
| 47 | + * | |
| 48 | + * @var array<int, true> | |
| 49 | + */ | |
| 50 | + protected $gutenberg_bar_assets = []; | |
| 51 | + | |
| 52 | + /** | |
| 53 | + * Initially Invoked | |
| 54 | + * when its initialized. | |
| 55 | + */ | |
| 56 | + public function __construct() { | |
| 57 | + Analytics::get_instance(); | |
| 58 | + BarSpace::get_instance(); | |
| 59 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 60 | + if (!is_admin() || !empty($_GET['frontend'])) { | |
| 61 | + add_action('init', [$this, 'init'], 10); | |
| 62 | + } | |
| 63 | + add_filter('nx_frontend_localize_data', [$this, 'get_localize_data']); | |
| 64 | + Preview::get_instance(); | |
| 65 | + } | |
| 66 | + | |
| 67 | + /** | |
| 68 | + * This method is reponsible for Admin Menu of | |
| 69 | + * NotificationX | |
| 70 | + * | |
| 71 | + * @return void | |
| 72 | + */ | |
| 73 | + public function init() { | |
| 74 | + add_action('wp_enqueue_scripts', [$this, 'enqueue_scripts'], 10); | |
| 75 | + add_filter('nx_fallback_data', [$this, 'fallback_data'], 10, 3); | |
| 76 | + add_filter('nx_filtered_data', [$this, 'filtered_data'], 9999, 3); | |
| 77 | + add_filter('nx_filtered_post', [$this, 'filtered_post'], 9999, 2); | |
| 78 | + add_action('wp_print_footer_scripts', [$this, 'footer_scripts']); | |
| 79 | + // After wp_enqueue_scripts (wp_head priority 1) has collected the page's bars. | |
| 80 | + add_action('wp_head', [$this, 'print_bar_reserve'], 3); | |
| 81 | + add_filter('body_class', [ $this, 'nx_add_body_class' ] ); | |
| 82 | + add_filter('style_loader_tag', [$this, 'non_blocking_style_tag'], 10, 2); | |
| 83 | + | |
| 84 | + } | |
| 85 | + | |
| 86 | + /** | |
| 87 | + * Third-party stylesheets used by the notification themes, keyed by style | |
| 88 | + * handle. | |
| 89 | + * | |
| 90 | + * They used to be CSS `@import`s at the top of frontend.css, which the | |
| 91 | + * browser only discovers once frontend.css has downloaded: a serial, | |
| 92 | + * render-blocking chain to two more origins on every page. They are now | |
| 93 | + * enqueued next to `notificationx-public` and loaded without blocking the | |
| 94 | + * first paint (see non_blocking_style_tag()). | |
| 95 | + * | |
| 96 | + * @since 3.3.3 | |
| 97 | + * @return array<string, string> Style handle => URL. | |
| 98 | + */ | |
| 99 | + public function get_external_styles() { | |
| 100 | + $styles = []; | |
| 101 | + /** | |
| 102 | + * Filters whether NotificationX loads Open Sans from Google Fonts. | |
| 103 | + * | |
| 104 | + * Return false if the site already loads Open Sans or must not | |
| 105 | + * contact Google Fonts; the themes then fall back to sans-serif. | |
| 106 | + * | |
| 107 | + * @since 3.3.3 | |
| 108 | + * @param bool $load Default true. | |
| 109 | + */ | |
| 110 | + if (apply_filters('notificationx_load_open_sans', true)) { | |
| 111 | + $styles['notificationx-open-sans'] = 'https://fonts.googleapis.com/css2?family=Open+Sans:wght@400;500;600;700&display=swap'; | |
| 112 | + } | |
| 113 | + /** | |
| 114 | + * Filters whether NotificationX loads FontAwesome 4.7 from cdnjs. | |
| 115 | + * | |
| 116 | + * The icons are drawn in pseudo-elements of a few themes only. Return | |
| 117 | + * false if the site already loads FontAwesome 4. | |
| 118 | + * | |
| 119 | + * @since 3.3.3 | |
| 120 | + * @param bool $load Default true. | |
| 121 | + */ | |
| 122 | + if (apply_filters('notificationx_load_fontawesome', true)) { | |
| 123 | + $styles['notificationx-fontawesome-4'] = 'https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'; | |
| 124 | + } | |
| 125 | + return $styles; | |
| 126 | + } | |
| 127 | + | |
| 128 | + /** | |
| 129 | + * Enqueue the third-party font and icon stylesheets (get_external_styles()). | |
| 130 | + * | |
| 131 | + * Call this wherever `notificationx-public` (or a stylesheet that bundles | |
| 132 | + * the frontend themes) is enqueued. | |
| 133 | + * | |
| 134 | + * @since 3.3.3 | |
| 135 | + * @return void | |
| 136 | + */ | |
| 137 | + public function enqueue_external_styles() { | |
| 138 | + foreach ($this->get_external_styles() as $handle => $src) { | |
| 139 | + // phpcs:ignore WordPress.WP.EnqueuedResourceParameters.MissingVersion -- Third-party URL; a ?ver= query would only split the CDN cache. | |
| 140 | + wp_enqueue_style($handle, $src, [], null); | |
| 141 | + } | |
| 142 | + } | |
| 143 | + | |
| 144 | + /** | |
| 145 | + * Load some stylesheets without blocking the first paint. | |
| 146 | + * | |
| 147 | + * - `notificationx-public` styles only what the runtime renders — bars, | |
| 148 | + * popups and shortcodes all mount from REST data after the page has | |
| 149 | + * loaded (the bar's reserved space is a separate inline style), and the | |
| 150 | + * runtime waits for this sheet before its first render (whenStyled()). | |
| 151 | + * At ~600 KB it was the largest render-blocking stylesheet on every page. | |
| 152 | + * - `notificationx-gdpr-modal` styles only the cookie-preferences modal, | |
| 153 | + * which opens on a click. | |
| 154 | + * - The font and icon stylesheets from get_external_styles(): the fonts | |
| 155 | + * swap in, and the FontAwesome glyphs are drawn only in pseudo-elements | |
| 156 | + * of notifications the runtime renders after the page has loaded. | |
| 157 | + * | |
| 158 | + * The stylesheet is requested as `print` and switched to `all` once it has | |
| 159 | + * loaded; the <noscript> copy keeps it for visitors without JavaScript. | |
| 160 | + * `data-nx-style` marks it for the runtime, which also switches it (see | |
| 161 | + * applyDeferredStyles() in external-styles.ts) in case the inline handler | |
| 162 | + * was stripped by an optimizer or blocked by a Content Security Policy. | |
| 163 | + * | |
| 164 | + * @param string $tag The link tag. | |
| 165 | + * @param string $handle Style handle. | |
| 166 | + * @return string | |
| 167 | + */ | |
| 168 | + public function non_blocking_style_tag($tag, $handle) { | |
| 169 | + $handles = ['notificationx-public', 'notificationx-gdpr-modal', 'notificationx-open-sans', 'notificationx-fontawesome-4']; | |
| 170 | + if (!in_array($handle, $handles, true) || false !== strpos($tag, 'onload=')) { | |
| 171 | + return $tag; | |
| 172 | + } | |
| 173 | + $deferred = preg_replace('/\smedia=([\'"])all\1/', ' media=$1print$1 onload="this.media=\'all\'" data-nx-style=$1print$1', $tag, 1, $count); | |
| 174 | + if (!$count) { | |
| 175 | + return $tag; | |
| 176 | + } | |
| 177 | + return $deferred . '<noscript>' . trim($tag) . "</noscript>\n"; | |
| 178 | + } | |
| 179 | + | |
| 180 | + /** | |
| 181 | + * Script dependencies of the `notificationx-public` runtime. | |
| 182 | + * | |
| 183 | + * `wp-hooks` provides `window.wp.hooks`, the registry the runtime reads its | |
| 184 | + * frontend filters from (see nxdev/notificationx/frontend/core/hooks.ts and | |
| 185 | + * docs/api/frontend-js-hooks.md). It is always kept, even if a filter drops | |
| 186 | + * it, because without it every add-on filter silently stops firing. | |
| 187 | + * | |
| 188 | + * @since 3.3.3 | |
| 189 | + * @return string[] | |
| 190 | + */ | |
| 191 | + public function get_script_dependencies() { | |
| 192 | + /** | |
| 193 | + * Filters the script dependencies of the `notificationx-public` runtime. | |
| 194 | + * | |
| 195 | + * @since 3.3.3 | |
| 196 | + * @param string[] $deps Script handles. | |
| 197 | + */ | |
| 198 | + $deps = apply_filters( 'nx_frontend_script_deps', [ 'wp-hooks' ] ); | |
| 199 | + $deps = is_array( $deps ) ? array_filter( $deps, 'is_string' ) : []; | |
| 200 | + array_unshift( $deps, 'wp-hooks' ); | |
| 201 | + return array_values( array_unique( $deps ) ); | |
| 202 | + } | |
| 203 | + | |
| 204 | + /** | |
| 205 | + * This method is responsible for enqueueing scripts for public use. | |
| 206 | + * | |
| 207 | + * @return void | |
| 208 | + */ | |
| 209 | + public function enqueue_scripts() { | |
| 210 | + $custom_css = $this->generate_custom_css(); | |
| 211 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 212 | + wp_register_script('notificationx-public', Helper::file('public/js/frontend.js', true), $this->get_script_dependencies(), apply_filters('nx_frontend_js_version', NOTIFICATIONX_VERSION ), true); | |
| 213 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 214 | + wp_register_style('notificationx-public', Helper::file('public/css/frontend.css', true), [], apply_filters('nx_frontend_css_version', NOTIFICATIONX_VERSION ), 'all'); | |
| 215 | + // GDPR cookie-customisation modal styles, split out of frontend.css | |
| 216 | + // (~305 KB) so only pages with an active GDPR notice load them. | |
| 217 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 218 | + wp_register_style('notificationx-gdpr-modal', Helper::file('public/css/gdpr-modal.css', true), ['notificationx-public'], apply_filters('nx_frontend_css_version', NOTIFICATIONX_VERSION ), 'all'); | |
| 219 | + // wp_register_style('notificationx-icon-pack', Helper::file('public/icon/style.css', true), [], NOTIFICATIONX_VERSION, 'all'); | |
| 220 | + // Localize scripts for frontend | |
| 221 | + wp_localize_script( | |
| 222 | + 'notificationx-public', | |
| 223 | + 'notificationxPublic', | |
| 224 | + array( | |
| 225 | + 'necessary_tab_info' => [ | |
| 226 | + 'title' => __('Necessary', 'notificationx'), | |
| 227 | + 'desc' => __('Necessary cookies are needed to ensure the basic functions of this site, like allowing secure log-ins and managing your consent settings. These cookies do not collect any personal information.', 'notificationx'), | |
| 228 | + ], | |
| 229 | + 'functional_tab_info' => [ | |
| 230 | + 'title' => __('Functional', 'notificationx'), | |
| 231 | + 'desc' => __('Functional cookies assist in performing tasks like sharing website content on social media, collecting feedback, and enabling other third-party features.', 'notificationx'), | |
| 232 | + ], | |
| 233 | + 'analytics_tab_info' => [ | |
| 234 | + 'title' => __('Analytics', 'notificationx'), | |
| 235 | + 'desc' => __('Analytical cookies help us understand how visitors use the website. They provide data on metrics like the number of visitors, bounce rate, traffic sources etc.', 'notificationx'), | |
| 236 | + ], | |
| 237 | + 'performance_tab_info' => [ | |
| 238 | + 'title' => __('Performance', 'notificationx'), | |
| 239 | + 'desc' => __("Performance cookies help analyze the website's key performance indicators, which in turn helps improve the user experience for visitors.", 'notificationx'), | |
| 240 | + ], | |
| 241 | + 'advertising_tab_info' => [ | |
| 242 | + 'title' => __('Advertisement', 'notificationx'), | |
| 243 | + 'desc' => __("Advertisement cookies help analyze the website's key advertising indicators, which in turn helps improve the user experience for visitors.", 'notificationx'), | |
| 244 | + ], | |
| 245 | + 'uncategorized_tab_info' => [ | |
| 246 | + 'title' => __('Uncategorized', 'notificationx'), | |
| 247 | + 'desc' => __("Uncategorized cookies are those that don't fall into any specific category but may still be used for various purposes on the site. These cookies help us improve user experience by tracking interactions that don't fit into other cookie types.", 'notificationx'), | |
| 248 | + ], | |
| 249 | + 'is_enabled_wp_consent_api' => is_plugin_active('wp-consent-api/wp-consent-api.php'), | |
| 250 | + ) | |
| 251 | + ); | |
| 252 | + | |
| 253 | + $exit = false; | |
| 254 | + $referer = isset($_SERVER['HTTP_REFERER']) ? esc_url_raw(wp_unslash($_SERVER['HTTP_REFERER'])) : ''; | |
| 255 | + if($referer && strpos($referer, 'wp-admin/widgets.php') !== false){ | |
| 256 | + $exit = ['total' => 0]; | |
| 257 | + } | |
| 258 | + | |
| 259 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 260 | + $exit = apply_filters('nx_before_enqueue_scripts', $exit); | |
| 261 | + if(!empty($exit)){ | |
| 262 | + $this->notificationXArr = $exit; | |
| 263 | + return; | |
| 264 | + } | |
| 265 | + | |
| 266 | + // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 267 | + if (!$exit && empty($_GET['elementor-preview'])) { | |
| 268 | + $this->notificationXArr = $this->get_notifications_ids(); | |
| 269 | + if ($this->notificationXArr['total'] > 0) { | |
| 270 | + $lang = get_locale(); | |
| 271 | + $lang = str_replace('_', '-', $lang); | |
| 272 | + $lang = strtolower($lang); | |
| 273 | + $_lang = explode('-', $lang); | |
| 274 | + if ($lang !== "en" && $lang !== "en-us") { | |
| 275 | + $script = Helper::file("public/locale/$lang.js", false); | |
| 276 | + if (file_exists($script)) { | |
| 277 | + wp_enqueue_script('notificationx-moment-locale', Helper::file("public/locale/$lang.js", true), [], NOTIFICATIONX_VERSION, true); | |
| 278 | + } else if (!empty($_lang[1])) { | |
| 279 | + $lang = $_lang[0]; | |
| 280 | + $script = Helper::file("public/locale/$lang.js", false); | |
| 281 | + if (file_exists($script)) { | |
| 282 | + wp_enqueue_script('notificationx-moment-locale', Helper::file("public/locale/$lang.js", true), [], NOTIFICATIONX_VERSION, true); | |
| 283 | + } | |
| 284 | + } | |
| 285 | + } | |
| 286 | + | |
| 287 | + wp_enqueue_style('notificationx-public'); | |
| 288 | + $this->enqueue_external_styles(); | |
| 289 | + if ( ! empty( $this->notificationXArr['gdpr'] ) ) { | |
| 290 | + wp_enqueue_style('notificationx-gdpr-modal'); | |
| 291 | + } | |
| 292 | + wp_enqueue_script('notificationx-public'); | |
| 293 | + wp_enqueue_style('dashicons'); | |
| 294 | + do_action('notificationx_scripts', $this->notificationXArr); | |
| 295 | + wp_add_inline_style( 'notificationx-public', $custom_css ); | |
| 296 | + } | |
| 297 | + } else { | |
| 298 | + // @todo maybe elementor edit mode CSS. to move to top. | |
| 299 | + // LATER | |
| 300 | + } | |
| 301 | + } | |
| 302 | + | |
| 303 | + /** | |
| 304 | + * Reserve the top bar's measured height before it mounts (see BarSpace). | |
| 305 | + * | |
| 306 | + * @return void | |
| 307 | + */ | |
| 308 | + public function print_bar_reserve() { | |
| 309 | + // The builder preview passes preview data here, not bar IDs. | |
| 310 | + if (!empty($this->notificationXArr['nxPreview']) || empty($this->notificationXArr['pressbar']) || !is_array($this->notificationXArr['pressbar'])) { | |
| 311 | + return; | |
| 312 | + } | |
| 313 | + $ids = array_filter($this->notificationXArr['pressbar'], 'is_numeric'); | |
| 314 | + if ($ids) { | |
| 315 | + BarSpace::get_instance()->print_reserve($ids); | |
| 316 | + } | |
| 317 | + } | |
| 318 | + | |
| 319 | + public function nx_add_body_class($classes) { | |
| 320 | + $classes[] = 'has-notificationx'; | |
| 321 | + // Tells the runtime it need not fetch these bars' pages for their assets. | |
| 322 | + foreach (array_keys($this->gutenberg_bar_assets) as $gutenberg_id) { | |
| 323 | + $classes[] = 'nx-bar-assets-' . $gutenberg_id; | |
| 324 | + } | |
| 325 | + return $classes; | |
| 326 | + } | |
| 327 | + | |
| 328 | + /** | |
| 329 | + * Put a block-editor bar's block assets on the current page. | |
| 330 | + * | |
| 331 | + * The bar's HTML arrives over REST after load, where anything its blocks | |
| 332 | + * enqueue is discarded. The runtime used to recover those assets by | |
| 333 | + * fetching the bar's own permalink — a full themed page (~300 KB on | |
| 334 | + * essential-blocks.com) — and loading each stylesheet and script it had | |
| 335 | + * that this page did not, one after another, before the bar could settle. | |
| 336 | + * Rendering the blocks here, while this page's assets are still being | |
| 337 | + * collected, lets each block enqueue what it needs (e.g. a countdown's | |
| 338 | + * frontend script) exactly as it would in post content; the output is | |
| 339 | + * discarded. Mirrors the Elementor branch above. | |
| 340 | + * | |
| 341 | + * Runs for page loads only: REST and admin requests have no page to add | |
| 342 | + * assets to. | |
| 343 | + * | |
| 344 | + * @param int|string $gutenberg_id The bar's block post ID. | |
| 345 | + * @return void | |
| 346 | + */ | |
| 347 | + protected function enqueue_gutenberg_bar_assets($gutenberg_id) { | |
| 348 | + $gutenberg_id = absint($gutenberg_id); | |
| 349 | + if (!$gutenberg_id || isset($this->gutenberg_bar_assets[$gutenberg_id]) || !doing_action('wp_enqueue_scripts')) { | |
| 350 | + return; | |
| 351 | + } | |
| 352 | + // Same lookup as PressBar::print_bar_notice(), which renders the HTML the runtime shows. | |
| 353 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 354 | + $post_id = apply_filters('wpml_object_id', $gutenberg_id, 'wp_block', true); | |
| 355 | + $post = $post_id ? get_post($post_id) : null; | |
| 356 | + if (!$post || '' === trim((string) $post->post_content)) { | |
| 357 | + return; | |
| 358 | + } | |
| 359 | + // This runs inside <head> (wp_enqueue_scripts). A block whose render | |
| 360 | + // callback echoes instead of returning would print into <head> and push | |
| 361 | + // every later head tag into <body>; buffer and discard all output. | |
| 362 | + ob_start(); | |
| 363 | + try { | |
| 364 | + do_blocks($post->post_content); | |
| 365 | + } finally { | |
| 366 | + ob_end_clean(); | |
| 367 | + } | |
| 368 | + $this->gutenberg_bar_assets[$gutenberg_id] = true; | |
| 369 | + } | |
| 370 | + | |
| 371 | + private function separate_css($css) { | |
| 372 | + $media_css = ''; | |
| 373 | + $normal_css = ''; | |
| 374 | + | |
| 375 | + // Match @media blocks | |
| 376 | + preg_match_all('/@media[^{]*{([^}]*{[^}]*})*[^}]*}/', $css, $media_matches); | |
| 377 | + | |
| 378 | + // Extract normal CSS | |
| 379 | + $normal_css = preg_replace('/@media[^{]*{([^}]*{[^}]*})*[^}]*}/', '', $css); | |
| 380 | + | |
| 381 | + // Extract @media CSS | |
| 382 | + if (!empty($media_matches[0])) { | |
| 383 | + $media_css = implode("\n", $media_matches[0]); | |
| 384 | + } | |
| 385 | + | |
| 386 | + // Clean up normal CSS (remove extra whitespace) | |
| 387 | + $normal_css = trim($normal_css); | |
| 388 | + | |
| 389 | + return [ | |
| 390 | + 'normal_css' => $normal_css, | |
| 391 | + 'media_css' => $media_css | |
| 392 | + ]; | |
| 393 | + } | |
| 394 | + | |
| 395 | + public function generate_custom_css() { | |
| 396 | + $posts = Database::get_instance()->get_posts(Database::$table_posts, '*', ['enabled' => true] ); | |
| 397 | + $combine_css = ""; | |
| 398 | + foreach ($posts as $post) { | |
| 399 | + // Raw rows (not normalize_post()), so check the type here. | |
| 400 | + if( !empty( $post['data']['add_custom_css'] ) && is_string( $post['data']['add_custom_css'] ) && !empty( $post['nx_id'] ) ) { | |
| 401 | + $separatedCss = $this->separate_css($post['data']['add_custom_css']); | |
| 402 | + if( !empty( $post['data']['source'] ) && $post['data']['source'] == 'press_bar' ) { | |
| 403 | + $combine_css .= "{$separatedCss['normal_css']} {$separatedCss['media_css']} "; | |
| 404 | + } else if( !empty( $post['data']['source'] ) && $post['data']['source'] == 'gdpr_notification' ) { | |
| 405 | + $combine_css .= "{$separatedCss['normal_css']} {$separatedCss['media_css']} "; | |
| 406 | + } | |
| 407 | + else { | |
| 408 | + $combine_css .= "{$separatedCss['normal_css']} {$separatedCss['media_css']} "; | |
| 409 | + } | |
| 410 | + } | |
| 411 | + } | |
| 412 | + return $combine_css; | |
| 413 | + } | |
| 414 | + | |
| 415 | + public function footer_scripts() { | |
| 416 | + if (!empty($this->notificationXArr['total']) && $this->notificationXArr['total'] > 0) { | |
| 417 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 418 | + $this->notificationXArr = apply_filters('nx_frontend_localize_data', $this->notificationXArr); | |
| 419 | + ?> | |
| 420 | + <script data-no-optimize="1"> | |
| 421 | + (function() { | |
| 422 | + window.notificationXArr = window.notificationXArr || []; | |
| 423 | + window.notificationXArr.push(<?php echo json_encode($this->notificationXArr); ?>); | |
| 424 | + })(); | |
| 425 | + </script> | |
| 426 | + <?php | |
| 427 | + } | |
| 428 | + } | |
| 429 | + | |
| 430 | + // @todo deprecated. use get_localize_data instead | |
| 431 | + public function localizeScripts() { | |
| 432 | + return []; | |
| 433 | + } | |
| 434 | + | |
| 435 | + /** | |
| 436 | + * The URL WordPress prints for a registered stylesheet. | |
| 437 | + * | |
| 438 | + * @param string $handle Style handle. | |
| 439 | + * @return string Empty when the handle has no source. | |
| 440 | + */ | |
| 441 | + protected function style_url($handle) { | |
| 442 | + $style = wp_styles()->query($handle, 'registered'); | |
| 443 | + if (!$style || empty($style->src) || !is_string($style->src)) { | |
| 444 | + return ''; | |
| 445 | + } | |
| 446 | + $src = $style->src; | |
| 447 | + // Same version rule as WP_Styles::_css_href(). | |
| 448 | + $ver = null === $style->ver ? '' : ($style->ver ? $style->ver : get_bloginfo('version')); | |
| 449 | + if ('' !== $ver) { | |
| 450 | + $src = add_query_arg('ver', $ver, $src); | |
| 451 | + } | |
| 452 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Core filter, so CDN rewrites apply. | |
| 453 | + return (string) apply_filters('style_loader_src', $src, $handle); | |
| 454 | + } | |
| 455 | + | |
| 456 | + public function get_localize_data($data) { | |
| 457 | + $data['rest'] = REST::get_instance()->rest_data(false); | |
| 458 | + $data['assets'] = self::ASSET_URL; | |
| 459 | + if (empty($data['cross'])) { | |
| 460 | + // The runtime re-adds these if an optimizer combined them into a | |
| 461 | + // bundle that does not apply (e.g. a print-only one). | |
| 462 | + $styles = []; | |
| 463 | + foreach (['notificationx-public', 'notificationx-gdpr-modal'] as $handle) { | |
| 464 | + if (wp_style_is($handle, 'enqueued') || wp_style_is($handle, 'done')) { | |
| 465 | + $url = $this->style_url($handle); | |
| 466 | + if ($url) { | |
| 467 | + $styles[$handle] = $url; | |
| 468 | + } | |
| 469 | + } | |
| 470 | + } | |
| 471 | + if ($styles) { | |
| 472 | + $data['styles'] = $styles; | |
| 473 | + } | |
| 474 | + } | |
| 475 | + $data['is_pro'] = false; | |
| 476 | + $data['gmt_offset'] = get_option('gmt_offset'); | |
| 477 | + $data['lang'] = get_locale(); | |
| 478 | + $data['common_assets'] = NOTIFICATIONX_COMMON_URL; | |
| 479 | + $data['extra'] = [ | |
| 480 | + 'is_singular' => is_singular(), | |
| 481 | + 'query' => $GLOBALS['wp_query']->query, | |
| 482 | + 'queried_id' => get_queried_object_id(), | |
| 483 | + 'pid' => !empty($GLOBALS['post']->ID) ? $GLOBALS['post']->ID : 0, | |
| 484 | + ]; | |
| 485 | + $data['localeData'] = load_script_textdomain('notificationx-public', 'notificationx'); | |
| 486 | + if (!empty($data['cross'])) { | |
| 487 | + // Cross-domain embeds have no WordPress enqueue: the runtime adds these. | |
| 488 | + $data['external_styles'] = $this->get_external_styles(); | |
| 489 | + } | |
| 490 | + return $data; | |
| 491 | + } | |
| 492 | + | |
| 493 | + public function get_notifications_data($params) { | |
| 494 | + $_params = $params; | |
| 495 | + $result = [ | |
| 496 | + 'global' => [], | |
| 497 | + 'active' => [], | |
| 498 | + 'pressbar' => [], | |
| 499 | + 'gdpr' => [], | |
| 500 | + 'shortcode' => [], | |
| 501 | + 'popup' => [], | |
| 502 | + 'exit_intent' => [], | |
| 503 | + ]; | |
| 504 | + if (!empty($_params['all_active'])) { | |
| 505 | + $params = $this->get_notifications_ids(); | |
| 506 | + } | |
| 507 | + $params = wp_parse_args( | |
| 508 | + $params, | |
| 509 | + [ | |
| 510 | + 'global' => [], | |
| 511 | + 'active' => [], | |
| 512 | + 'pressbar' => [], | |
| 513 | + 'gdpr' => [], | |
| 514 | + 'popup' => [], | |
| 515 | + 'exit_intent' => [], | |
| 516 | + 'shortcode' => [], | |
| 517 | + 'inline_shortcode' => false, | |
| 518 | + ] | |
| 519 | + ); | |
| 520 | + // These come straight from the public REST `notice` request, where | |
| 521 | + // `?global=1` arrives as a string; the code below needs ID lists. | |
| 522 | + foreach (['global', 'active', 'pressbar', 'gdpr', 'popup', 'exit_intent', 'shortcode'] as $list_key) { | |
| 523 | + $params[$list_key] = NotificationX::get_instance()->normalize_multiple_value($params[$list_key]); | |
| 524 | + } | |
| 525 | + $global = $params['global']; | |
| 526 | + $active = $params['active']; | |
| 527 | + $pressbar = $params['pressbar']; | |
| 528 | + $gdpr = $params['gdpr']; | |
| 529 | + $popup = $params['popup']; | |
| 530 | + $exit_intent = $params['exit_intent']; | |
| 531 | + $shortcode = $params['shortcode']; | |
| 532 | + $all = array_merge($global, $active, $shortcode); | |
| 533 | + $_defaults = array( | |
| 534 | + 'none' => '', | |
| 535 | + 'name' => __('Someone', 'notificationx'), | |
| 536 | + 'first_name' => __('Someone', 'notificationx'), | |
| 537 | + 'last_name' => __('Someone', 'notificationx'), | |
| 538 | + 'anonymous_title' => __('Anonymous Title', 'notificationx'), | |
| 539 | + 'sometime' => __('Some time ago', 'notificationx'), | |
| 540 | + ); | |
| 541 | + | |
| 542 | + // foreach (['global', 'active'] as $key => $type) { | |
| 543 | + // foreach ($params[$type] as $id) { | |
| 544 | + // $result[$type][$id] = []; | |
| 545 | + // } | |
| 546 | + // } | |
| 547 | + | |
| 548 | + $device = isset($params['deviceType']) && !empty($params['deviceType']) ? $params['deviceType'] : ''; | |
| 549 | + if (!empty($all)) { | |
| 550 | + $notifications = $this->get_notifications($all, $device); | |
| 551 | + $entries = $this->get_entries($all, $notifications, $params); | |
| 552 | + | |
| 553 | + foreach ($entries as $entry) { | |
| 554 | + $nx_id = $entry['nx_id']; | |
| 555 | + $settings = $notifications[$nx_id]; | |
| 556 | + | |
| 557 | + // check if notification is enabled or not. | |
| 558 | + if (!$settings['enabled']) { | |
| 559 | + continue; | |
| 560 | + } | |
| 561 | + | |
| 562 | + $type = $settings['type']; | |
| 563 | + $source = $settings['source']; | |
| 564 | + | |
| 565 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 566 | + $should_continue = apply_filters("nx_entry_show_on_frontend_$source", false, $entry, $settings); | |
| 567 | + if ( $should_continue ) { | |
| 568 | + continue; | |
| 569 | + } | |
| 570 | + | |
| 571 | + if (!empty($entry['timestamp'])) { | |
| 572 | + $timestamp = $entry['timestamp']; | |
| 573 | + $display_from = !empty($settings['display_from']) ? $settings['display_from'] : 2; | |
| 574 | + $display_from = Helper::generate_time_string($settings); | |
| 575 | + if (!is_numeric($timestamp)) { | |
| 576 | + $entry['timestamp'] = $timestamp = is_string($timestamp) ? strtotime($timestamp) : false; | |
| 577 | + } | |
| 578 | + if ($timestamp && $display_from > $timestamp) { | |
| 579 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 580 | + if (apply_filters("nx_entry_display_$source", true, $entry, $settings)) { | |
| 581 | + continue; | |
| 582 | + } | |
| 583 | + } | |
| 584 | + } | |
| 585 | + | |
| 586 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 587 | + $defaults = apply_filters("nx_fallback_data_$source", $_defaults, $entry, $settings); | |
| 588 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 589 | + $defaults = apply_filters('nx_fallback_data', $defaults, $entry, $settings); | |
| 590 | + | |
| 591 | + $entry = $this->apply_defaults($entry, $defaults); | |
| 592 | + $entry['image_data'] = $this->get_image_url($entry, $settings); | |
| 593 | + if (!empty($entry['title'])) { | |
| 594 | + $entry['title'] = wp_strip_all_tags(html_entity_decode($entry['title'])); | |
| 595 | + } | |
| 596 | + | |
| 597 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 598 | + $entry = apply_filters("nx_filtered_entry_$type", $entry, $settings); | |
| 599 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 600 | + $entry = apply_filters("nx_filtered_entry_$source", $entry, $settings); | |
| 601 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 602 | + $entry = apply_filters('nx_filtered_entry', $entry, $settings); | |
| 603 | + $entry = $this->link_url($entry, $settings, $params); | |
| 604 | + | |
| 605 | + // @todo shortcode | |
| 606 | + // @todo check if the current page have shortcode. | |
| 607 | + if (in_array($nx_id, $shortcode)) { | |
| 608 | + $position = $settings['position']; | |
| 609 | + $settings['position'] = "notificationx-shortcode-$nx_id"; | |
| 610 | + if (empty($result['shortcode'][$nx_id]['post'])) { | |
| 611 | + $result['shortcode'][$nx_id]['post'] = $settings; | |
| 612 | + } | |
| 613 | + $result['shortcode'][$nx_id]['entries'][] = $entry; | |
| 614 | + $settings['position'] = $position; | |
| 615 | + if ($settings['show_on'] === 'only_shortcode' || 'inline' === $settings['type'] || 'woocommerce_sales_inline' == $settings['source']) { | |
| 616 | + continue; | |
| 617 | + } | |
| 618 | + if (empty($global) && empty($active)) { | |
| 619 | + continue; | |
| 620 | + } | |
| 621 | + } | |
| 622 | + | |
| 623 | + if (!empty($settings['global_queue'])) { | |
| 624 | + if (empty($result['global'][$nx_id]['post'])) { | |
| 625 | + $result['global'][$nx_id]['post'] = $settings; | |
| 626 | + } | |
| 627 | + $result['global'][$nx_id]['entries'][] = $entry; | |
| 628 | + } else { | |
| 629 | + if (empty($result['active'][$nx_id]['post'])) { | |
| 630 | + $result['active'][$nx_id]['post'] = $settings; | |
| 631 | + } | |
| 632 | + $result['active'][$nx_id]['entries'][] = $entry; | |
| 633 | + } | |
| 634 | + } | |
| 635 | + | |
| 636 | + foreach ($result as &$group) { | |
| 637 | + foreach ($group as &$value) { | |
| 638 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 639 | + $value['entries'] = apply_filters("nx_filtered_data_{$value['post']['type']}", $value['entries'], $value['post'], $params); | |
| 640 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 641 | + $value['entries'] = apply_filters("nx_filtered_data_{$value['post']['source']}", $value['entries'], $value['post'], $params); | |
| 642 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 643 | + $value['entries'] = apply_filters('nx_filtered_data', $value['entries'], $value['post'], $params); | |
| 644 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 645 | + $value['post'] = apply_filters('nx_filtered_post', $value['post'], $params); | |
| 646 | + } | |
| 647 | + } | |
| 648 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 649 | + $result = apply_filters('nx_filtered_notice', $result, $params); | |
| 650 | + } | |
| 651 | + | |
| 652 | + if (!empty($pressbar)) { | |
| 653 | + $notifications = $this->get_notifications($pressbar, $device); | |
| 654 | + foreach ($notifications as $key => $settings) { | |
| 655 | + $_nx_id = $settings['nx_id']; | |
| 656 | + // check if position is bottom_left then modify it to top | |
| 657 | + if($settings['position'] == 'bottom_left'){ | |
| 658 | + $settings['position'] = 'top'; | |
| 659 | + } | |
| 660 | + $elementor_post_id = isset($settings['elementor_id']) ? $settings['elementor_id'] : ''; | |
| 661 | + if ($elementor_post_id == '' || get_post_status($elementor_post_id) !== 'publish' | !class_exists('\Elementor\Plugin')) { | |
| 662 | + $settings['elementor_id'] = false; | |
| 663 | + } | |
| 664 | + if ( ( !empty( $_params['all_active']) && $elementor_post_id ) || !$settings['enabled'] ) { | |
| 665 | + continue; | |
| 666 | + } | |
| 667 | + | |
| 668 | + // $settings['button_url'] = apply_filters("nx_notification_link_{$settings['source']}", $settings['button_url'], $settings); | |
| 669 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 670 | + $settings['button_url'] = apply_filters('nx_notification_link', $settings['button_url'], $settings); | |
| 671 | + if (!empty($settings['button_url']) && strpos($settings['button_url'], '//') === false && strpos($settings['button_url'], './') === false) { | |
| 672 | + $settings['button_url'] = "//{$settings['button_url']}"; | |
| 673 | + } | |
| 674 | + $bar_content = $this->get_bar_content($settings, false, $params); | |
| 675 | + if ($bar_content !== ' ' || !empty($settings['enable_countdown'])) { | |
| 676 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 677 | + $settings = apply_filters('nx_filtered_post', $settings, $params); | |
| 678 | + $result['pressbar'][$_nx_id]['post'] = $settings; | |
| 679 | + $result['pressbar'][$_nx_id]['content'] = $bar_content; | |
| 680 | + } | |
| 681 | + | |
| 682 | + unset($_nx_id); | |
| 683 | + } | |
| 684 | + } | |
| 685 | + | |
| 686 | + if (!empty($gdpr)) { | |
| 687 | + $notifications = $this->get_notifications($gdpr); | |
| 688 | + foreach ($notifications as $key => $settings) { | |
| 689 | + $_nx_id = $settings['nx_id']; | |
| 690 | + if (!empty($_params['all_active'])) { | |
| 691 | + continue; | |
| 692 | + } | |
| 693 | + | |
| 694 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 695 | + $settings = apply_filters('nx_filtered_post', $settings, $params); | |
| 696 | + | |
| 697 | + $result['gdpr'][$_nx_id]['post'] = $settings; | |
| 698 | + $result['gdpr'][$_nx_id]['content'] = ""; | |
| 699 | + unset($_nx_id); | |
| 700 | + } | |
| 701 | + } | |
| 702 | + | |
| 703 | + // Popup Notification | |
| 704 | + if (!empty($popup)) { | |
| 705 | + $popup_notifications = $this->get_notifications($popup); | |
| 706 | + foreach ($popup_notifications as $key => $settings) { | |
| 707 | + $_nx_id = $settings['nx_id']; | |
| 708 | + if ( !$settings['enabled'] ) { | |
| 709 | + continue; | |
| 710 | + } | |
| 711 | + | |
| 712 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 713 | + $settings = apply_filters('nx_filtered_post', $settings, $params); | |
| 714 | + | |
| 715 | + $result['popup'][$_nx_id]['post'] = $settings; | |
| 716 | + $result['popup'][$_nx_id]['content'] = ""; | |
| 717 | + unset($_nx_id); | |
| 718 | + } | |
| 719 | + } | |
| 720 | + | |
| 721 | + // Exit Intent Notification | |
| 722 | + if (!empty($exit_intent)) { | |
| 723 | + $exit_intent_notifications = $this->get_notifications($exit_intent); | |
| 724 | + foreach ($exit_intent_notifications as $key => $settings) { | |
| 725 | + $_nx_id = $settings['nx_id']; | |
| 726 | + if ( !$settings['enabled'] ) { | |
| 727 | + continue; | |
| 728 | + } | |
| 729 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 730 | + $settings = apply_filters('nx_filtered_post', $settings, $params); | |
| 731 | + $result['exit_intent'][$_nx_id]['post'] = $settings; | |
| 732 | + $result['exit_intent'][$_nx_id]['content'] = ""; | |
| 733 | + unset($_nx_id); | |
| 734 | + } | |
| 735 | + } | |
| 736 | + | |
| 737 | + $result['settings'] = $this->get_settings(); | |
| 738 | + return $result; | |
| 739 | + } | |
| 740 | + | |
| 741 | + public function get_settings(){ | |
| 742 | + | |
| 743 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 744 | + $branding_url = apply_filters('nx_branding_url', NOTIFICATIONX_PLUGIN_URL . '?utm_source=' . esc_url(home_url()) . '&utm_medium=notificationx'); | |
| 745 | + $settings = [ | |
| 746 | + 'disable_powered_by' => Settings::get_instance()->get('settings.disable_powered_by'), | |
| 747 | + 'affiliate_link' => $branding_url, | |
| 748 | + 'enable_analytics' => Settings::get_instance()->get('settings.enable_analytics', true), | |
| 749 | + 'analytics_from' => Settings::get_instance()->get('settings.analytics_from'), | |
| 750 | + 'delay_before' => Settings::get_instance()->get('settings.delay_before', 5), | |
| 751 | + 'display_for' => Settings::get_instance()->get('settings.display_for', 5), | |
| 752 | + 'delay_between' => Settings::get_instance()->get('settings.delay_between', 5), | |
| 753 | + 'loop' => Settings::get_instance()->get('settings.loop', 5), | |
| 754 | + 'random' => Settings::get_instance()->get('settings.random', 5), | |
| 755 | + 'analytics_nonce' => wp_create_nonce('analytics_nonce'), | |
| 756 | + ]; | |
| 757 | + return $settings; | |
| 758 | + } | |
| 759 | + | |
| 760 | + public function get_notifications_ids($return_posts = false, $args = []) { | |
| 761 | + $args = wp_parse_args($args, [ | |
| 762 | + 'enabled' => true, | |
| 763 | + 'updated_at' => ['<=', Helper::mysql_time()], | |
| 764 | + // 'global_queue' => true, | |
| 765 | + ]); | |
| 766 | + $notifications = PostType::get_instance()->get_posts($args); | |
| 767 | + | |
| 768 | + $active_notifications = $global_notifications = $bar_notifications = $gdpr_notification = $popup_notifications = $exit_intent_notifications = array(); | |
| 769 | + | |
| 770 | + foreach ($notifications as $key => $settings) { | |
| 771 | + // $settings = NotificationX::get_instance()->normalize_post($post); | |
| 772 | + | |
| 773 | + // IF PRESSBAR TIME RE_CONFIG THEN REMOVE COOKIE | |
| 774 | + // if( $settings['source'] == 'press_bar'){ | |
| 775 | + // if( $_settings->enable_countdown && ( Helper::current_timestamp($_settings->countdown_start_date) < time() || Helper::current_timestamp($_settings->countdown_end_date) > time() ) ) { | |
| 776 | + // unset( $_COOKIE["notificationx_{$settings['nx_id']}"] ); | |
| 777 | + // \setcookie("notificationx_{$settings['nx_id']}", null); | |
| 778 | + // } | |
| 779 | + // } | |
| 780 | + | |
| 781 | + /** | |
| 782 | + * Check if it's a pro source and pro plugin is disabled. | |
| 783 | + */ | |
| 784 | + if(!NotificationX::is_pro()){ | |
| 785 | + $ext = ExtensionFactory::get_instance()->get($settings['source']); | |
| 786 | + if($ext && $ext->is_pro){ | |
| 787 | + continue; | |
| 788 | + } | |
| 789 | + } | |
| 790 | + | |
| 791 | + $countdown_rand = !empty($settings['countdown_rand']) ? "-{$settings['countdown_rand']}" : ''; | |
| 792 | + | |
| 793 | + if (!empty($_COOKIE["notificationx_{$settings['nx_id']}$countdown_rand"]) && $_COOKIE["notificationx_{$settings['nx_id']}$countdown_rand"] == true) { | |
| 794 | + unset($notifications[$key]); | |
| 795 | + continue; | |
| 796 | + } | |
| 797 | + | |
| 798 | + if($this->is_logged_in($settings['show_on_display'])){ | |
| 799 | + continue; | |
| 800 | + } | |
| 801 | + | |
| 802 | + $locations = isset($settings['all_locations']) ? $settings['all_locations'] : []; | |
| 803 | + $custom_ids = isset($settings['custom_ids']) ? $settings['custom_ids'] : []; | |
| 804 | + $taxonomy_ids = isset($settings['taxonomy_ids']) ? $settings['taxonomy_ids'] : []; | |
| 805 | + | |
| 806 | + if($this->check_show_on($locations, $custom_ids, $settings['show_on'], $taxonomy_ids)){ | |
| 807 | + continue; | |
| 808 | + } | |
| 809 | + | |
| 810 | + /** | |
| 811 | + * Check for hiding in mobile device | |
| 812 | + */ | |
| 813 | + // if ($settings['hide_on_mobile'] && wp_is_mobile()) { | |
| 814 | + // continue; | |
| 815 | + // } | |
| 816 | + | |
| 817 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 818 | + $show_on_exclude = apply_filters('nx_show_on_exclude', false, $settings); | |
| 819 | + if ($show_on_exclude) { | |
| 820 | + continue; | |
| 821 | + } | |
| 822 | + | |
| 823 | + // excluding pressBar on rest request. PressBar is printed directly in head. | |
| 824 | + // if((empty($args['source']) || $args['source'] !== 'press_bar') && $settings['source'] == 'press_bar'){ | |
| 825 | + // continue; | |
| 826 | + // } | |
| 827 | + | |
| 828 | + $active_global_queue = boolval($settings['global_queue']); | |
| 829 | + if ($settings['source'] == 'press_bar') { | |
| 830 | + // if( | |
| 831 | + // !$_settings->elementor_id && | |
| 832 | + // $_settings->enable_countdown && | |
| 833 | + // !$_settings->evergreen_timer && | |
| 834 | + // ( | |
| 835 | + // strtotime($_settings->countdown_start_date) > time() || | |
| 836 | + // strtotime($_settings->countdown_end_date) < time() | |
| 837 | + // ) | |
| 838 | + // ){ | |
| 839 | + // continue; | |
| 840 | + // } | |
| 841 | + | |
| 842 | + $bar_notifications[] = $return_posts ? $settings : $settings['nx_id']; | |
| 843 | + if (!empty($settings['elementor_id']) && class_exists('\Elementor\Plugin')) { | |
| 844 | + // @todo Find a function to only load css instead of building content. | |
| 845 | + \Elementor\Plugin::$instance->frontend->get_builder_content($settings['elementor_id'], false); | |
| 846 | + } elseif (!empty($settings['gutenberg_id'])) { | |
| 847 | + $this->enqueue_gutenberg_bar_assets($settings['gutenberg_id']); | |
| 848 | + } | |
| 849 | + } elseif($settings['source'] == 'gdpr_notification') { | |
| 850 | + $gdpr_notification[] = $return_posts ? $settings : $settings['nx_id']; | |
| 851 | + } elseif($settings['source'] == 'popup_notification') { | |
| 852 | + $popup_notifications[] = $settings['nx_id']; | |
| 853 | + } elseif($settings['source'] == 'exit_intent_custom') { | |
| 854 | + $exit_intent_notifications[] = $settings['nx_id']; | |
| 855 | + // Force Elementor's frontend runtime + per-widget assets onto the | |
| 856 | + // page (elementor-frontend.js, the document CSS, and each widget's | |
| 857 | + // get_style_depends()/get_script_depends() — e.g. nx-countdown). | |
| 858 | + // The popup HTML itself is rendered later via REST, where these | |
| 859 | + // enqueues would be discarded, so the countdown widget would lose | |
| 860 | + // its layout CSS and timer JS. Mirrors the press_bar branch above. | |
| 861 | + if (!empty($settings['elementor_id']) && class_exists('\Elementor\Plugin')) { | |
| 862 | + \Elementor\Plugin::$instance->frontend->get_builder_content($settings['elementor_id'], false); | |
| 863 | + } | |
| 864 | + } elseif ($active_global_queue && NotificationX::is_pro()) { | |
| 865 | + $global_notifications[] = $return_posts ? $settings : $settings['nx_id']; | |
| 866 | + } else { | |
| 867 | + $active_notifications[] = $return_posts ? $settings : $settings['nx_id']; | |
| 868 | + } | |
| 869 | + | |
| 870 | + unset($notifications[$key]); | |
| 871 | + } | |
| 872 | + // do_action('nx_active_notificationx', $notifications); | |
| 873 | + | |
| 874 | + // @todo maybe combine two hooks. | |
| 875 | + | |
| 876 | + return apply_filters( | |
| 877 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 878 | + 'get_notifications_ids', | |
| 879 | + [ | |
| 880 | + 'global' => $global_notifications, | |
| 881 | + 'active' => $active_notifications, | |
| 882 | + 'pressbar' => $bar_notifications, | |
| 883 | + 'gdpr' => $gdpr_notification, | |
| 884 | + 'popup' => $popup_notifications, | |
| 885 | + 'exit_intent' => $exit_intent_notifications, | |
| 886 | + 'total' => (count($global_notifications) + count($active_notifications) + count($bar_notifications) + count($gdpr_notification) + count($popup_notifications) + count($exit_intent_notifications)), | |
| 887 | + ], | |
| 888 | + $notifications | |
| 889 | + ); | |
| 890 | + } | |
| 891 | + | |
| 892 | + public function is_logged_in($show_on_display){ | |
| 893 | + $logged_in = is_user_logged_in(); | |
| 894 | + | |
| 895 | + if (($logged_in && 'logged_out_user' == $show_on_display) || (!$logged_in && 'logged_in_user' == $show_on_display)) { | |
| 896 | + return true; | |
| 897 | + } | |
| 898 | + return false; | |
| 899 | + } | |
| 900 | + | |
| 901 | + /** | |
| 902 | + * @todo filter is not extensive enough. | |
| 903 | + */ | |
| 904 | + public function check_show_on($locations, $custom_ids, $show_on, $taxonomy_ids = ''){ | |
| 905 | + $check_location = false; | |
| 906 | + | |
| 907 | + if ($locations == 'is_custom' || is_array($locations) && in_array('is_custom', $locations)) { | |
| 908 | + $custom_ids = !empty($custom_ids) ? $custom_ids : []; | |
| 909 | + } | |
| 910 | + if (!empty($locations)) { | |
| 911 | + // @todo need to pass url. | |
| 912 | + $check_location = Locations::get_instance()->check_location($locations, $custom_ids, $taxonomy_ids); | |
| 913 | + } | |
| 914 | + | |
| 915 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 916 | + $check_location = apply_filters('nx_check_location', $check_location, $custom_ids, $show_on); | |
| 917 | + | |
| 918 | + if ($show_on == 'on_selected') { | |
| 919 | + // show if the page is on selected | |
| 920 | + if (!$check_location) { | |
| 921 | + return true; | |
| 922 | + } | |
| 923 | + } elseif ($show_on == 'hide_on_selected') { | |
| 924 | + // hide if the page is on selected | |
| 925 | + if ($check_location) { | |
| 926 | + return true; | |
| 927 | + } | |
| 928 | + } elseif ($show_on === 'only_shortcode') { | |
| 929 | + return true; | |
| 930 | + } | |
| 931 | + return false; | |
| 932 | + } | |
| 933 | + | |
| 934 | + public function get_notifications($ids, $device = '') { | |
| 935 | + $results = []; | |
| 936 | + $notifications = PostType::get_instance()->get_posts_by_ids($ids); | |
| 937 | + | |
| 938 | + foreach ($notifications as $key => $value) { | |
| 939 | + /** | |
| 940 | + * Check for hiding in mobile device | |
| 941 | + */ | |
| 942 | + if (empty($value['hide_on_mobile']) && $device === 'mobile') { | |
| 943 | + continue; | |
| 944 | + } | |
| 945 | + | |
| 946 | + /** | |
| 947 | + * Check for hiding in tablet device | |
| 948 | + */ | |
| 949 | + if (empty($value['hide_on_tab']) && $device === 'tablet') { | |
| 950 | + continue; | |
| 951 | + } | |
| 952 | + | |
| 953 | + /** | |
| 954 | + * Check for hiding in desktop device | |
| 955 | + */ | |
| 956 | + if (empty($value['hide_on_desktop']) && $device === 'desktop') { | |
| 957 | + continue; | |
| 958 | + } | |
| 959 | + | |
| 960 | + /** | |
| 961 | + * Check if it's a pro source and pro plugin is disabled. | |
| 962 | + */ | |
| 963 | + if(!NotificationX::is_pro()){ | |
| 964 | + $ext = ExtensionFactory::get_instance()->get($value['source']); | |
| 965 | + if($ext && $ext->is_pro){ | |
| 966 | + continue; | |
| 967 | + } | |
| 968 | + } | |
| 969 | + | |
| 970 | + $results[$value['nx_id']] = $value; | |
| 971 | + } | |
| 972 | + return $results; | |
| 973 | + } | |
| 974 | + | |
| 975 | + public function get_entries($ids, $notifications,$params) { | |
| 976 | + $entries = []; | |
| 977 | + if (!empty($ids) && is_array($ids)) { | |
| 978 | + $query = []; | |
| 979 | + foreach ($ids as $id) { | |
| 980 | + if (!empty($notifications[$id])) { | |
| 981 | + $post = $notifications[$id]; | |
| 982 | + $global_query = " nx_id = " . absint($id) . " AND source = '" . esc_sql($post['source']) . "'"; | |
| 983 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 984 | + $_q = apply_filters("nx_get_entries_query_part_{$notifications[$id]['source']}",$global_query, $notifications[$id], $params ); | |
| 985 | + $query[$id] = " (" . $_q . ")"; | |
| 986 | + } | |
| 987 | + } | |
| 988 | + if (!empty($query)) { | |
| 989 | + $entries = Entries::get_instance()->get_entries('WHERE' . implode(' OR ', $query)); | |
| 990 | + foreach ($entries as $key => $value) { | |
| 991 | + if (!empty($value['data'])) { | |
| 992 | + $entries[$key] = array_merge($value, $value['data']); | |
| 993 | + unset($entries[$key]['data']); | |
| 994 | + } | |
| 995 | + } | |
| 996 | + } | |
| 997 | + } | |
| 998 | + if (!is_array($entries)) { | |
| 999 | + $entries = []; | |
| 1000 | + } | |
| 1001 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 1002 | + $entries = apply_filters('nx_frontend_get_entries', $entries, $ids, $notifications,$params); | |
| 1003 | + return $entries; | |
| 1004 | + } | |
| 1005 | + | |
| 1006 | + /** | |
| 1007 | + * This function is responsible for make ready the link for notifications. | |
| 1008 | + * | |
| 1009 | + * @param array $data | |
| 1010 | + * @return void | |
| 1011 | + */ | |
| 1012 | + public static function link_url($entry, $post, $params = []) { | |
| 1013 | + if (empty($entry)) { | |
| 1014 | + return false; | |
| 1015 | + } | |
| 1016 | + $link = isset($entry['link']) ? $entry['link'] : ''; | |
| 1017 | + // removing link if link type is none. | |
| 1018 | + if (empty($post['link_type']) || $post['link_type'] === 'none') { | |
| 1019 | + $link = ''; | |
| 1020 | + } | |
| 1021 | + | |
| 1022 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 1023 | + $link = apply_filters("nx_notification_link_{$post['source']}", $link, $post, $entry, $params); | |
| 1024 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 1025 | + $entry['link'] = apply_filters('nx_notification_link', $link, $post, $entry, $params); | |
| 1026 | + return $entry; | |
| 1027 | + } | |
| 1028 | + | |
| 1029 | + /** | |
| 1030 | + * This function is responsible for getting the image url | |
| 1031 | + * using Product ID or from default image settings. | |
| 1032 | + * | |
| 1033 | + * @param array $data | |
| 1034 | + * @param array $settings | |
| 1035 | + * @return array of image data, contains url and title as alt text | |
| 1036 | + */ | |
| 1037 | + public function get_image_url($data, $settings) { | |
| 1038 | + $source = $settings['source']; | |
| 1039 | + $alt_title = isset($data['name']) ? $data['name'] : ''; | |
| 1040 | + $image_type = isset($settings['show_notification_image']) ? $settings['show_notification_image'] : false; | |
| 1041 | + if (empty($alt_title)) { | |
| 1042 | + $alt_title = isset($data['title']) ? $data['title'] : ''; | |
| 1043 | + } | |
| 1044 | + $image_data = [ | |
| 1045 | + 'url' => '', | |
| 1046 | + 'alt' => $alt_title, | |
| 1047 | + ]; | |
| 1048 | + | |
| 1049 | + if ($settings['show_default_image']) { | |
| 1050 | + if (!empty($settings['image_url']['url'])) { | |
| 1051 | + $image_size = (string) Settings::get_instance()->get('settings.notification_image_size', '100_100'); | |
| 1052 | + $image_size = explode('_', $image_size); | |
| 1053 | + $width = 100; | |
| 1054 | + $height = 100; | |
| 1055 | + if( !empty( $image_size[0] ) && !empty( $image_size[1] ) ) { | |
| 1056 | + $width = $image_size[0]; | |
| 1057 | + $height = $image_size[1]; | |
| 1058 | + } | |
| 1059 | + $image = wp_get_attachment_image_src($settings['image_url']['id'], [$width, $height], true); | |
| 1060 | + $image_data['url'] = $image[0]; | |
| 1061 | + } else { | |
| 1062 | + $default_avatar = $settings['default_avatar']; | |
| 1063 | + $image_data['url'] = NOTIFICATIONX_PUBLIC_URL . 'image/icons/' . $default_avatar; | |
| 1064 | + } | |
| 1065 | + } else { | |
| 1066 | + if ($image_type === 'gravatar') { | |
| 1067 | + $_data = array_change_key_case($data); | |
| 1068 | + if (isset($_data['email'])) { | |
| 1069 | + $image_data['url'] = get_avatar_url($_data['email'], ['size' => '100']); | |
| 1070 | + } | |
| 1071 | + } | |
| 1072 | + } | |
| 1073 | + | |
| 1074 | + $image_data['classes'] = $image_type; | |
| 1075 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 1076 | + $image_data = apply_filters("nx_notification_image_$source", $image_data, $data, $settings); | |
| 1077 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 1078 | + $image_data = apply_filters('nx_notification_image', $image_data, $data, $settings); | |
| 1079 | + | |
| 1080 | + if (!empty($image_data['url'])) { | |
| 1081 | + return $image_data; | |
| 1082 | + } | |
| 1083 | + | |
| 1084 | + return false; | |
| 1085 | + } | |
| 1086 | + | |
| 1087 | + public function apply_defaults($entry, $defaults) { | |
| 1088 | + | |
| 1089 | + foreach ($defaults as $key => $value) { | |
| 1090 | + // @todo mukul remove `|| empty(trim($entry[$key]))` | |
| 1091 | + if (empty($entry[$key]) || (is_string($entry[$key]) && empty(trim($entry[$key])))) { | |
| 1092 | + $entry[$key] = $value; | |
| 1093 | + } | |
| 1094 | + } | |
| 1095 | + | |
| 1096 | + return $entry; | |
| 1097 | + } | |
| 1098 | + | |
| 1099 | + public function fallback_data($data, $saved_data, $settings) { | |
| 1100 | + if ((empty($saved_data['name']) || $data['name'] == __('Someone', 'notificationx')) && isset($saved_data['first_name']) || isset($saved_data['last_name'])) { | |
| 1101 | + $first_name = isset($saved_data['first_name']) ? $saved_data['first_name'] : ''; | |
| 1102 | + $last_name = isset($saved_data['last_name']) ? $saved_data['last_name'] : ''; | |
| 1103 | + $data['name'] = Helper::name($first_name, $last_name); | |
| 1104 | + } | |
| 1105 | + if (!empty($saved_data['name']) && empty($saved_data['first_name']) && empty($saved_data['last_name'])) { | |
| 1106 | + $data['first_name'] = $saved_data['name']; | |
| 1107 | + } | |
| 1108 | + $data['title'] = isset($saved_data['post_title']) ? $saved_data['post_title'] : (isset($data['title']) ? $data['title'] : ''); | |
| 1109 | + return $data; | |
| 1110 | + } | |
| 1111 | + | |
| 1112 | + /** | |
| 1113 | + * Add NotificationX in Footer | |
| 1114 | + * | |
| 1115 | + * @return void | |
| 1116 | + */ | |
| 1117 | + public function filtered_data($entries, $post, $params) { | |
| 1118 | + if (is_array($entries) && (!defined('NX_DEBUG') || !NX_DEBUG)) { | |
| 1119 | + if (!empty($post['display_last']) && !in_array($post['source'], ['google', 'woo_inline', 'edd_inline', 'tutor_inline', 'learndash_inline', 'google_reviews', 'youtube','woocommerce_sales_inline','fluentcart_inline'])) { | |
| 1120 | + $entries = array_slice($entries, 0, $post['display_last']); | |
| 1121 | + } | |
| 1122 | + foreach ($entries as $index => $entry) { | |
| 1123 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 1124 | + $_entry = apply_filters("nx_frontend_keep_entry_{$post['source']}", [ | |
| 1125 | + 'nx_id' => $entry['nx_id'], | |
| 1126 | + 'timestamp' => isset($entry['timestamp']) ? $entry['timestamp'] : Helper::current_timestamp($entry['updated_at']), | |
| 1127 | + 'updated_at' => isset( $entry['updated_at'] ) ? $entry['updated_at'] : '', | |
| 1128 | + 'image_data' => $entry['image_data'], | |
| 1129 | + 'link' => $entry['link'], | |
| 1130 | + // Location is rendered by themes (e.g. conv-theme-fifteen) via the | |
| 1131 | + // hardcoded {{city_country}} tag, not through a notification-template | |
| 1132 | + // param, so the template loop below never whitelists it. Keep the | |
| 1133 | + // raw parts here so the frontend can compose "City, Country". | |
| 1134 | + 'city' => $entry['city'] ?? '', | |
| 1135 | + 'country' => $entry['country'] ?? '', | |
| 1136 | + ], $entry, $post, $params); | |
| 1137 | + if (!empty($params['inline_shortcode']) && isset($entry['product_id'])) { | |
| 1138 | + $_entry['product_id'] = $entry['product_id']; | |
| 1139 | + } | |
| 1140 | + | |
| 1141 | + // `notification-template` can be absent for some posts (e.g. advanced- | |
| 1142 | + // template notifications or imported/migrated posts), so guard against | |
| 1143 | + // passing null to array_values() — that is a fatal TypeError on PHP 8. | |
| 1144 | + $template_arr = ( ! empty( $post['notification-template'] ) && is_array( $post['notification-template'] ) ) | |
| 1145 | + ? array_values( $post['notification-template'] ) | |
| 1146 | + : []; | |
| 1147 | + if ( ! empty( $post['template_adv'] ) ) { | |
| 1148 | + $adv_template = isset( $post['advanced_template'] ) ? $post['advanced_template'] : ''; | |
| 1149 | + $pattern = "/{{(.+?)}}/i"; | |
| 1150 | + if (preg_match_all($pattern, $adv_template, $matches)) { | |
| 1151 | + $template_arr = $matches[1]; | |
| 1152 | + } | |
| 1153 | + } | |
| 1154 | + if (is_array($template_arr)) { | |
| 1155 | + foreach ($template_arr as $entry_key) { | |
| 1156 | + $_entry_key = $entry_key; | |
| 1157 | + if ($entry_key == 'tag_siteview' || $entry_key == 'tag_realtime_siteview') { | |
| 1158 | + $entry_key = 'views'; | |
| 1159 | + } elseif ($entry_key == 'ga_title' || $entry_key == 'ga_page_title') { | |
| 1160 | + $entry_key = 'title'; | |
| 1161 | + } elseif (strpos($entry_key, 'tag_product_') === 0) { | |
| 1162 | + $entry_key = str_replace('tag_product_', '', $entry_key); | |
| 1163 | + } elseif (strpos($entry_key, 'tag_') === 0) { | |
| 1164 | + $entry_key = str_replace('tag_', '', $entry_key); | |
| 1165 | + } elseif (strpos($entry_key, 'product_') === 0) { | |
| 1166 | + $entry_key = str_replace('product_', '', $entry_key); | |
| 1167 | + } | |
| 1168 | + | |
| 1169 | + if (isset($entry[$entry_key])) { | |
| 1170 | + $_entry[$entry_key] = $entry[$entry_key]; | |
| 1171 | + } | |
| 1172 | + if (isset($entry[$_entry_key])) { | |
| 1173 | + $_entry[$_entry_key] = $entry[$_entry_key]; | |
| 1174 | + } | |
| 1175 | + } | |
| 1176 | + $entries[$index] = $_entry; | |
| 1177 | + } | |
| 1178 | + } | |
| 1179 | + } | |
| 1180 | + return $entries; | |
| 1181 | + } | |
| 1182 | + | |
| 1183 | + /** | |
| 1184 | + * Remove unnecessary props from post in frontend. | |
| 1185 | + * | |
| 1186 | + * @return void | |
| 1187 | + */ | |
| 1188 | + public function filtered_post($post, $params = null) { | |
| 1189 | + if (is_array($post) && empty($params['inline_shortcode']) && (!defined('NX_DEBUG') || !NX_DEBUG)) { | |
| 1190 | + $ignore_props = [ | |
| 1191 | + 'all_locations', | |
| 1192 | + 'category_list', | |
| 1193 | + 'combine_multiorder_display', | |
| 1194 | + 'combine_multiorder_text', | |
| 1195 | + 'content_trim_length', | |
| 1196 | + 'convertkit_form', | |
| 1197 | + 'currentTab', | |
| 1198 | + 'custom_contents', | |
| 1199 | + 'custom_ids', | |
| 1200 | + 'default_avatar', | |
| 1201 | + 'elementor_edit_link', | |
| 1202 | + 'enabled', | |
| 1203 | + 'exclude_categories', | |
| 1204 | + 'exclude_products', | |
| 1205 | + 'form_list', | |
| 1206 | + 'freemius_item_type', | |
| 1207 | + 'freemius_plugins', | |
| 1208 | + 'freemius_themes', | |
| 1209 | + 'give_form_list', | |
| 1210 | + 'give_forms_control', | |
| 1211 | + 'image_url', | |
| 1212 | + 'inline_location', | |
| 1213 | + 'is_confirmed', | |
| 1214 | + 'is_elementor', | |
| 1215 | + 'is_inline', | |
| 1216 | + 'ld_course_list', | |
| 1217 | + 'ld_product_control', | |
| 1218 | + 'activecampaign_form', | |
| 1219 | + 'brevo_list', | |
| 1220 | + 'mailchimp_list', | |
| 1221 | + 'max_stock', | |
| 1222 | + 'nx-bar_with_elementor', | |
| 1223 | + 'nx-bar_with_elementor-remove', | |
| 1224 | + 'nx-bar_with_elementor_install', | |
| 1225 | + 'order_status', | |
| 1226 | + 'press_content', | |
| 1227 | + 'preview', | |
| 1228 | + 'product_control', | |
| 1229 | + 'product_exclude_by', | |
| 1230 | + 'product_list', | |
| 1231 | + 'rest_route', | |
| 1232 | + 'show_default_image', | |
| 1233 | + 'show_notification_image', | |
| 1234 | + 'show_on', | |
| 1235 | + 'show_on_display', | |
| 1236 | + 'source_error', | |
| 1237 | + 'utm_campaign', | |
| 1238 | + 'utm_medium', | |
| 1239 | + 'utm_source', | |
| 1240 | + 'wp_reviews_product_type', | |
| 1241 | + 'wp_reviews_slug', | |
| 1242 | + 'wp_stats_product_type', | |
| 1243 | + 'wp_stats_slug', | |
| 1244 | + '_locale', | |
| 1245 | + '__product_list', | |
| 1246 | + '__form_list', | |
| 1247 | + '__ld_course_list', | |
| 1248 | + '__give_form_list', | |
| 1249 | + ]; | |
| 1250 | + foreach ($ignore_props as $prop) { | |
| 1251 | + if (isset($post[$prop])) { | |
| 1252 | + unset($post[$prop]); | |
| 1253 | + } | |
| 1254 | + } | |
| 1255 | + } | |
| 1256 | + if (isset($post['template_adv'], $post['advanced_template'])) { | |
| 1257 | + $post['advanced_template'] = do_shortcode($post['advanced_template']); | |
| 1258 | + } | |
| 1259 | + if( !empty( $post['notification-template'] ) ) { | |
| 1260 | + $post['notification-template'] = array_map( 'esc_html', $post['notification-template'] ); | |
| 1261 | + } | |
| 1262 | + return $post; | |
| 1263 | + } | |
| 1264 | + | |
| 1265 | + public function get_bar_content($settings, $suppress_filters = false, $params = []){ | |
| 1266 | + $bar_content = PressBar::get_instance()->print_bar_notice($settings); | |
| 1267 | + if(!$suppress_filters){ | |
| 1268 | + // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Reviewed for the NotificationX codebase: acceptable in this context. | |
| 1269 | + $bar_content = apply_filters("nx_filtered_data_{$settings['source']}", $bar_content, $settings, $params); | |
| 1270 | + } | |
| 1271 | + | |
| 1272 | + // checking if content is empty | |
| 1273 | + $_bar_content = str_replace(array("\r\n", "\n", "\r"), '', $bar_content); | |
| 1274 | + $_bar_content = trim(wp_strip_all_tags($_bar_content)); | |
| 1275 | + if (empty($_bar_content) && !empty($settings['enable_countdown'])) { | |
| 1276 | + $bar_content = ' '; | |
| 1277 | + } | |
| 1278 | + return $bar_content; | |
| 1279 | + } | |
| 1280 | + | |
| 1281 | +} | |