PluginProbe
ShopEngine Elementor WooCommerce Builder Addon – All in One WooCommerce Solution with eCommerce Templates & Woo Widgets / 4.9.1
ShopEngine Elementor WooCommerce Builder Addon – All in One WooCommerce Solution with eCommerce Templates & Woo Widgets v4.9.1
4.9.5 4.9.4 4.9.3 4.9.2 4.9.1 4.9.0 2.0.0 2.1.0 2.2.0 2.2.1 2.2.2 2.3.0 2.4.0 2.5.0 2.5.1 3.0.0 3.1.0 3.1.1 4.0.0 4.0.1 4.1.0 4.1.1 4.2.0 4.2.1 4.3.0 All 85 releases
← All changes | plugin.php +630 -424 2.2.04.9.1 View file →
@@ -1,424 +1,630 @@
1 -<?php
2 -
3 -namespace ShopEngine;
4 -
5 -use ShopEngine\Compatibility\Conflicts\Manifest as Conflict_Manifest;
6 -use ShopEngine\Core\Builders\Base;
7 -use ShopEngine\Core\Query_Modifier;
8 -use ShopEngine\Core\Template_Cpt;
9 -use ShopEngine\Libs\License\License_Route;
10 -use ShopEngine\Libs\Updater\Init as Updater;
11 -use ShopEngine\Modules\Manifest as Module_Manifest;
12 -use ShopEngine\Widgets\Manifest;
13 -
14 -defined('ABSPATH') || exit;
15 -
16 -/**
17 - * Plugin final Class.
18 - * Handles dynamically loading classes only when needed. Check Elementor Plugin, Woocomerce Plugin Loaded or Install.
19 - *
20 - * @since 1.0.0
21 - */
22 -final class Plugin {
23 -
24 - private static $instance;
25 -
26 - /**
27 - * __construct function
28 - * @since 1.0.0
29 - */
30 - public function __construct() {
31 - // load autoload method
32 - Autoloader::run();
33 - }
34 -
35 -
36 - /**
37 - * Public function init.
38 - * call function for all
39 - *
40 - * @since 1.0.0
41 - */
42 - public function init() {
43 -
44 - $error = false;
45 -
46 - // check woocommerce plugin
47 - if(!did_action('woocommerce_loaded')) {
48 - add_action('admin_notices', [$this, 'missing_woocommerce']);
49 -
50 - $error = true;
51 - }
52 -
53 - $check_elementor_version = false;
54 -
55 - // Check if Elementor installed and activated.
56 - if(!did_action('elementor/loaded')) {
57 -
58 - if(!did_action('shopengine-gutenberg-addon/before_loaded')) {
59 -
60 - add_action('admin_notices', [$this, 'missing_elementor']);
61 -
62 - $error = true;
63 - }
64 - }
65 -
66 - // Check for required Elementor version.
67 - if(did_action('elementor/loaded') && defined('ELEMENTOR_VERSION') && !version_compare(ELEMENTOR_VERSION, '3.0.0', '>=')) {
68 -
69 - add_action('admin_notices', [$this, 'failed_elementor_version']);
70 -
71 - $error = true;
72 - }
73 -
74 - if($error) {
75 - return;
76 - }
77 -
78 - add_filter("plugin_action_links_shopengine/shopengine.php", function ($links) {
79 -
80 - $custom_links[] = '<a href="'.admin_url('edit.php?post_type=shopengine-template#getting-started').'" target="_blank">' . esc_html__('Settings', 'shopengine') . '</a>';
81 -
82 - foreach ($custom_links as $custom_link):
83 - array_unshift($links, $custom_link);
84 - endforeach;
85 -
86 - if (!is_plugin_active('shopengine-pro/shopengine-pro.php')) {
87 - $links[] = '<a href="https://wpmet.com/plugin/shopengine/pricing/" style="color:#FCB214;font-weight:700" target="_blank">' . esc_html__('Go Pro', 'shopengine') . '</a>';
88 - }
89 - return $links;
90 - });
91 -
92 -
93 - /**
94 - * Routes initialization
95 - *
96 - */
97 - new License_Route();
98 -
99 - /**
100 - * Run pro plugin updater here....
101 - *
102 - */
103 - add_action('admin_init', function () {
104 - if(class_exists('ShopEngine_Pro')) {
105 - new Updater();
106 - }
107 - });
108 -
109 -
110 - add_action('wp_loaded', function () {
111 -
112 - if(isset($_REQUEST['preview']) && $_REQUEST['preview'] == 'true' && !empty($_REQUEST['preview_id'])) {
113 -
114 - $pid = (int)$_REQUEST['preview_id'];
115 -
116 - $po = get_post($pid);
117 -
118 - if($po->post_type === Template_Cpt::TYPE) {
119 -
120 - $template = \ShopEngine\Core\Builders\Templates::get_registered_template_data($pid);
121 -
122 - if(empty($template) || !isset($template['url'])) {
123 - return;
124 - }
125 -
126 - $param = [
127 - 'shopengine_template_id' => $pid,
128 - 'preview_nonce' => wp_create_nonce('template_preview_' . $pid),
129 - 'change_template' => '1',
130 - ];
131 -
132 - $url = \ShopEngine\Utils\Helper::add_to_url($template['url'], $param);
133 -
134 - wp_safe_redirect($url);
135 - exit;
136 - }
137 - }
138 - });
139 -
140 - // avoid themes for loading woocommerce functions
141 - $avoid_themes = ['avada'];
142 -
143 - if(!in_array(strtolower(wp_get_theme()), $avoid_themes)) {
144 - /**
145 - * Ensuring woocommerce functions are loaded before theme is modifying those
146 - *
147 - */
148 - require_once WC_ABSPATH . '/includes/wc-template-functions.php';
149 - }
150 -
151 -
152 - if(did_action('elementor/loaded')) {
153 - // Load custom elementor controls
154 - new \ShopEngine\Core\Elementor_Controls\Init();
155 -
156 - //Loading the scripts and styles
157 - add_action('elementor/editor/after_enqueue_styles', [$this, 'js_css_elementor']);
158 - }
159 -
160 -
161 - //Loading public scripts and styles
162 - add_action('wp_enqueue_scripts', [$this, 'js_css_public']);
163 -
164 - //woocommece theme support
165 - if(!current_theme_supports('woocommerce')) {
166 - add_theme_support('woocommerce');
167 - add_theme_support('wc-product-gallery-zoom');
168 - add_theme_support('wc-product-gallery-lightbox');
169 - add_theme_support('wc-product-gallery-slider');
170 - }
171 -
172 -
173 - #Registering new post-type & etc
174 - Base::instance()->init();
175 -
176 - \ShopEngine\Core\Settings\Base::instance()->init();
177 -
178 - new Libs\Select_Api\Base();
179 -
180 - (new Module_Manifest())->init();
181 -
182 - // working get instance of elementor widget
183 - (new Manifest())->init();
184 -
185 - Query_Modifier::instance()->init();
186 -
187 - (new Conflict_Manifest())->init();
188 -
189 - // view count
190 - add_action('get_header', [$this, 'shopengine_track_product_views']);
191 -
192 - // database migrations
193 - // (new \ShopEngine\Compatibility\Migrations\Migration())->init();
194 - (new \ShopEngine\Compatibility\Migrations\Temp_Migration())->init();
195 -
196 -
197 - // call service providers
198 -
199 - $service_providers = include \ShopEngine::plugin_dir().'core/service-provider-manager.php';
200 - $method = 'init';
201 - foreach( $service_providers as $service_provider ){
202 -
203 - if(class_exists($service_provider) && method_exists($service_provider, $method)) {
204 - $instance = new $service_provider();
205 - $instance->$method();
206 - }
207 -
208 - }
209 -
210 -
211 -
212 - add_filter('script_loader_tag', [$this, 'filter_load_type'], 99, 3);
213 - }
214 -
215 -
216 - // add async and defer attributes to enqueued scripts
217 - public function filter_load_type($tag, $handle, $src) {
218 -
219 - if(strpos($handle, '-async') !== false) {
220 - $tag = str_replace(' src', ' async="async" src', $tag);
221 - }
222 -
223 - if(strpos($handle, '-defer') !== false) {
224 - $tag = str_replace('<script ', '<script defer ', $tag);
225 - }
226 -
227 - return $tag;
228 - }
229 -
230 - /**
231 - * Public function shopengine_track_product_views
232 - * Adding Product Views Count Meta
233 - */
234 - public function shopengine_track_product_views() {
235 -
236 - if(class_exists('WooCommerce') && !is_product()) {
237 - return;
238 - }
239 -
240 - $product_id = get_the_id();
241 -
242 - $cookie_name = "shopengine_recent_viewed_product";
243 -
244 - if(isset($_COOKIE[$cookie_name])) {
245 -
246 - $cookie_ids = $_COOKIE[$cookie_name];
247 - $product_ids = explode(',', $cookie_ids);
248 -
249 - if(!is_array($product_ids)) {
250 - $product_ids = [$product_ids];
251 - }
252 -
253 - $product_ids = array_combine($product_ids, $product_ids);
254 - unset($product_ids[$product_id]);
255 - $product_ids[] = $product_id;
256 -
257 - $cookie_value = implode(',', $product_ids);
258 -
259 - } else {
260 - $cookie_value = $product_id;
261 - }
262 -
263 - setcookie($cookie_name, $cookie_value, strtotime('+30 days'), '/' );
264 -
265 - $count_key = 'shopengine_product_views_count';
266 - $count = get_post_meta($product_id, $count_key, true);
267 -
268 - if($count == '') {
269 - $count = 1;
270 - delete_post_meta($product_id, $count_key);
271 - add_post_meta($product_id, $count_key, '1');
272 - } else {
273 - $count++;
274 - update_post_meta($product_id, $count_key, $count);
275 - }
276 - }
277 -
278 - /**
279 - * Public function js_css_public .
280 - * Include public function
281 - *
282 - * @since 1.0.0
283 - */
284 - public function js_css_public() {
285 - wp_enqueue_style('shopengine-icon', \ShopEngine::plugin_url() . 'assets/css/shopengine-icon.css', false, \ShopEngine::version());
286 - wp_enqueue_style('shopengine-simple-scrollbar-css', \ShopEngine::plugin_url() . 'assets/css/simple-scrollbar.css', false, \ShopEngine::version());
287 - wp_enqueue_style('shopengine-public-css', \ShopEngine::plugin_url() . 'assets/css/public-style.css', false, \ShopEngine::version());
288 -
289 - // Modal Stylesheet
290 - wp_register_style('shopengine-modal-styles', \ShopEngine::plugin_url() . 'assets/css/shopengine-modal.css', false, \ShopEngine::version());
291 -
292 - // Modal Script
293 - wp_register_script('shopengine-modal-script', \ShopEngine::plugin_url() . 'assets/js/shopengine-modal.js', ['jquery'], \ShopEngine::version(), true);
294 -
295 - wp_enqueue_script('shopengine-simple-scrollbar.js-js', \ShopEngine::plugin_url() . 'assets/js/simple-scrollbar.js', [], \ShopEngine::version(), true);
296 - wp_enqueue_script('shopengine-filter-js', \ShopEngine::plugin_url() . 'assets/js/filter.js', [], \ShopEngine::version(), true);
297 - wp_enqueue_script('shopengine-js', \ShopEngine::plugin_url() . 'assets/js/public.js', [], \ShopEngine::version(), true);
298 -
299 -
300 - wp_localize_script('shopengine-js', 'shopEngineApiSettings', [
301 - 'resturl' => get_rest_url(),
302 - 'rest_nonce' => wp_create_nonce('wp_rest'),
303 - ]);
304 -
305 -
306 - /**
307 - * Registering libs css/js
308 - *
309 - */
310 -
311 - wp_register_style(
312 - 'lib-sqv-css',
313 - \ShopEngine::plugin_url() . '/assets/sqv/smart-quick-view.css',
314 - [],
315 - \ShopEngine::version()
316 - );
317 -
318 - wp_register_script(
319 - 'lib-sqv-js',
320 - \ShopEngine::plugin_url() . 'assets/sqv/smart-quick-view.js',
321 - ['jquery', 'wc-single-product'],
322 - \ShopEngine::version(),
323 - true
324 - );
325 - }
326 -
327 - public function js_css_elementor() {
328 - wp_enqueue_style('shopnegine-panel-icon', \ShopEngine::plugin_url() . 'assets/css/shopengine-icon.css', false, \ShopEngine::version());
329 -
330 - if('shopengine-template' === get_post_type()):
331 - wp_enqueue_style('shopnegine-editor-css', \ShopEngine::plugin_url() . 'assets/css/editor.css', false, \ShopEngine::version());
332 - endif;
333 - }
334 -
335 -
336 - public function missing_woocommerce() {
337 -
338 - if(isset($_GET['activate'])) {
339 - unset($_GET['activate']);
340 - }
341 -
342 - if(file_exists(WP_PLUGIN_DIR . '/woocommerce/woocommerce.php')) {
343 -
344 - $btn['label'] = esc_html__('Activate WooCommerce', 'shopengine');
345 - $btn['url'] = wp_nonce_url('plugins.php?action=activate&plugin=woocommerce/woocommerce.php&plugin_status=all&paged=1', 'activate-plugin_woocommerce/woocommerce.php');
346 -
347 - } else {
348 -
349 - $btn['label'] = esc_html__('Install WooCommerce', 'shopengine');
350 - $btn['url'] = wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=woocommerce'), 'install-plugin_woocommerce');
351 - }
352 -
353 - Utils\Notice::push(
354 - [
355 - 'id' => 'missing-woo',
356 - 'type' => 'error',
357 - 'dismissible' => true,
358 - 'btn' => $btn,
359 - 'message' => sprintf(esc_html__('ShopEngine requires woocommerce Plugin, which is currently NOT RUNNING.', 'shopengine'), '4.1.0'),
360 - ]
361 - );
362 - }
363 -
364 -
365 - public function missing_elementor() {
366 -
367 - if(isset($_GET['activate'])) {
368 - unset($_GET['activate']);
369 - }
370 -
371 - if(file_exists(WP_PLUGIN_DIR . '/elementor/elementor.php')) {
372 -
373 - $btn['label'] = esc_html__('Activate Elementor', 'shopengine');
374 - $btn['url'] = wp_nonce_url('plugins.php?action=activate&plugin=elementor/elementor.php&plugin_status=all&paged=1', 'activate-plugin_elementor/elementor.php');
375 -
376 - } else {
377 -
378 - $btn['label'] = esc_html__('Install Elementor', 'shopengine');
379 - $btn['url'] = wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=elementor'), 'install-plugin_elementor');
380 - }
381 -
382 - Utils\Notice::push(
383 - [
384 - 'id' => 'missing-elementor',
385 - 'type' => 'error',
386 - 'dismissible' => true,
387 - 'btn' => $btn,
388 - 'message' => sprintf(esc_html__('ShopEngine requires Elementor version %1$s+, which is currently NOT RUNNING.', 'shopengine'), '3.0.0'),
389 - ]
390 - );
391 - }
392 -
393 -
394 - public function failed_elementor_version() {
395 -
396 - $btn['label'] = esc_html__('Update Elementor', 'shopengine');
397 - $btn['url'] = wp_nonce_url(self_admin_url('update.php?action=upgrade-plugin&plugin=elementor'), 'upgrade-plugin_elementor');
398 -
399 - Utils\Notice::push(
400 - [
401 - 'id' => 'unsupported-elementor-version',
402 - 'type' => 'error',
403 - 'dismissible' => true,
404 - 'btn' => $btn,
405 - 'message' => sprintf(esc_html__('ShopEngine requires Elementor version %1$s+, which is currently NOT RUNNING.', 'shopengine'), '3.0.0'),
406 - ]
407 - );
408 - }
409 -
410 -
411 - public function flush_rewrites() {
412 - $form_cpt = new Core\Builders\Cpt();
413 - $form_cpt->flush_rewrites();
414 - }
415 -
416 -
417 - public static function instance() {
418 - if(!self::$instance) {
419 - self::$instance = new self();
420 - }
421 -
422 - return self::$instance;
423 - }
424 -}
1 +<?php
2 +
3 +namespace ShopEngine;
4 +
5 +defined('ABSPATH') || exit;
6 +
7 +use ShopEngine\Compatibility\Conflicts\Manifest as Conflict_Manifest;
8 +use ShopEngine\Core\Builders\Base;
9 +use ShopEngine\Compatibility\Migrations\LangMigration;
10 +use ShopEngine\Core\Query_Modifier;
11 +use ShopEngine\Core\Wc_Customizer\Register_Settings;
12 +use ShopEngine\Core\Template_Cpt;
13 +use ShopEngine\Libs\License\License_Route;
14 +use ShopEngine\Libs\Rating\Rating;
15 +use ShopEngine\Libs\Updater\Init as Updater;
16 +use ShopEngine\Modules\Manifest as Module_Manifest;
17 +use ShopEngine\Utils\Feedback\Plugin_Unsubscribe;
18 +use ShopEngine\Widgets\Manifest;
19 +
20 +
21 +/**
22 + * Plugin final Class.
23 + * Handles dynamically loading classes only when needed. Check Elementor Plugin, Woocomerce Plugin Loaded or Install.
24 + *
25 + * @since 1.0.0
26 + */
27 +final class Plugin {
28 +
29 + private static $instance;
30 +
31 + /**
32 + * __construct function
33 + * @since 1.0.0
34 + */
35 + public function __construct() {
36 + // load autoload method
37 + Autoloader::run();
38 + add_action( 'wp_ajax_shopengine_admin_action', [\ShopEngine\Utils\Util::class, 'shopengine_admin_action'] );
39 + }
40 +
41 + public function utils_url()
42 + {
43 + return $this->plugin_url() . 'utils/';
44 + }
45 + /**
46 + * Public function init.
47 + * call function for all
48 + *
49 + * @since 1.0.0
50 + */
51 + public function init() {
52 +
53 + $error = false;
54 +
55 + // init notice class
56 + \Oxaim\Libs\Notice::init();
57 +
58 + // check woocommerce plugin
59 + if(!did_action('woocommerce_loaded')) {
60 + add_action('admin_notices', [$this, 'missing_woocommerce']);
61 +
62 + $error = true;
63 + }
64 +
65 + $check_elementor_version = false;
66 +
67 + // Check if Elementor installed and activated.
68 + if(!did_action('elementor/loaded')) {
69 +
70 + if(!did_action('shopengine-gutenberg-addon/before_loaded')) {
71 +
72 + add_action('admin_notices', [$this, 'missing_elementor']);
73 +
74 + $error = true;
75 + }
76 + }
77 +
78 + // Check for required Elementor version.
79 + if(did_action('elementor/loaded') && defined('ELEMENTOR_VERSION') && !version_compare(ELEMENTOR_VERSION, '3.0.0', '>=')) {
80 +
81 + add_action('admin_notices', [$this, 'failed_elementor_version']);
82 +
83 + $error = true;
84 + }
85 +
86 + if($error) {
87 + return;
88 + }
89 +
90 +
91 +
92 + add_filter("plugin_action_links_shopengine/shopengine.php", function ($links) {
93 + $free = esc_html__("Go To Shopengine","shopengine");
94 + $pro = esc_html__("Go To ShopenginePro","shopengine");
95 +
96 + $custom_links[] = '<a title="' . $free . '" href="'.admin_url('edit.php?post_type=shopengine-template#getting-started').'" target="_blank">' . esc_html__('Settings', 'shopengine') . '</a>';
97 +
98 + foreach ($custom_links as $custom_link):
99 + array_unshift($links, $custom_link);
100 + endforeach;
101 +
102 + if (!is_plugin_active('shopengine-pro/shopengine-pro.php')) {
103 + $links[] = '<a title="' . $pro . '" href="https://wpmet.com/plugin/shopengine/pricing/" style="color:#FCB214;font-weight:700" target="_blank" rel="noopener">' . esc_html__('Go Pro', 'shopengine') . '</a>';
104 + }
105 + return $links;
106 + });
107 +
108 + if(\ShopEngine\Utils\Util::get_settings( 'shopengine_user_consent_for_banner', 'true' ) == 'true'){
109 +
110 + /**
111 + * EmailKit Global Class initialization
112 + *
113 + */
114 + if( !class_exists('EmailKit') && !did_action('edit_with_emailkit_loaded') && class_exists('\Wpmet\Libs\Emailkit') ) {
115 +
116 + new \Wpmet\Libs\Emailkit();
117 + }
118 +
119 + /**
120 + * MetForm get free templates promotional class initialization
121 + *
122 + */
123 + if( !did_action('metform/after_load') && did_action('elementor/loaded') && class_exists('\Wpmet\Libs\Metform_Promo_Banner') ) {
124 +
125 + new \Wpmet\Libs\Metform_Promo_Banner();
126 + }
127 + }
128 +
129 +
130 + /**
131 + * Routes initialization
132 + *
133 + */
134 + new License_Route();
135 +
136 + // Initialize deactivation feedback modal
137 + new \ShopEngine\Utils\Feedback\Plugin_Unsubscribe();
138 + /**
139 + * Run pro plugin updater here....
140 + *
141 + */
142 + add_action('admin_init', function () {
143 + if(class_exists('ShopEngine_Pro')) {
144 + new Updater();
145 + }
146 + new \ShopEngine\Compatibility\Migrations\Direct_Checkout;
147 + });
148 +
149 +
150 + add_action('wp_loaded', function () {
151 + /**
152 + * migrate data
153 + */
154 + LangMigration::instance()->init();
155 + });
156 +
157 + // avoid themes for loading woocommerce functions
158 + $avoid_themes = ['avada', 'woodmart', 'Avada', 'Woodmart'];
159 +
160 + if( !in_array(get_template(), $avoid_themes) ) {
161 + /**
162 + * Ensuring woocommerce functions are loaded before theme is modifying those
163 + *
164 + */
165 + require_once WC_ABSPATH . '/includes/wc-template-functions.php';
166 + }
167 +
168 +
169 + if(did_action('elementor/loaded')) {
170 + // Load custom elementor controls
171 + new \ShopEngine\Core\Elementor_Controls\Init();
172 +
173 + //Loading the scripts and styles
174 + add_action('elementor/editor/after_enqueue_styles', [$this, 'js_css_elementor']);
175 +
176 + // Register widgets immediately after elementor is loaded with higher priority
177 + if(is_plugin_active('related-products-manager-woocommerce/related-products-manager-for-woocommerce.php')) {
178 +
179 + add_action('elementor/widgets/register', function() {
180 + (new Manifest())->init();
181 + }, 5); // Priority 5 to load early
182 + }
183 +
184 + }
185 +
186 + // Cart validation compatibility with WC Min Max Quantity plugin
187 +
188 + if ( function_exists( 'is_plugin_active' ) && is_plugin_active( 'woo-min-max-quantity-step-control-single/wcmmq.php' ) ) {
189 +
190 + add_filter( 'wcmmq_cart_validation_check', [ $this, 'shopengine_wcmmq_cart_validation_compat' ], 10, 2 );
191 + }
192 +
193 +
194 + //Loading public scripts and styles
195 + add_action('wp_enqueue_scripts', [$this, 'js_css_public']);
196 +
197 + //woocommece theme support
198 + if(!current_theme_supports('woocommerce')) {
199 + add_theme_support('woocommerce');
200 + add_theme_support('wc-product-gallery-zoom');
201 + add_theme_support('wc-product-gallery-lightbox');
202 + add_theme_support('wc-product-gallery-slider');
203 + }
204 +
205 +
206 + $filter_string = ''; // elementskit,metform-pro
207 + $filter_string .= ((!in_array('elementskit/elementskit.php', apply_filters('active_plugins', get_option('active_plugins')))) ? '' : ',elementskit');
208 + $filter_string .= (!class_exists('\MetForm\Plugin') ? '' : ',metform');
209 + $filter_string .= (!class_exists('\MetForm_Pro\Plugin') ? '' : ',metform-pro');
210 +
211 + #Registering new post-type & etc
212 + Base::instance()->init();
213 +
214 +
215 + Rating::instance('shopengine')
216 + ->set_plugin( 'ShopEngine', 'https://wpmet.com/wordpress.org/rating/shopengine' )
217 + ->set_rating_url( 'https://wordpress.org/support/plugin/shopengine/reviews/#new-post' )
218 + ->set_plugin_logo( 'https://ps.w.org/shopengine/assets/icon-256x256.gif?rev=2505061', 'width:150px !important' )
219 + ->set_priority( 11 )
220 + ->set_first_appear_day( 7 )
221 + ->set_condition( true )
222 + ->call();
223 +
224 + if ( is_admin() && \ShopEngine\Utils\Util::get_settings( 'shopengine_user_consent_for_banner', 'true' ) == 'true' ) {
225 +
226 + /**
227 + * Show WPMET stories widget in dashboard
228 + */
229 +
230 + \Wpmet\Libs\Stories::instance('shopengine')
231 +
232 + ->set_filter($filter_string)
233 + ->set_plugin('ShopEngine', 'https://wpmet.com/plugin/shopengine/')
234 + ->set_api_url('https://api.wpmet.com/public/stories/')
235 + ->call();
236 +
237 + // banner
238 + \Wpmet\Libs\Banner::instance('shopengine')
239 + ->set_filter(ltrim($filter_string, ','))
240 + ->set_api_url('https://api.wpmet.com/public/jhanda')
241 + ->set_plugin_screens('edit-shopengine-template')
242 + ->set_plugin_screens('edit-shopengine-template')
243 + ->call();
244 + }
245 +
246 + add_action('init', function () {
247 + $apps_img_path = \ShopEngine::plugin_url() . 'assets/images/apps-page/';
248 + /**
249 + * Show our plugins menu for others wpmet plugins
250 + */
251 + \ShopEngine\Wpmet\Libs\Plugins::instance()->init('shopengine')
252 + ->set_parent_menu_slug('shopengine-settings')
253 + ->set_submenu_name('Our Plugins')
254 + ->set_section_title('Get More out of Your WooCommerce Website!')
255 + ->set_section_description('Install other plugins from us and take your WooCommerce site to the next level for absolutely free!')
256 + ->set_items_per_row(4)
257 + ->set_plugins(
258 + [
259 + 'elementskit-lite/elementskit-lite.php' => [
260 + 'name' => esc_html__('ElementsKit', 'shopengine'),
261 + 'url' => 'https://wordpress.org/plugins/elementskit-lite/',
262 + 'icon' => $apps_img_path. 'elementskit.gif',
263 + 'desc' => esc_html__('All-in-one Elementor addon trusted by 1 Million+ users, makes your website builder process easier with ultimate freedom.', 'shopengine'),
264 + 'docs' => 'https://wpmet.com/doc/elementskit/',
265 + ],
266 + 'gutenkit-blocks-addon/gutenkit-blocks-addon.php' => [
267 + 'name' => esc_html__('GutenKit', 'shopengine'),
268 + 'url' => 'https://wordpress.org/plugins/gutenkit-blocks-addon/',
269 + 'icon' => $apps_img_path. 'guten-kit.png',
270 + 'desc' => esc_html__('Gutenberg blocks, patterns, and templates that extend the page-building experience using the WordPress block editor.', 'shopengine'),
271 + 'docs' => 'https://wpmet.com/doc/gutenkit/',
272 + ],
273 + 'rox-dynamic-cpt-fields-engine/rox-dynamic-cpt-fields-engine.php' => [
274 + 'name' => esc_html__('Rox Dynamic CPT Fields', 'shopengine'),
275 + 'url' => 'https://wordpress.org/plugins/rox-dynamic-cpt-fields-engine/',
276 + 'icon' => 'https://ps.w.org/rox-dynamic-cpt-fields-engine/assets/icon-256x256.jpeg?rev=3538537',
277 + 'desc' => esc_html__('Build custom post types, fields, taxonomies, and dynamic frontend layouts for WordPress, with zero coding and full AI-generated schema.', 'shopengine'),
278 + 'docs' => 'https://wpmet.com/doc/rox-dynamic-cpt-fields-engine/',
279 + ],
280 + 'rox-appointment-booking/rox-appointment-booking.php' => [
281 + 'name' => esc_html__('Rox Appointment Booking', 'shopengine'),
282 + 'url' => 'https://wordpress.org/plugins/rox-appointment-booking/',
283 + 'icon' => 'https://ps.w.org/rox-appointment-booking/assets/icon-256x256.png?rev=3575641',
284 + 'desc' => esc_html__('Manage bookings, agents, payments, and calendars from one dashboard! A complete appointment and scheduling solution for WordPress.', 'shopengine'),
285 + 'docs' => 'https://wpmet.com/doc/rox-appointment-booking/',
286 + ],
287 + 'metform/metform.php' => [
288 + 'name' => esc_html__('MetForm', 'shopengine'),
289 + 'url' => 'https://wordpress.org/plugins/metform/',
290 + 'icon' => $apps_img_path. 'metform.png',
291 + 'desc' => esc_html__('Drag & drop form builder for Elementor to create contact forms, multi-step forms, and more — smoother, faster, and better!', 'shopengine'),
292 + 'docs' => 'https://wpmet.com/doc/metform/',
293 + ],
294 + 'popup-builder-block/popup-builder-block.php' => [
295 + 'name' => esc_html__('PopupKit', 'shopengine'),
296 + 'url' => 'https://wordpress.org/plugins/popup-builder-block/',
297 + 'icon' => 'https://ps.w.org/popup-builder-block/assets/icon-256x256.png?rev=3316844',
298 + 'desc' => esc_html__('Design popups that convert, right in your WordPress dashboard.', 'shopengine'),
299 + 'docs' => 'https://wpmet.com/doc/popupkit/',
300 + ],
301 + 'table-builder-block/table-builder-block.php' => [
302 + 'name' => esc_html__('TableKit', 'shopengine'),
303 + 'url' => 'https://wordpress.org/plugins/table-builder-block/',
304 + 'icon' => 'https://ps.w.org/table-builder-block/assets/icon-256x256.png?rev=3509972',
305 + 'desc' => esc_html__('Fully Customizable. Multi-Media Integration. Synch Any Data Files. All Within Block Editor.', 'shopengine'),
306 + 'docs' => 'https://wpmet.com/doc/tablekit/',
307 + ],
308 + 'getgenie/getgenie.php' => [
309 + 'name' => esc_html__('GetGenie', 'shopengine'),
310 + 'url' => 'https://wordpress.org/plugins/getgenie/',
311 + 'icon' => $apps_img_path.'getgenie.gif',
312 + 'desc' => esc_html__('Your personal AI assistant for content and SEO. Write content that ranks on Google with NLP keywords and SERP analysis data.', 'shopengine'),
313 + 'docs' => 'https://getgenie.ai/docs/',
314 + ],
315 + 'emailkit/EmailKit.php' => [
316 + 'name' => esc_html__('EmailKit', 'shopengine'),
317 + 'url' => 'https://wordpress.org/plugins/emailkit/',
318 + 'icon' => $apps_img_path . 'emailkit.png',
319 + 'desc' => esc_html__('Advanced email customizer for WooCommerce and WordPress. Build, customize, and send emails from WordPress to boost your sales!', 'shopengine'),
320 + 'docs' => 'https://wpmet.com/doc/emailkit/',
321 + ],
322 + 'wp-social/wp-social.php' => [
323 + 'name' => esc_html__('WP Social', 'shopengine'),
324 + 'url' => 'https://wordpress.org/plugins/wp-social/',
325 + 'icon' => $apps_img_path . 'wp-social.png',
326 + 'desc' => esc_html__('Add social share, login, and engagement counter — unified solution for all social media with tons of different styles for your website.', 'shopengine'),
327 + 'docs' => 'https://wpmet.com/doc/wp-social/',
328 + ],
329 + 'blocks-for-shopengine/shopengine-gutenberg-addon.php' => [
330 + 'name' => esc_html__('Blocks for ShopEngine', 'shopengine'),
331 + 'url' => 'https://wordpress.org/plugins/blocks-for-shopengine/',
332 + 'icon' => $apps_img_path. 'shopengine.gif',
333 + 'desc' => esc_html__('All in one WooCommerce solution for Gutenberg! Build your WooCommerce pages in a block editor with full customization.', 'shopengine'),
334 + 'docs' => 'https://wpmet.com/doc/shopengine/shopengine-gutenberg/',
335 + ],
336 + ]
337 + )
338 + ->call();
339 +
340 + // working get instance of elementor widget
341 + (new Manifest())->init();
342 + } );
343 +
344 +
345 +
346 + \ShopEngine\Core\MultiLanguage\Language::instance()->init();
347 +
348 + \ShopEngine\Core\Settings\Base::instance()->init();
349 +
350 +
351 + new Libs\Select_Api\Base();
352 +
353 + (new Module_Manifest())->init();
354 +
355 +
356 + Query_Modifier::instance()->init();
357 +
358 + (new Conflict_Manifest())->init();
359 +
360 + // view count
361 + add_action('get_header', [$this, 'shopengine_track_product_views']);
362 +
363 + // database migrations
364 + // (new \ShopEngine\Compatibility\Migrations\Migration())->init();
365 + // (new \ShopEngine\Compatibility\Migrations\Temp_Migration())->init();
366 +
367 +
368 + // call service providers
369 +
370 + $service_providers = include \ShopEngine::plugin_dir().'core/service-provider-manager.php';
371 + $method = 'init';
372 + foreach( $service_providers as $service_provider ){
373 +
374 + if(class_exists($service_provider) && method_exists($service_provider, $method)) {
375 + $instance = new $service_provider();
376 + $instance->$method();
377 + }
378 +
379 + }
380 +
381 + add_filter('script_loader_tag', [$this, 'filter_load_type'], 99, 3);
382 +
383 + //it will register an option in customizer for woocommerce products catelog. It's related with our Arcive Products widget.
384 + Register_Settings::instance()->init();
385 + }
386 +
387 + public function shopengine_wcmmq_cart_validation_compat( $check, $request ) {
388 +
389 + $cart_widget_flag = isset( $_REQUEST['shopengine_cart_widget'] )
390 + ? sanitize_text_field( wp_unslash( $_REQUEST['shopengine_cart_widget'] ) )
391 + : '';
392 + $cart_widget_nonce = isset( $_REQUEST['shopengine_cart_widget_nonce'] )
393 + ? sanitize_text_field( wp_unslash( $_REQUEST['shopengine_cart_widget_nonce'] ) )
394 + : '';
395 +
396 + if ( $cart_widget_flag === '1' && wp_verify_nonce( $cart_widget_nonce, 'shopengine_cart_widget' ) ) {
397 + return false; // Skip WC MMQ validation for verified ShopEngine cart widget requests
398 + }
399 + return $check; // Proceed with normal validation for other requests
400 + }
401 +
402 +
403 +
404 +
405 +
406 + // add async and defer attributes to enqueued scripts
407 + public function filter_load_type($tag, $handle, $src) {
408 +
409 + if(strpos($handle, '-async') !== false) {
410 + $tag = str_replace(' src', ' async="async" src', $tag);
411 + }
412 +
413 + if(strpos($handle, '-defer') !== false) {
414 + $tag = str_replace('<script ', '<script defer ', $tag);
415 + }
416 +
417 + return $tag;
418 + }
419 +
420 + /**
421 + * Public function shopengine_track_product_views
422 + * Adding Product Views Count Meta
423 + */
424 + public function shopengine_track_product_views() {
425 +
426 + if(class_exists('WooCommerce') && !is_product()) {
427 + return;
428 + }
429 +
430 + $product_id = get_the_id();
431 +
432 + $cookie_name = "shopengine_recent_viewed_product";
433 +
434 + if(isset($_COOKIE[$cookie_name])) {
435 +
436 + $cookie_ids = sanitize_text_field(wp_unslash($_COOKIE[$cookie_name]));
437 + $product_ids = explode(',', $cookie_ids);
438 +
439 + if(!is_array($product_ids)) {
440 + $product_ids = [$product_ids];
441 + }
442 +
443 + $product_ids = array_combine($product_ids, $product_ids);
444 + unset($product_ids[$product_id]);
445 + $product_ids[] = $product_id;
446 +
447 + $cookie_value = implode(',', $product_ids);
448 +
449 + } else {
450 + $cookie_value = $product_id;
451 + }
452 +
453 + setcookie($cookie_name, $cookie_value, strtotime('+30 days'), '/' );
454 +
455 + $count_key = 'shopengine_product_views_count';
456 + $count = get_post_meta($product_id, $count_key, true);
457 +
458 + if($count == '') {
459 + $count = 1;
460 + delete_post_meta($product_id, $count_key);
461 + add_post_meta($product_id, $count_key, '1');
462 + } else {
463 + $count++;
464 + update_post_meta($product_id, $count_key, $count);
465 + }
466 + }
467 +
468 + /**
469 + * Public function js_css_public .
470 + * Include public function
471 + *
472 + * @since 1.0.0
473 + */
474 + public function js_css_public() {
475 + wp_register_style('shopengine-public', \ShopEngine::plugin_url() . 'assets/css/shopengine-public.css', false, \ShopEngine::version());
476 +
477 + // Modal Stylesheet
478 + wp_register_style('shopengine-modal-styles', \ShopEngine::plugin_url() . 'assets/css/shopengine-modal.css', false, \ShopEngine::version());
479 +
480 + // Modal Script
481 + wp_register_script('shopengine-modal-script', \ShopEngine::plugin_url() . 'assets/js/shopengine-modal.js', ['jquery'], \ShopEngine::version(), true);
482 +
483 + wp_enqueue_script('shopengine-simple-scrollbar.js-js', \ShopEngine::plugin_url() . 'assets/js/simple-scrollbar.js', [], \ShopEngine::version(), true);
484 + wp_enqueue_script('shopengine-filter-js', \ShopEngine::plugin_url() . 'assets/js/filter.js', [], \ShopEngine::version(), true);
485 + wp_enqueue_script('shopengine-js', \ShopEngine::plugin_url() . 'assets/js/public.js', [], \ShopEngine::version(), true);
486 +
487 +
488 + wp_localize_script('shopengine-js', 'shopEngineApiSettings', [
489 + 'resturl' => get_rest_url(),
490 + 'rest_nonce' => wp_create_nonce('wp_rest'),
491 + ]);
492 +
493 +
494 + /**
495 + * Registering libs css/js
496 + *
497 + */
498 +
499 + wp_register_style(
500 + 'lib-sqv-css',
501 + \ShopEngine::plugin_url() . '/assets/sqv/smart-quick-view.css',
502 + [],
503 + \ShopEngine::version()
504 + );
505 +
506 + wp_register_script(
507 + 'lib-sqv-js',
508 + \ShopEngine::plugin_url() . 'assets/sqv/smart-quick-view.js',
509 + ['jquery', 'wc-single-product'],
510 + \ShopEngine::version(),
511 + true
512 + );
513 + }
514 +
515 + public function js_css_elementor() {
516 + wp_enqueue_style('shopnegine-panel-icon', \ShopEngine::plugin_url() . 'assets/css/shopengine-icon.css', false, \ShopEngine::version());
517 +
518 + if('shopengine-template' === get_post_type()):
519 + wp_enqueue_style('shopnegine-editor-css', \ShopEngine::plugin_url() . 'assets/css/editor.css', false, \ShopEngine::version());
520 + endif;
521 + }
522 +
523 +
524 + public function missing_woocommerce() {
525 +
526 + if(!current_user_can('manage_options')) {
527 + return;
528 + }
529 +
530 + if(file_exists(WP_PLUGIN_DIR . '/woocommerce/woocommerce.php')) {
531 +
532 + $btn['label'] = esc_html__('Activate WooCommerce', 'shopengine');
533 + $btn['url'] = wp_nonce_url('plugins.php?action=activate&plugin=woocommerce/woocommerce.php&plugin_status=all&paged=1', 'activate-plugin_woocommerce/woocommerce.php');
534 +
535 + } else {
536 +
537 + $btn['label'] = esc_html__('Install WooCommerce', 'shopengine');
538 + $btn['url'] = wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=woocommerce'), 'install-plugin_woocommerce');
539 + }
540 +
541 + Utils\Notice::push(
542 + [
543 + 'id' => 'missing-woo',
544 + 'type' => 'error',
545 + 'dismissible' => true,
546 + 'is_required' => true,
547 + 'btn' => $btn,
548 + 'message' => sprintf(esc_html__('ShopEngine requires woocommerce Plugin, which is currently NOT RUNNING.', 'shopengine'), '4.1.0'),
549 + ]
550 + );
551 + }
552 +
553 +
554 + public function missing_elementor() {
555 +
556 + if(!current_user_can('manage_options')) {
557 + return;
558 + }
559 +
560 + if(file_exists(WP_PLUGIN_DIR . '/elementor/elementor.php')) {
561 +
562 + $btn['label'] = esc_html__('Activate Elementor', 'shopengine');
563 + $btn['url'] = wp_nonce_url('plugins.php?action=activate&plugin=elementor/elementor.php&plugin_status=all&paged=1', 'activate-plugin_elementor/elementor.php');
564 +
565 + } else {
566 +
567 + $btn['label'] = esc_html__('Install Elementor', 'shopengine');
568 + $btn['url'] = wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=elementor'), 'install-plugin_elementor');
569 + }
570 +
571 + if(file_exists(WP_PLUGIN_DIR . '/blocks-for-shopengine/shopengine-gutenberg-addon.php')) {
572 +
573 + $btn2['label'] = esc_html__('Activate Blocks for ShopEngine', 'shopengine');
574 + $btn2['url'] = wp_nonce_url('plugins.php?action=activate&plugin=blocks-for-shopengine/shopengine-gutenberg-addon.php&plugin_status=all&paged=1', 'activate-plugin_blocks-for-shopengine/shopengine-gutenberg-addon.php');
575 +
576 + } else {
577 +
578 + $btn2['label'] = esc_html__('Install Blocks for ShopEngine', 'shopengine');
579 + $btn2['url'] = wp_nonce_url(self_admin_url('update.php?action=install-plugin&plugin=blocks-for-shopengine'), 'install-plugin_blocks-for-shopengine');
580 + }
581 +
582 + Utils\Notice::push(
583 + [
584 + 'id' => 'missing-elementor',
585 + 'type' => 'error',
586 + 'is_required' => true,
587 + 'dismissible' => true,
588 + 'btn' => $btn,
589 + 'btn2' => $btn2,
590 + 'message' => esc_html__('To use ShopEngine, install Elementor (For the Elementor Builder) OR Blocks for ShopEngine (For Gutenberg Builder).', 'shopengine'),
591 + ]
592 + );
593 + }
594 +
595 +
596 + public function failed_elementor_version() {
597 +
598 + if(!current_user_can('manage_options')) {
599 + return;
600 + }
601 +
602 + $btn['label'] = esc_html__('Update Elementor', 'shopengine');
603 + $btn['url'] = wp_nonce_url(self_admin_url('update.php?action=upgrade-plugin&plugin=elementor'), 'upgrade-plugin_elementor');
604 +
605 + Utils\Notice::push(
606 + [
607 + 'id' => 'unsupported-elementor-version',
608 + 'type' => 'error',
609 + 'dismissible' => true,
610 + 'btn' => $btn,
611 + 'message' => sprintf(esc_html__('ShopEngine requires Elementor version %1$s+, which is currently NOT RUNNING.', 'shopengine'), '3.0.0'),
612 + ]
613 + );
614 + }
615 +
616 +
617 + public function flush_rewrites() {
618 + $form_cpt = new Core\Builders\Cpt();
619 + $form_cpt->flush_rewrites();
620 + }
621 +
622 +
623 + public static function instance() {
624 + if(!self::$instance) {
625 + self::$instance = new self();
626 + }
627 +
628 + return self::$instance;
629 + }
630 +}