PluginProbe
Solace Extra / 1.5.3
Solace Extra v1.5.3
1.7.1 1.7.0 1.6.2 1.6.1 1.6.0 1.5.3 trunk 1.0.8 1.1.0 1.1.1 1.1.2 1.1.3 1.1.4 1.1.5 1.1.7 1.1.8 1.1.9 1.2.1 1.2.2 1.3.0 1.3.1 1.3.2 1.3.3 1.5.0 1.5.1 All 26 releases
solace-extra / solace-extra.php

solace-extra.php in Solace Extra 1.5.3, at solace-extra.php

803 lines 31.2 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /**
3 * The plugin bootstrap file
4 *
5 * This file is read by WordPress to generate the plugin information in the plugin
6 * admin area. This file also includes all of the dependencies used by the plugin,
7 * registers the activation and deactivation functions, and defines a function
8 * that starts the plugin.
9 *
10 * @link https://solacewp.com
11 * @since 1.1.6
12 * @package Solace_Extra
13 *
14 * Plugin Name: Solace Extra
15 * Plugin URI: https://solacewp.com/
16 * Description: Additional features for Solace Theme
17 * Version: 1.5.3
18 * Requires PHP: 7.4
19 * Author: Solace
20 * Author URI: https://solacewp.com/
21 * License: GPL-2.0+
22 * License URI: http://www.gnu.org/licenses/gpl-2.0.txt
23 * Text Domain: solace-extra
24 * Domain Path: /languages
25 */
26
27 use \Elementor\Plugin as Elementor_Plugin;
28
29 // If this file is called directly, abort.
30 if ( ! defined( 'WPINC' ) ) {
31 die;
32 }
33
34 defined( 'ABSPATH' ) || exit;
35
36 /**
37 * Currently plugin version.
38 * Start at version 1.0.0 and use SemVer - https://semver.org
39 * Rename this for your plugin and update it as you release new versions.
40 */
41 define( 'SOLACE_EXTRA_VERSION', '1.5.3' );
42 define( 'SOLACE_EXTRA_DIR', plugin_dir_url( __FILE__ ) );
43 define( 'SOLACE_EXTRA_DIR_PATH', plugin_dir_path( __FILE__ ) );
44 define( 'SOLACE_EXTRA_ASSETS_URL', plugin_dir_url( __FILE__ ) . 'assets/' );
45 define( 'SOLACE_EXTRA_SLUG', dirname( plugin_basename( __FILE__ ) ) );
46 define( 'SOLACE_EXTRA_API_BASE_URL', 'https://solacewp.com/wp-json/solace/v1/' );
47 define( 'SOLACE_EXTRA_DEMO_IMPORT_URL', 'https://solacewp.com/' );
48 define( 'SOLACE_EXTRA_ELEMENTOR_ADDONS__FILE__', __FILE__ );
49 define( 'SOLACE_EXTRA_ELEMENTOR_ADDONS_BASE', plugin_basename( __FILE__ ) );
50 define( 'SOLACE_EXTRA_ELEMENTOR_ADDONS_DIR_PATH', plugin_dir_path( SOLACE_EXTRA_ELEMENTOR_ADDONS__FILE__ ) );
51 define( 'SOLACE_EXTRA_ELEMENTOR_ADDONS_DIR_URL', plugin_dir_url( SOLACE_EXTRA_ELEMENTOR_ADDONS__FILE__ ) );
52 define( 'SOLACE_EXTRA_ELEMENTOR_ADDONS_ASSETS', trailingslashit( SOLACE_EXTRA_ELEMENTOR_ADDONS_DIR_URL . 'assets' ) );
53 define( 'SOLACE_EXTRA_ELEMENTOR_ADDONS_WIDGET', trailingslashit( SOLACE_EXTRA_ELEMENTOR_ADDONS_DIR_PATH . 'widgets' ) );
54
55 // require plugin_dir_path( __FILE__ ) . 'classes/class-library-manager.php';
56 // require plugin_dir_path( __FILE__ ) . 'classes/class-library-source.php';
57
58 define( 'SOLACE_SITE_URL', urlencode( home_url() ) );
59 define( 'SOLACE_UPGRADE_BASE_URL', 'https://pro.solacewp.com/' );
60
61 define( 'SOLACE_UPGRADE_URL',
62 add_query_arg(
63 array(
64 'utm_source' => 'plugin',
65 'utm_medium' => 'upgrade_link',
66 'utm_campaign' => 'solace_free_to_pro',
67 'version' => SOLACE_EXTRA_VERSION,
68 'site_url' => SOLACE_SITE_URL,
69 ),
70 SOLACE_UPGRADE_BASE_URL
71 )
72 );
73 define( 'SOLACE_SUPPORT_URL',
74 add_query_arg(
75 array(
76 'utm_source' => 'plugin',
77 'utm_medium' => 'support_link',
78 'utm_campaign' => 'solace_free_to_pro',
79 'version' => SOLACE_EXTRA_VERSION,
80 'site_url' => SOLACE_SITE_URL,
81 ),
82 SOLACE_UPGRADE_BASE_URL . 'my-account/my-tickets'
83 )
84 );
85
86 global $solace_is_run_in_shortcode;
87
88 // set_time_limit(0);
89
90 /**
91 * The code that runs during plugin activation.
92 * This action is documented in includes/class-solace-extra-activator.php
93 */
94 function solace_extra_activate() {
95 add_option( 'solace_extra_redirect_after_activation_option', true );
96 require_once plugin_dir_path( __FILE__ ) . 'includes/class-solace-extra-activator.php';
97 Solace_Extra_Activator::activate();
98 }
99
100 /**
101 * The code that runs during plugin deactivation.
102 * This action is documented in includes/class-solace-extra-deactivator.php
103 */
104 function solace_extra_deactivate() {
105
106 // Delete the 'solace_disable_admin_notices' cookie directly
107 if ( isset( $_COOKIE['solace_disable_admin_notices'] ) ) {
108 // Set the cookie with an expiration time in the past to delete it
109 setcookie( 'solace_disable_admin_notices', '', time() - 3600 );
110 }
111
112 require_once plugin_dir_path( __FILE__ ) . 'includes/class-solace-extra-deactivator.php';
113 Solace_Extra_Deactivator::deactivate();
114 }
115
116 register_activation_hook( __FILE__, 'solace_extra_activate' );
117 register_deactivation_hook( __FILE__, 'solace_extra_deactivate' );
118
119 function solace_hide_hostinger_easy_onboarding_notice() {
120 echo '<style>
121 .hostinger-onboarding,
122 .hostinger-onboarding-reminder,
123 .hostinger-onboarding-notice,
124 #hostinger-easy-onboarding,
125 .hstm-admin-notice {
126 display: none !important;
127 }
128 </style>';
129 }
130
131 function solace_hostinger_easy_onboarding_notice() {
132 if ( ! function_exists( 'is_plugin_active' ) ) {
133 include_once( ABSPATH . 'wp-admin/includes/plugin.php' );
134 }
135
136 if ( is_plugin_active( 'hostinger-easy-onboarding/hostinger-easy-onboarding.php' ) ) {
137 add_action( 'admin_head', 'solace_hide_hostinger_easy_onboarding_notice' );
138 }
139 }
140 // phpcs:ignore WordPress.Security.NonceVerification.Recommended
141 if ( isset( $_GET['singleproduct'] ) ) {
142 add_action( 'admin_init', 'solace_hostinger_easy_onboarding_notice' );
143 }
144
145
146 /**
147 * The core plugin class that is used to define internationalization,
148 * admin-specific hooks, and public-facing site hooks.
149 */
150 require plugin_dir_path( __FILE__ ) . 'includes/class-solace-extra.php';
151
152 if (class_exists('Elementor\Plugin')) {
153 require plugin_dir_path( __FILE__ ) . 'elementor/widgets/elementor.php';
154 require_once( __DIR__ . '/elementor/widgets/controls/gradient-text.php' );
155 require_once( __DIR__ . '/elementor/widgets/functions.php' );
156 require_once( __DIR__ . '/elementor/widgets/woocommerce/functions.php' );
157
158 /**
159 * Registers Elementor widgets for the Solace Extra plugin.
160 *
161 * This function registers the Elementor List Widget and oEmbed Widget for use within the Solace Extra plugin.
162 *
163 * @param Elementor\Elements_Manager $widgets_manager The Elementor widgets manager.
164 */
165 function solace_extra_register_widget_elementor( $widgets_manager ) {
166 require_once( __DIR__ . '/elementor/widgets/widget/nav-menu/nav-menu.php' );
167 require_once( __DIR__ . '/elementor/widgets/widget/purchase-summary/purchase-summary.php' );
168 require_once( __DIR__ . '/elementor/widgets/widget/site-logo/site-logo.php' );
169 require_once( __DIR__ . '/elementor/widgets/widget/shop/shop.php' );
170 require_once( __DIR__ . '/elementor/widgets/widget/shop/cart.php' );
171 require_once( __DIR__ . '/elementor/widgets/widget/shop/minicart.php' );
172 require_once( __DIR__ . '/elementor/widgets/widget/shop/checkout.php' );
173 require_once( __DIR__ . '/elementor/widgets/widget/shop/myaccount.php' );
174 require_once( __DIR__ . '/elementor/widgets/widget/shop/related-product.php' );
175 require_once( __DIR__ . '/elementor/widgets/widget/shop/product-addtocart.php' );
176 require_once( __DIR__ . '/elementor/widgets/widget/shop/producttab.php' );
177 require_once( __DIR__ . '/elementor/widgets/widget/shop/separator.php' );
178 require_once( __DIR__ . '/elementor/widgets/widget/archive-posts/archive-posts.php' );
179 // require_once( __DIR__ . '/elementor/widgets/widget/form-builder/form-builder.php' );
180 require_once( __DIR__ . '/elementor/widgets/widget/post-author/post-author.php' );
181 require_once( __DIR__ . '/elementor/widgets/widget/post-categories/post-categories.php' );
182 // require_once( __DIR__ . '/elementor/widgets/widget/post-date/post-date.php' );
183 require_once( __DIR__ . '/elementor/widgets/widget/post-excerpt/post-excerpt.php' );
184 require_once( __DIR__ . '/elementor/widgets/widget/post-title/post-title.php' );
185 require_once( __DIR__ . '/elementor/widgets/widget/post-featuredimage/featuredimage.php' );
186 require_once( __DIR__ . '/elementor/widgets/widget/post-fullcontent/fullcontent.php' );
187 require_once( __DIR__ . '/elementor/widgets/widget/post-tags/post-tags.php' );
188 require_once( __DIR__ . '/elementor/widgets/widget/post-datetime/post-datetime.php' );
189 require_once( __DIR__ . '/elementor/widgets/widget/post-comments/post-comments.php' );
190 require_once( __DIR__ . '/elementor/widgets/widget/post-breadcrumb/post-breadcrumb.php' );
191 require_once( __DIR__ . '/elementor/widgets/widget/post-navigation/post-navigation.php' );
192 require_once( __DIR__ . '/elementor/widgets/widget/social-share/social-share.php' );
193 require_once( __DIR__ . '/elementor/widgets/widget/post-relatedpost/post-relatedpost.php' );
194
195 // Define the WooCommerce widgets directory.
196 $woocommerce_dir = __DIR__ . '/elementor/widgets/woocommerce';
197
198 // Check if the folder exists before proceeding.
199 if ( is_dir( $woocommerce_dir ) ) {
200 solace_extra_register_woocommerce_widgets_recursively( $woocommerce_dir, $widgets_manager );
201 }
202
203 $widgets_manager->register( new \Solace_Extra_Nav_Menu() );
204 $widgets_manager->register( new \Solace_Extra_Purchase_Summary() );
205 // $widgets_manager->register( new \Solace_Extra_Navigation_Menu() );
206 $widgets_manager->register( new \Solace_Extra_Site_Logo() );
207 $widgets_manager->register( new \Solace_Extra_WooCommerce_Shop() );
208 $widgets_manager->register( new \Solace_Extra_WooCommerce_Cart() );
209 $widgets_manager->register( new \Solace_Extra_WooCommerce_MiniCart() );
210 $widgets_manager->register( new \Solace_Extra_WooCommerce_MyAccount() );
211 $widgets_manager->register( new \Solace_Extra_WooCommerce_Checkout() );
212 // $widgets_manager->register( new \Solace_Extra_WooCommerce_AddToCart() );
213 $widgets_manager->register( new \Solace_Extra_WooCommerce_Related_Products() );
214 $widgets_manager->register( new \Solace_Extra_WooCommerce_ProductAddToCart() );
215 $widgets_manager->register( new \Solace_Extra_WooCommerce_ProductTab() );
216 $widgets_manager->register( new \Solace_Extra_WooCommerce_Separator() );
217
218 $widgets_manager->register( new \Solace_Extra_Post_Archive() );
219 // $widgets_manager->register( new \Solace_Form_Builder() );
220 $widgets_manager->register( new \Solace_Extra_Post_Author() );
221 $widgets_manager->register( new \Solace_Extra_Post_Categories() );
222 // $widgets_manager->register( new \Solace_Extra_Post_Date() );
223 $widgets_manager->register( new \Solace_Extra_Post_Excerpt() );
224 $widgets_manager->register( new \Solace_Extra_Post_Title() );
225 $widgets_manager->register( new \Solace_Extra_Post_Featured_Image() );
226 $widgets_manager->register( new \Solace_Extra_Post_Full_Content() );
227 $widgets_manager->register( new \Solace_Extra_Post_Tags() );
228 $widgets_manager->register( new \Solace_Extra_Post_Date_Time() );
229 $widgets_manager->register( new \Solace_Extra_Post_Comments() );
230 $widgets_manager->register( new \Solace_Extra_Post_Breadcrumb() );
231 $widgets_manager->register( new \Solace_Extra_Post_Navigation() );
232 $widgets_manager->register( new \Solace_Extra_Post_RelatedPost() );
233 $widgets_manager->register( new \Solace_Social_Share_Widget() );
234 }
235 add_action( 'elementor/widgets/register', 'solace_extra_register_widget_elementor' );
236
237
238 /**
239 * Adds a new category to the Elementor widgets manager for the Solace Extra plugin.
240 *
241 * This function adds a new category named 'Solace Extra' with an icon of 'eicon-star' to the Elementor widgets manager.
242 *
243 * @param Elementor\Elements_Manager $elements_manager The Elementor widgets manager.
244 */
245 function solace_extra_add_elementor_widget_categories( $elements_manager ) {
246
247 $elements_manager->add_category(
248 'solace-extra',
249 [
250 'title' => esc_html__( 'Solace Extra', 'solace-extra' ),
251 'icon' => 'eicon-star',
252 ]
253 );
254
255 foreach ( solace_extra_widget_categories() as $id => $data ) {
256 $elements_manager->add_category(
257 $id,
258 [
259 'title' => $data['title'],
260 'icon' => $data['icon'],
261 ]
262 );
263 }
264 }
265 add_action( 'elementor/elements/categories_registered', 'solace_extra_add_elementor_widget_categories' );
266
267 }
268
269 /**
270 * Begins execution of the plugin.
271 *
272 * Since everything within the plugin is registered via hooks,
273 * then kicking off the plugin from this point in the file does
274 * not affect the page life cycle.
275 *
276 * @since 1.0.0
277 */
278 function solace_extra_run() {
279 $plugin = new Solace_Extra();
280 $plugin->run();
281
282 // Include the dynamic tags functionality file located in the 'dynamic-tags' directory.
283 // require plugin_dir_path( __FILE__ ) . 'admin/dynamic-tags/dynamic-tags.php';
284
285 }
286 solace_extra_run();
287
288 add_action('init', 'solace_extra_handle_logo_upload');
289
290 function solace_extra_handle_logo_upload() {
291 // phpcs:ignore WordPress.Security.NonceVerification.Missing
292 if (isset($_POST['action']) && $_POST['action'] === 'upload_logo_image') {
293
294 // Verify the nonce to ensure the request is legitimate
295 if (!isset($_POST['solace_conditions_nonce']) || !wp_verify_nonce(sanitize_key(wp_unslash($_POST['solace_conditions_nonce'])), 'solace_conditions_nonce_action')) {
296 wp_send_json_error('Invalid nonce.');
297 return;
298 }
299 $method = !empty($_SERVER['REQUEST_METHOD']) ? sanitize_text_field(wp_unslash($_SERVER['REQUEST_METHOD'])) : '';
300
301 if ($method === 'POST') {
302 $image_url = ! empty( $_POST['logo_image_url'] ) ? esc_url_raw( wp_unslash( $_POST['logo_image_url'] ) ) : '';
303
304 // Use wp_remote_get() instead of file_get_contents()
305 $response = wp_remote_get($image_url);
306
307 if (is_wp_error($response)) {
308 // Handle request error
309 wp_die(esc_html('Logo download failed. Error: ' . $response->get_error_message()));
310 }
311
312 $body = wp_remote_retrieve_body($response);
313
314 // Upload the image to media library
315 $upload = wp_upload_bits(basename($image_url), null, $body);
316
317 if (!$upload['error']) {
318 // Attach the image to the media library
319 $attachment = array(
320 'post_mime_type' => wp_remote_retrieve_header($response, 'content-type'), // Use content-type from response
321 'post_title' => sanitize_file_name(basename($image_url)),
322 'post_content' => '',
323 'post_status' => 'inherit'
324 );
325
326 $attach_id = wp_insert_attachment($attachment, $upload['file']);
327
328 require_once ABSPATH . 'wp-admin/includes/image.php';
329 $attach_data = wp_generate_attachment_metadata($attach_id, $upload['file']);
330 wp_update_attachment_metadata($attach_id, $attach_data);
331
332 // Set the logo setting in Customizer
333 set_theme_mod('custom_logo', $attach_id);
334
335 // Redirect back to the page where the form was submitted
336 $referer = ! empty( $_SERVER['HTTP_REFERER'] ) ? esc_url_raw( wp_unslash( $_SERVER['HTTP_REFERER'] ) ) : '';
337 wp_safe_redirect( $referer );
338 exit();
339 } else {
340 // Handle upload error
341 wp_die(esc_html('Logo upload failed. Error: ' . $upload['error']));
342 }
343 }
344 }
345 }
346 add_action('wp_ajax_solace_extra_upload_logo', 'solace_extra_upload_logo');
347 add_action('wp_ajax_nopriv_solace_extra_upload_logo', 'solace_extra_upload_logo');
348
349 if ( ! function_exists( 'solace_is_run_in_shortcode' ) ) {
350
351 /**
352 * solace_is_run_in_shortcode - Returns true when posts run in from shortcode.
353 *
354 * @return bool
355 */
356 function solace_is_run_in_shortcode() {
357 global $solace_is_run_in_shortcode;
358
359 return $solace_is_run_in_shortcode;
360 }
361 }
362
363
364
365 // CODE FOR SITE-BUILDER IS BEGIN HERE
366
367 function solace_register_sitebuilder_post_type() {
368 $labels = array(
369 'name' => _x( 'Site Builder Parts', 'Post type general name', 'solace-extra' ),
370 'singular_name' => _x( 'Site Builder Part', 'Post type singular name', 'solace-extra' ),
371 'menu_name' => _x( 'Website Parts', 'Admin Menu text', 'solace-extra' ),
372 'name_admin_bar' => _x( 'Site Builder Part', 'Add New on Toolbar', 'solace-extra' ),
373 'add_new' => __( 'Create New', 'solace-extra' ),
374 'add_new_item' => __( 'Create New Site Builder Part', 'solace-extra' ),
375 'new_item' => __( 'New Site Builder Part', 'solace-extra' ),
376 'edit_item' => __( 'Edit Site Builder Part', 'solace-extra' ),
377 'view_item' => __( 'View Site Builder Part', 'solace-extra' ),
378 'all_items' => __( 'All Site Builder Parts', 'solace-extra' ),
379 'search_items' => __( 'Search Site Builder Parts', 'solace-extra' ),
380 'not_found' => __( 'No site builder parts found.', 'solace-extra' ),
381 'not_found_in_trash' => __( 'No site builder parts found in Trash.', 'solace-extra' ),
382 );
383
384 $args = array(
385 'labels' => $labels,
386 'public' => true,
387 // 'show_in_menu' => true,
388 'show_in_menu' => 'dashboard', // Set as submenu of Solace menu
389 'menu_position' => 25,
390 // 'rewrite' => array('slug' => 'solace-sitebuilder'),
391 'capability_type' => 'post',
392 'menu_icon' => 'dashicons-editor-code',
393 'supports' => array('title', 'editor', 'thumbnail'),
394
395 'has_archive' => false,
396 'exclude_from_search'=> true,
397 'publicly_queryable' => true,
398 );
399 solace_add_elementor_cpt_support();
400
401 register_post_type( 'solace-sitebuilder', $args );
402 flush_rewrite_rules();
403
404 }
405 add_action( 'init', 'solace_register_sitebuilder_post_type' );
406
407 function solace_add_admin_menus() {
408
409 add_submenu_page(
410 'solace',
411 __('Site Builder Parts', 'solace-extra'),
412 __('Site Builder Parts', 'solace-extra'),
413 'manage_options', // Capability
414 'edit.php?post_type=solace-sitebuilder' // URL submenu
415 );
416 }
417 // add_action('admin_menu', 'solace_add_admin_menus');
418
419 function solace_add_elementor_cpt_support() {
420
421 if ( ! is_admin() ) {
422 return;
423 }
424
425 $cpt_support = get_option( 'elementor_cpt_support' );
426
427 if ( ! $cpt_support ) {
428 update_option( 'elementor_cpt_support', array( 'post', 'page', 'solace-sitebuilder' ) );
429 } elseif ( ! in_array( 'solace-sitebuilder', $cpt_support, true ) ) {
430 $cpt_support[] = 'solace-sitebuilder';
431 update_option( 'elementor_cpt_support', $cpt_support );
432 }
433
434 }
435 // Add Elementor support for the custom post type
436 function solace_add_elementor_support_for_sitebuilder() {
437 \Elementor\Plugin::instance()->elements_manager->add_category(
438 'solace-sitebuilder',
439 array(
440 'title' => __( 'Site Builder Parts', 'solace-extra' ),
441 'icon' => 'fa fa-plug',
442 ),
443 1
444 );
445 }
446 add_action( 'elementor/elements/categories_registered', 'solace_add_elementor_support_for_sitebuilder' );
447
448 require plugin_dir_path( __FILE__ ) . 'sitebuilder/sitebuilder.php';
449
450 // add_action('wp_head', 'solace_display_custom_header');
451
452 function solace_check_import_status() {
453 $status = get_option('solace_extra_import_zip_complete', false);
454 wp_send_json([
455 'completed' => (bool) $status
456 ]);
457 exit;
458 }
459 add_action('wp_ajax_check_import_status', 'solace_check_import_status');
460 add_action('wp_ajax_nopriv_check_import_status', 'solace_check_import_status');
461
462
463 function solace_disable_image_processing() {
464 if (defined('DOING_AJAX') && DOING_AJAX) {
465 // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped,WordPress.Security.NonceVerification.Recommended,WordPress.Security.NonceVerification.Missing
466 $action = isset($_GET['action']) ? sanitize_key(wp_unslash($_GET['action'])) :
467 (isset($_POST['action']) ? sanitize_key(wp_unslash($_POST['action'])) : 'tidak_terdeteksi');
468 // phpcs:enable
469 if ($action === 'wp_import_posts_process') {
470 add_filter('intermediate_image_sizes_advanced', 'solace_disable_sizes');
471 } else {
472 }
473
474 }
475 // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped,WordPress.Security.NonceVerification.Recommended
476 else if (isset($_GET['page']) && $_GET['page'] === 'dashboard-progress') {
477 add_filter('intermediate_image_sizes_advanced', 'solace_disable_sizes');
478 }
479 // phpcs:enable
480 }
481
482 function solace_disable_sizes($sizes) {
483 return [];
484 }
485
486 solace_disable_image_processing();
487
488 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Used as cron callback, name kept for compatibility
489 function generate_all_thumbnails_for_all_images() {
490 $args = array(
491 'post_type' => 'attachment',
492 'post_mime_type' => 'image',
493 'posts_per_page' => -1,
494 'post_status' => 'any',
495 );
496
497 $query = new WP_Query( $args );
498
499 if ( $query->have_posts() ) {
500
501 while ( $query->have_posts() ) {
502 $query->the_post();
503 $image_id = get_the_ID();
504 generate_thumbnails_for_single_image( $image_id );
505 }
506
507 wp_reset_postdata();
508
509 } else {
510 }
511 }
512
513 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedFunctionFound -- Used as cron callback, name kept for compatibility
514 function generate_thumbnails_for_single_image( $image_id ) {
515 if ( ! wp_attachment_is_image( $image_id ) ) {
516 return false;
517 }
518
519 $file_path = get_attached_file( $image_id );
520 if ( ! $file_path || ! file_exists( $file_path ) ) {
521 return false;
522 }
523
524 $sizes = array(
525 'solace-single2' => array( 2000, 975 ),
526 'solace-single-default' => array( 1220, 715 ),
527 'solace-default-blog' => array( 1214, 715 ),
528 'solace-related-posts' => array( 250, 277 ),
529 'solace-wc-shop-layout3-layout4-layout6' => array( 350, 500 ),
530
531 'thumbnail' => array( (int) get_option( 'thumbnail_size_w' ), (int) get_option( 'thumbnail_size_h' ) ),
532 'medium' => array( (int) get_option( 'medium_size_w' ), (int) get_option( 'medium_size_h' ) ),
533 'medium_large' => array( (int) get_option( 'medium_large_size_w' ), (int) get_option( 'medium_large_size_h' ) ),
534 'large' => array( (int) get_option( 'large_size_w' ), (int) get_option( 'large_size_h' ) ),
535 );
536
537 $metadata = wp_get_attachment_metadata( $image_id );
538
539 if ( isset( $metadata['sizes'] ) ) {
540 foreach ( $metadata['sizes'] as $size_name => $size_data ) {
541 if ( isset( $sizes[$size_name] ) ) {
542 $file = dirname( $file_path ) . '/' . $size_data['file'];
543 if ( file_exists( $file ) ) {
544 wp_delete_file( $file );
545
546 }
547 }
548 }
549 }
550
551 foreach ( $sizes as $size_name => $dimensions ) {
552 $thumbnail = image_make_intermediate_size( $file_path, $dimensions[0], $dimensions[1], true );
553 if ( $thumbnail ) {
554 $metadata['sizes'][$size_name] = array(
555 'file' => basename( $thumbnail['file'] ),
556 'width' => $thumbnail['width'],
557 'height' => $thumbnail['height'],
558 'mime-type' => get_post_mime_type( $image_id ),
559 );
560 wp_update_attachment_metadata( $image_id, $metadata );
561 } else {
562 }
563 }
564 }
565
566
567 add_action('wp', function() {
568 // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped,WordPress.Security.NonceVerification.Recommended
569 if (isset($_GET['page']) && $_GET['page'] === 'dashboard-congratulations') {
570 if (!wp_next_scheduled('generate_thumbnails_cron')) {
571
572 wp_schedule_single_event(time() + 10, 'generate_thumbnails_cron');
573
574 }
575 }
576 // phpcs:enable
577 });
578
579 add_action('generate_thumbnails_cron', function() {
580 if (get_transient('thumbnails_cron_running')) {
581 return;
582 }
583
584 set_transient('thumbnails_cron_running', true, 0);
585 // phpcs:ignore Squiz.PHP.DiscouragedFunctions.Discouraged
586 set_time_limit(0);
587 ignore_user_abort(true);
588
589
590 $unfinished_jobs = get_transient('unfinished_thumbnails');
591
592 if (empty($unfinished_jobs)) {
593 $args = array(
594 'post_type' => 'attachment',
595 'post_mime_type' => 'image',
596 'post_status' => 'any',
597 'posts_per_page' => -1,
598 'nopaging' => true,
599 );
600
601 remove_all_filters('posts_clauses');
602 delete_transient('unfinished_thumbnails');
603
604 $query = new WP_Query($args);
605 $unfinished_jobs = [];
606
607 if ($query->have_posts()) {
608 while ($query->have_posts()) {
609 $query->the_post();
610 $unfinished_jobs[] = get_the_ID();
611 }
612 wp_reset_postdata();
613 }
614
615 set_transient('unfinished_thumbnails', $unfinished_jobs, 3600);
616 }
617
618 if (!empty($unfinished_jobs)) {
619 $image_id = array_shift($unfinished_jobs);
620 set_transient('unfinished_thumbnails', $unfinished_jobs, 3600);
621
622 generate_thumbnails_for_single_image($image_id);
623
624 if (!empty($unfinished_jobs)) {
625 wp_schedule_single_event(time() + 10, 'generate_thumbnails_cron');
626 } else {
627 delete_transient('unfinished_thumbnails');
628 }
629 }
630
631 delete_transient('thumbnails_cron_running');
632 });
633
634
635 add_action('admin_init', function() {
636 // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped,WordPress.Security.NonceVerification.Recommended
637 if (isset($_GET['page']) && $_GET['page'] === 'dashboard-progress') {
638 foreach (_get_cron_array() as $timestamp => $cron) {
639 foreach ($cron as $hook => $events) {
640 if (strpos($hook, 'generate_thumbnails_cron') !== false) {
641 wp_unschedule_event($timestamp, $hook);
642 }
643 }
644 }
645
646 delete_transient('unfinished_thumbnails');
647 delete_transient('thumbnails_cron_running');
648
649 }
650 // phpcs:enable
651 });
652
653 add_action('admin_init', function() {
654 // phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped,WordPress.Security.NonceVerification.Recommended
655 if (isset($_GET['page']) && $_GET['page'] === 'dashboard-congratulations') {
656
657 $cron_url = admin_url('admin-ajax.php?action=run_generate_thumbnails_cron');
658 wp_remote_post($cron_url, array('blocking' => false));
659
660 if (!wp_next_scheduled('generate_thumbnails_cron')) {
661 wp_schedule_single_event(time(), 'generate_thumbnails_cron');
662 }
663 }
664 // phpcs:enable
665 });
666
667
668 add_action('wp_ajax_run_generate_thumbnails_cron', function() {
669 if (get_transient('thumbnails_cron_running')) {
670 wp_send_json_error('Proses sudah berjalan.');
671 return;
672 }
673
674 set_transient('thumbnails_cron_running', true, 3600);
675
676 // phpcs:ignore WordPress.NamingConventions.PrefixAllGlobals.NonPrefixedHooknameFound -- Plugin cron hook, name kept for compatibility
677 do_action('generate_thumbnails_cron');
678
679 wp_send_json_success('Proses generate thumbnail dimulai di background.');
680 });
681
682 add_action('wp_ajax_woocommerce_ajax_add_to_cart', 'solace_custom_ajax_add_to_cart');
683 add_action('wp_ajax_nopriv_woocommerce_ajax_add_to_cart', 'solace_custom_ajax_add_to_cart');
684
685 function solace_custom_ajax_add_to_cart() {
686 // phpcs:ignore WordPress.Security.NonceVerification.Missing
687 if (!isset($_POST['product_id'])) {
688 wp_send_json_error(['error' => true, 'message' => 'Product ID is missing.']);
689 }
690
691 // phpcs:ignore WordPress.Security.NonceVerification.Missing
692 $product_id = absint($_POST['product_id']);
693
694 // phpcs:ignore WordPress.Security.NonceVerification.Missing
695 $quantity = isset($_POST['quantity']) ? absint($_POST['quantity']) : 1;
696
697 $added = WC()->cart->add_to_cart($product_id, $quantity);
698
699 if ($added) {
700 wp_send_json_success([
701 'success' => true,
702 'product_url' => wc_get_cart_url()
703 ]);
704 } else {
705 wp_send_json_error([
706 'error' => true,
707 'product_url' => get_permalink($product_id),
708 'message' => 'Failed to add product to cart.'
709 ]);
710 }
711
712 wp_die();
713 }
714 add_action( 'admin_menu', 'solace_register_theme_submenu_dashboard_upgrade_support',999 );
715
716 function solace_register_theme_submenu_dashboard_upgrade_support() {
717 if ( ! function_exists( 'solace_pro_card' ) ) {
718 add_submenu_page(
719 'solace',
720 __( 'Upgrade', 'solace-extra' ),
721 __( 'Upgrade', 'solace-extra' ),
722 'manage_options',
723 'solace-upgrade-link',
724 '__return_null'
725 );
726 }
727
728 $saved_key = get_option( 'solace_license_key', '' );
729 $license_info = false;
730 $license_valid = false;
731
732 if ( ! empty( $saved_key ) && function_exists( 'solace_check_license' ) ) {
733 $license_info = solace_check_license( $saved_key );
734
735 if ( $license_info && isset( $license_info->license ) && $license_info->license === 'valid' ) {
736 $license_valid = true;
737 }
738 }
739
740 if ( $license_valid ) {
741 add_submenu_page(
742 'solace',
743 __( 'Support', 'solace-extra' ),
744 __( 'Support', 'solace-extra' ),
745 'manage_options',
746 'solace-support-link',
747 '__return_null'
748 );
749 }
750 }
751
752 add_action('admin_footer', function() {
753 ?>
754 <script type="text/javascript">
755 jQuery(document).ready(function($){
756 $('a[href="admin.php?page=solace-upgrade-link"]').closest('li').addClass('upgrade-menu-item');
757 $('a[href="admin.php?page=solace-upgrade-link"]')
758 .attr('href', '<?php echo esc_js( esc_url( SOLACE_UPGRADE_URL ) ); ?>')
759 .attr('target','_blank');
760 });
761 </script>
762 <script type="text/javascript">
763 jQuery(document).ready(function($){
764 $('a[href="admin.php?page=solace-support-link"]').closest('li').addClass('support-menu-item');
765 $('a[href="admin.php?page=solace-support-link"]')
766 .attr('href', '<?php echo esc_js( esc_url( SOLACE_SUPPORT_URL ) ); ?>')
767 .attr('target','_blank');
768 });
769 </script>
770 <?php
771 });
772
773 add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), 'solace_plugin_action_links' );
774
775 function solace_plugin_action_links( $links ) {
776 $saved_key = get_option( 'solace_license_key' );
777
778 $license_status = 'inactive';
779
780 if ( ! empty( $saved_key ) && function_exists( 'solace_check_license' ) ) {
781 $license_info = solace_check_license( $saved_key );
782
783 if ( $license_info && isset( $license_info->license ) ) {
784 $license_status = $license_info->license;
785 }
786 }
787
788 if ( $license_status !== 'valid' ) {
789 $upgrade_link = sprintf(
790 '<a href="%s" target="_blank"
791 style="background:#ff8f00; color:#fff; font-weight:bold; padding:4px 8px; margin-right:5px;
792 border-radius:4px; text-decoration:none;">
793 %s
794 </a>',
795 esc_url( SOLACE_UPGRADE_URL ),
796 esc_html__( 'Upgrade', 'solace-extra' )
797 );
798
799 $links[] = $upgrade_link;
800 }
801
802 return $links;
803 }