| 1 |
<?php |
| 2 |
/** |
| 3 |
* Plugin Name: Juicer |
| 4 |
* Plugin URI: https://wp.juicer.io |
| 5 |
* Description: Embed, curate & aggregate social media feeds from Instagram, Twitter, TikTok, Facebook, LinkedIn, YouTube, Slack, etc. and customize them as you like. |
| 6 |
* Version: 1.12.18 |
| 7 |
* Author: saas.group Inc. |
| 8 |
* Author URI: https://saas.group |
| 9 |
* License: GPLv2 or later |
| 10 |
*/ |
| 11 |
|
| 12 |
/* |
| 13 |
This program is free software; you can redistribute it and/or |
| 14 |
modify it under the terms of the GNU General Public License |
| 15 |
as published by the Free Software Foundation; either version 2 |
| 16 |
of the License, or (at your option) any later version. |
| 17 |
|
| 18 |
This program is distributed in the hope that it will be useful, |
| 19 |
but WITHOUT ANY WARRANTY; without even the implied warranty of |
| 20 |
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
| 21 |
GNU General Public License for more details. |
| 22 |
|
| 23 |
You should have received a copy of the GNU General Public License |
| 24 |
along with this program; if not, write to the Free Software |
| 25 |
Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. |
| 26 |
*/ |
| 27 |
|
| 28 |
define('JUICER_VERSION', '1.12.18'); |
| 29 |
|
| 30 |
class Juicer_Feed { |
| 31 |
public function render($args) { |
| 32 |
$defaults = array( |
| 33 |
'name' => 'error', |
| 34 |
); |
| 35 |
$args = wp_parse_args($args, $defaults); |
| 36 |
$name = $args['name']; |
| 37 |
|
| 38 |
// Legacy backbone feeds load embed-no-jquery.js, which still references |
| 39 |
// jQuery (the "nojquery" flag means "don't bundle it, use the page's |
| 40 |
// jQuery"). Keep jQuery enqueued so themes that don't load it on every |
| 41 |
// page still get it when the shortcode runs. Feed 2.0 doesn't need it |
| 42 |
// but enqueueing is idempotent and other plugins/themes typically load |
| 43 |
// jQuery anyway. |
| 44 |
wp_enqueue_script('jquery'); |
| 45 |
|
| 46 |
// Output <div> + <script> inline at the shortcode position rather than |
| 47 |
// enqueueing the embed script. wp_enqueue_script dedups by handle, so |
| 48 |
// two shortcodes for the same feed name collide and the second |
| 49 |
// invocation's attributes (e.g. filter=Instagram on the second segment) |
| 50 |
// are dropped. Emitting the pair adjacently makes each shortcode |
| 51 |
// self-contained and immune to handle collisions, footer placement, |
| 52 |
// and optimization plugins that reorder enqueued scripts. |
| 53 |
$map_attributes = generate_attributes($args); |
| 54 |
$attributes = join('&', $map_attributes); |
| 55 |
|
| 56 |
// Mirror args as data-* on the div so the embed JS can recover |
| 57 |
// per-instance config even if a caching plugin moves the <script> tag. |
| 58 |
$div_data_attrs = ''; |
| 59 |
foreach ($args as $key => $val) { |
| 60 |
if ($key === 'name') continue; |
| 61 |
$escaped_val = htmlspecialchars($val); |
| 62 |
if ($escaped_val === '') continue; |
| 63 |
$clean_key = str_replace('data-', '', $key); |
| 64 |
$div_data_attrs .= ' data-' . esc_attr($clean_key) . '="' . esc_attr($val) . '"'; |
| 65 |
} |
| 66 |
|
| 67 |
$script_url = '//www.juicer.io/embed/' . rawurlencode($name) |
| 68 |
. '/wp-plugin-1-12.js?nojquery=true' |
| 69 |
. ($attributes !== '' ? '&' . $attributes : ''); |
| 70 |
|
| 71 |
return sprintf( |
| 72 |
'<div class="juicer-feed" data-feed-id="%s"%s></div>' |
| 73 |
. '<script type="text/javascript" src="%s"></script>', |
| 74 |
esc_attr($name), |
| 75 |
$div_data_attrs, |
| 76 |
esc_url($script_url) |
| 77 |
); |
| 78 |
} |
| 79 |
} |
| 80 |
|
| 81 |
function generate_attributes($array) { |
| 82 |
$attrs = array(); |
| 83 |
|
| 84 |
foreach ($array as $key => $val) { |
| 85 |
if ($key == 'name') { |
| 86 |
continue; |
| 87 |
} |
| 88 |
$escaped_val = htmlspecialchars($val); |
| 89 |
if (!empty($escaped_val)) { |
| 90 |
if (strpos($key, "data-") !== false) { |
| 91 |
$escaped_key = str_replace("data-", "", $key); |
| 92 |
array_push($attrs, $escaped_key . '=' . $escaped_val); |
| 93 |
} else { |
| 94 |
array_push($attrs, $key . '=' . $escaped_val); |
| 95 |
} |
| 96 |
} |
| 97 |
} |
| 98 |
|
| 99 |
return $attrs; |
| 100 |
} |
| 101 |
|
| 102 |
function juicer_feed($args) { |
| 103 |
$feed = new Juicer_Feed(); |
| 104 |
echo $feed->render($args); |
| 105 |
} |
| 106 |
|
| 107 |
function juicer_shortcode($args) { |
| 108 |
extract(shortcode_atts(array( |
| 109 |
'name' => 'error', |
| 110 |
), $args )); |
| 111 |
|
| 112 |
$feed = new Juicer_Feed(); |
| 113 |
return $feed->render($args); |
| 114 |
} |
| 115 |
add_shortcode('juicer', 'juicer_shortcode'); |
| 116 |
|
| 117 |
|
| 118 |
function juicer_activate() { |
| 119 |
// Only set cookie if headers haven't been sent |
| 120 |
if (!headers_sent()) { |
| 121 |
setcookie('juicer_welcome', 'true', time() + 3600, '/'); // Cookie expires in 1 hour |
| 122 |
} |
| 123 |
} |
| 124 |
register_activation_hook(__FILE__, 'juicer_activate'); |
| 125 |
|
| 126 |
// Setup menu for admin section |
| 127 |
function juicer_set_admin_menu() { |
| 128 |
$hook_suffix = add_menu_page( |
| 129 |
esc_html__('Juicer', 'juicer'), |
| 130 |
esc_html__('Juicer', 'juicer'), |
| 131 |
'manage_options', |
| 132 |
'juicer-settings', |
| 133 |
'juicer_set_settings_page', |
| 134 |
'data:image/svg+xml;base64,PHN2ZyB3aWR0aD0iNjIiIGhlaWdodD0iNjQiIHZpZXdCb3g9IjAgMCA2MiA2NCIgZmlsbD0ibm9uZSIgeG1sbnM9Imh0dHA6Ly93d3cudzMub3JnLzIwMDAvc3ZnIj4KPHBhdGggZD0iTTQ4LjYwOTUgMTMuNDI4NUM1MS4wMDMzIDEzLjQyODUgNTIuOTMzOCAxMS40OTggNTIuOTMzOCA5LjEwNDIzVjYuMzI0MzJDNTIuODU2NiAzLjkzMDUxIDUxLjAwMzMgMi4wMDAwMiA0OC42MDk1IDIuMDAwMDJDNDYuMjE1NyAyLjAwMDAyIDQ0LjI4NTIgMy45MzA1MSA0NC4yODUyIDYuMzI0MzJWOS4xODE0NUM0NC4yODUyIDExLjQ5OCA0Ni4yMTU3IDEzLjQyODUgNDguNjA5NSAxMy40Mjg1WiIgZmlsbD0iIzlEQTJBNyIvPgo8cGF0aCBkPSJNNTIuODU2OSA0MS4yMjc1VjIzLjAwMzdDNTIuODU2OSAyMC44NDE1IDUwLjkyNjQgMTkuMTQyNyA0OC41MzI2IDE5LjE0MjdDNDYuMTM4OCAxOS4xNDI3IDQ0LjIwODMgMjAuOTE4OCA0NC4yMDgzIDIzLjAwMzdWMzMuNDI4M1YzNS41OTA1QzQ0LjIwODMgMzcuOTg0MyA0Mi4yNzc4IDM5LjkxNDggMzkuODg0IDM5LjkxNDhDMzcuNDkwMiAzOS45MTQ4IDM1LjYzNjkgMzcuOTg0MyAzNS41NTk3IDM1LjY2NzdWMzQuODk1NVYzNC4yMDA1SDM1LjQ4MjVDMzUuMzI4IDMyLjExNTYgMzMuNTUyIDMwLjU3MTIgMzEuNDY3MSAzMC41NzEyQzI5LjMwNDkgMzAuNTcxMiAyNy42MDYxIDMyLjExNTYgMjcuMjIgMzQuMTIzM0gyNy4xNDI4VjM0LjgxODNWMzcuNjc1NEMyNy4xNDI4IDQwLjA2OTIgMjUuMjEyMyA0MS45MjI1IDIyLjgxODUgNDEuOTIyNUMyMC40MjQ3IDQxLjkyMjUgMTguNDk0MiAzOS45OTIgMTguNDk0MiAzNy41OTgyVjMzLjM1MTFDMTMuMzk3NyAzMy4yNzM5IDEwIDM0LjQzMjIgMTAgNDEuMjI3NUMxMCA1Mi43MzMzIDE5LjU3NTIgNjEuOTk5NiAzMS40NjcxIDYxLjk5OTZDNDMuMjgxNyA2Mi4wNzY4IDUyLjg1NjkgNTIuNzMzMyA1Mi44NTY5IDQxLjIyNzVaIiBmaWxsPSIjOURBMkE3Ii8+CjxwYXRoIGQ9Ik0zMS40NjY5IDI0Ljg1N0MzMy44NjA3IDI0Ljg1NyAzNS43OTEyIDIyLjkyNjUgMzUuNzkxMiAyMC41MzI3VjE3LjY3NTVDMzUuNzkxMiAxNS4yODE3IDMzLjg2MDcgMTMuMzUxMiAzMS40NjY5IDEzLjM1MTJDMjkuMDczMSAxMy4zNTEyIDI3LjE0MjYgMTUuMjgxNyAyNy4xNDI2IDE3LjY3NTVWMjAuNTMyN0MyNy4xNDI2IDIyLjkyNjUgMjkuMDczMSAyNC44NTcgMzEuNDY2OSAyNC44NTdaIiBmaWxsPSIjOURBMkE3Ii8+CjxwYXRoIGQ9Ik0yMy41MTMxIDQyLjg0OTNDMjMuMzU4NyA0Mi41NDA1IDIzLjIwNDIgNDIuMzA4OCAyMy4wNDk4IDQxLjk5OTlDMjIuOTcyNiA0MS45OTk5IDIyLjk3MjYgNDEuOTk5OSAyMi44OTU0IDQxLjk5OTlDMjAuNTAxNSA0MS45OTk5IDE4LjU3MTEgNDAuMDY5NCAxOC41NzExIDM3LjY3NTZWMzMuNDI4NUMxNi4xNzcyIDMzLjM1MTMgMTQuMTY5NSAzMy41ODMgMTIuNzAyNCAzNC40MzI0QzEyLjM5MzUgMzUuNDM2MyAxMi4yMzkgMzYuNTk0NiAxMi4yMzkgMzguMDYxN0MxMi4yMzkgNDkuNTY3NSAyMS44MTQzIDU4LjgzMzggMzMuNzA2MSA1OC44MzM4QzM5LjM0MzEgNTguODMzOCA0NC41OTQxIDU3LjA1NzggNDguNDU1MSA1My44MTQ1QzQ5Ljk5OTUgNTEuODg0IDUxLjIzNSA0OS42NDQ3IDUyLjAwNzIgNDcuMTczNkM0My4wNDk3IDUzLjk2OSAyOS44NDUxIDUyLjg4NzkgMjMuNTEzMSA0Mi44NDkzWiIgZmlsbD0iIzlEQTJBNyIvPgo8cGF0aCBkPSJNMjEuMjc0MSA0NS45MzhDMTkuNDIwOCA0My4wMDM2IDE4Ljg4MDMgNDAuNjg3IDE4LjcyNTggMzguNzU2NUMxOC42NDg2IDM4LjQ0NzcgMTguNTcxNCAzOC4wNjE2IDE4LjU3MTQgMzcuNzUyN1YzMy41MDU2QzEzLjM5NzcgMzMuMjczOSAxMCAzNC41MDk1IDEwIDQxLjIyNzZDMTAgNTIuNzMzMyAxOS41NzUyIDYxLjk5OTcgMzEuNDY3MSA2MS45OTk3QzQxLjExOTUgNjEuOTk5NyA0OS4zMDQ4IDU1LjgyMjEgNTIuMDA3NSA0Ny4yNTA3QzQzLjEyNzIgNTYuMjg1NCAyOC4yMjM4IDU2Ljk4MDQgMjEuMjc0MSA0NS45MzhaIiBmaWxsPSIjOURBMkE3Ii8+Cjwvc3ZnPgo=', |
| 135 |
99 |
| 136 |
); |
| 137 |
} |
| 138 |
add_action('admin_menu', 'juicer_set_admin_menu'); |
| 139 |
|
| 140 |
// Load custom admin CSS |
| 141 |
function load_custom_wp_admin_style() { |
| 142 |
wp_enqueue_style('juicer-admin-css', plugin_dir_url(__FILE__) . 'includes/admin/css/admin.css', array(), JUICER_VERSION); |
| 143 |
} |
| 144 |
add_action('admin_enqueue_scripts', 'load_custom_wp_admin_style'); |
| 145 |
|
| 146 |
// Load custom admin JavaScript and localize |
| 147 |
function load_custom_wp_admin_script($hook_suffix) { |
| 148 |
// Check if we're on the Juicer settings page or any admin page |
| 149 |
if ($hook_suffix === 'toplevel_page_juicer-settings' || $hook_suffix === 'index.php') { |
| 150 |
wp_enqueue_script('juicer-admin-js', plugin_dir_url(__FILE__) . 'includes/admin/js/admin.js', array('jquery'), JUICER_VERSION, true); |
| 151 |
|
| 152 |
// Localize the script with your data |
| 153 |
wp_localize_script('juicer-admin-js', 'juicer_admin', array( |
| 154 |
'ajax_url' => admin_url('admin-ajax.php'), |
| 155 |
'security' => wp_create_nonce('juicer_nonce') |
| 156 |
)); |
| 157 |
} |
| 158 |
} |
| 159 |
add_action('admin_enqueue_scripts', 'load_custom_wp_admin_script'); |
| 160 |
|
| 161 |
|
| 162 |
// Setup guide page |
| 163 |
function juicer_set_settings_page() { |
| 164 |
include('includes/admin/settings.php'); |
| 165 |
} |
| 166 |
|
| 167 |
// Plugin setup guide link |
| 168 |
function juicer_plugin_action_links($links) { |
| 169 |
$links[] = '<a href="' . admin_url('admin.php?page=juicer-settings') . '">' . __('Setup guide') . '</a>'; |
| 170 |
return $links; |
| 171 |
} |
| 172 |
add_filter('plugin_action_links_' . plugin_basename(__FILE__), 'juicer_plugin_action_links'); |
| 173 |
|
| 174 |
// Plugin review notice |
| 175 |
// Check for feed existence and set option |
| 176 |
function juicer_check_feed_existence() { |
| 177 |
$host_url = home_url(); |
| 178 |
$response = wp_remote_get('https://www.juicer.io/api/hosts?hostname=' . $host_url); |
| 179 |
|
| 180 |
// Default to no feeds existing |
| 181 |
update_option('juicer_feed_exists', false); |
| 182 |
|
| 183 |
if (!is_wp_error($response)) { |
| 184 |
$response_code = wp_remote_retrieve_response_code($response); |
| 185 |
|
| 186 |
if ($response_code !== 404) { |
| 187 |
$body = wp_remote_retrieve_body($response); |
| 188 |
$data = json_decode($body, true); |
| 189 |
|
| 190 |
foreach ($data as $item) { |
| 191 |
if (isset($item['feed_id'])) { |
| 192 |
// Update the option to true as feed exists |
| 193 |
update_option('juicer_feed_exists', true); |
| 194 |
break; |
| 195 |
} |
| 196 |
} |
| 197 |
} |
| 198 |
} |
| 199 |
} |
| 200 |
add_action('admin_init', 'juicer_check_feed_existence'); |
| 201 |
|
| 202 |
// Display review notice |
| 203 |
function juicer_review_notice() { |
| 204 |
// Get the current screen object to check the hook suffix |
| 205 |
$current_screen = get_current_screen(); |
| 206 |
$hook_suffix = $current_screen->base; |
| 207 |
|
| 208 |
// Check if the current page is one of the allowed pages |
| 209 |
if ($hook_suffix === 'toplevel_page_juicer-settings' || $hook_suffix === 'dashboard') { |
| 210 |
if (get_option('juicer_feed_exists') && juicer_should_show_review_notice()) { |
| 211 |
echo '<div class="notice notice-info is-dismissible" id="juicer-review-notice">'; |
| 212 |
echo '<div class="juicer__notice__holder">'; |
| 213 |
echo '<div class="juicer__notice__col_1">'; |
| 214 |
echo '<img src="' . plugin_dir_url(__FILE__) . 'includes/admin/img/juicer-icon.svg" width="24" >'; |
| 215 |
echo '</div>'; |
| 216 |
echo '<div class="juicer__notice__col_2">'; |
| 217 |
echo '<strong class="juicer__notice__title">Thanks for using Juicer!</strong>'; |
| 218 |
echo '<p class="juicer__notice__text">If you enjoy our plugin, would you consider leaving us a <strong>5-star review</strong> on Wordpress.org?</p>'; |
| 219 |
echo '<div class="juicer__notice__buttons">'; |
| 220 |
echo '<a href="https://wordpress.org/plugins/juicer/#reviews" target="_blank" id="juicer-love-it" class="button button-primary">Sure, I’d love to <img src="' . plugin_dir_url(__FILE__) . 'includes/admin/img/wp-outbound-link-icon-white.svg" width="16" height="16" ></a> '; |
| 221 |
echo '<button id="juicer-maybe-later" class="juicer-notice__links">Maybe later</button> '; |
| 222 |
echo '<button id="juicer-never-show" class="juicer-notice__links">Never show this again</button>'; |
| 223 |
echo '</div>'; |
| 224 |
echo '</div>'; |
| 225 |
echo '</div>'; |
| 226 |
echo '</div>'; |
| 227 |
} |
| 228 |
} |
| 229 |
} |
| 230 |
add_action('admin_notices', 'juicer_review_notice'); |
| 231 |
|
| 232 |
|
| 233 |
// AJAX handler for dismissing the review notice |
| 234 |
function juicer_dismiss_review_notice() { |
| 235 |
check_ajax_referer('juicer_nonce', 'security'); |
| 236 |
if (current_user_can('manage_options')) { |
| 237 |
if (isset($_POST['dismiss_type'])) { |
| 238 |
$dismiss_type = sanitize_text_field($_POST['dismiss_type']); |
| 239 |
if ($dismiss_type === 'permanent') { |
| 240 |
// Never show again |
| 241 |
update_option('juicer_review_permanently_dismissed', 'yes'); |
| 242 |
wp_send_json_success('Permanently dismissed.'); |
| 243 |
} elseif ($dismiss_type === 'temporary') { |
| 244 |
// Dismiss for 7 days |
| 245 |
update_option('juicer_review_dismissed', time() + 7 * DAY_IN_SECONDS); |
| 246 |
wp_send_json_success('Temporarily dismissed.'); |
| 247 |
} else { |
| 248 |
wp_send_json_error('Invalid dismiss type.'); |
| 249 |
} |
| 250 |
} else { |
| 251 |
wp_send_json_error('Dismiss type not set.'); |
| 252 |
} |
| 253 |
} else { |
| 254 |
wp_send_json_error('Permission denied.'); |
| 255 |
} |
| 256 |
wp_die(); |
| 257 |
} |
| 258 |
add_action('wp_ajax_juicer_dismiss_review_notice', 'juicer_dismiss_review_notice'); |
| 259 |
|
| 260 |
// Check if the review notice should be displayed |
| 261 |
function juicer_should_show_review_notice() { |
| 262 |
if (get_option('juicer_review_permanently_dismissed') === 'yes') { |
| 263 |
return false; |
| 264 |
} |
| 265 |
$dismissed_until = get_option('juicer_review_dismissed'); |
| 266 |
if ($dismissed_until && time() < $dismissed_until) { |
| 267 |
return false; |
| 268 |
} |
| 269 |
return true; |
| 270 |
} |
| 271 |
|
| 272 |
// Register the Elementor widget |
| 273 |
function register_juicer_elementor_widget($widgets_manager) { |
| 274 |
if (defined('ELEMENTOR_VERSION') && class_exists('Elementor\Widget_Base')) { |
| 275 |
require_once plugin_dir_path(__FILE__) . 'includes/elementor/elementor-widget.php'; |
| 276 |
$widgets_manager->register(new \Elementor_Juicer_Widget()); |
| 277 |
} |
| 278 |
} |
| 279 |
add_action('elementor/widgets/register', 'register_juicer_elementor_widget'); |
| 280 |
|
| 281 |
// Enqueue custom CSS for Elementor editor |
| 282 |
function enqueue_juicer_elementor_editor_styles() { |
| 283 |
wp_enqueue_style( |
| 284 |
'juicer-elementor-editor', |
| 285 |
plugin_dir_url(__FILE__) . 'includes/elementor/juicer-elementor.css', |
| 286 |
array(), |
| 287 |
JUICER_VERSION |
| 288 |
); |
| 289 |
} |
| 290 |
add_action('elementor/frontend/after_enqueue_styles', 'enqueue_juicer_elementor_editor_styles'); |
| 291 |
add_action('elementor/editor/after_enqueue_styles', 'enqueue_juicer_elementor_editor_styles'); |
| 292 |
|
| 293 |
function juicer_register_daterangepicker_assets() { |
| 294 |
if (wp_script_is('daterangepicker', 'registered')) { |
| 295 |
return; |
| 296 |
} |
| 297 |
wp_register_script('daterangepicker', 'https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.min.js', array('jquery', 'moment'), '3.1', true); |
| 298 |
wp_register_style('daterangepicker-css', 'https://cdn.jsdelivr.net/npm/daterangepicker/daterangepicker.css', array(), '3.1'); |
| 299 |
wp_register_script('juicer-daterangepicker-init', plugin_dir_url(__FILE__) . 'includes/elementor/daterangepicker-init.js', array('jquery', 'daterangepicker'), JUICER_VERSION, true); |
| 300 |
} |
| 301 |
add_action('elementor/editor/before_enqueue_scripts', 'juicer_register_daterangepicker_assets'); |
| 302 |
add_action('elementor/frontend/before_enqueue_scripts', 'juicer_register_daterangepicker_assets'); |
| 303 |
|
| 304 |
function juicer_editor_has_juicer_widget() { |
| 305 |
if (!isset($_GET['post']) || !function_exists('\Elementor\Plugin::instance')) { |
| 306 |
return false; |
| 307 |
} |
| 308 |
$post_id = absint($_GET['post']); |
| 309 |
if (!$post_id) { |
| 310 |
return false; |
| 311 |
} |
| 312 |
$document = \Elementor\Plugin::instance()->documents->get($post_id); |
| 313 |
if (!$document) { |
| 314 |
return false; |
| 315 |
} |
| 316 |
$data = $document->get_elements_data(); |
| 317 |
return juicer_find_widget_in_data($data, 'juicer_widget'); |
| 318 |
} |
| 319 |
|
| 320 |
function juicer_find_widget_in_data($elements, $widget_type) { |
| 321 |
if (!is_array($elements)) { |
| 322 |
return false; |
| 323 |
} |
| 324 |
foreach ($elements as $element) { |
| 325 |
if (isset($element['widgetType']) && $element['widgetType'] === $widget_type) { |
| 326 |
return true; |
| 327 |
} |
| 328 |
if (!empty($element['elements']) && juicer_find_widget_in_data($element['elements'], $widget_type)) { |
| 329 |
return true; |
| 330 |
} |
| 331 |
} |
| 332 |
return false; |
| 333 |
} |
| 334 |
|
| 335 |
function juicer_enqueue_daterangepicker_in_editor() { |
| 336 |
if (!juicer_editor_has_juicer_widget()) { |
| 337 |
return; |
| 338 |
} |
| 339 |
wp_enqueue_script('moment'); |
| 340 |
wp_enqueue_script('daterangepicker'); |
| 341 |
wp_enqueue_style('daterangepicker-css'); |
| 342 |
wp_enqueue_script('juicer-daterangepicker-init'); |
| 343 |
} |
| 344 |
add_action('elementor/editor/after_enqueue_scripts', 'juicer_enqueue_daterangepicker_in_editor'); |
| 345 |
?> |
| 346 |
|