PluginProbe
Forumax – AI Powered Advanced Community Forum Plugin / 2.5.0
Forumax – AI Powered Advanced Community Forum Plugin v2.5.0
2.5.0 2.4.4 2.4.3 2.4.2 2.4.1 2.4.0 trunk 1.0.8 1.1.0 1.2.1 1.2.2 1.2.3 1.2.4 1.2.5 1.2.6 1.2.7 1.2.8 1.2.9 1.3.0 1.3.1 1.3.2 1.3.3 1.4.0 1.4.1 2.0.0 All 30 releases
bbp-core / forumax.php

forumax.php in Forumax – AI Powered Advanced Community Forum Plugin 2.5.0, at forumax.php

700 lines 21.9 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Forumax
4 Plugin URI: https://forumax.spider-themes.net/
5 Description: Forumax is forum software for community discussions with public and private replies, private chats, voting, solved topics and more.
6 Author: spider-themes
7 Author URI: https://forumax.spider-themes.net/
8 Text Domain: forumax
9 Version: 2.5.0
10 Requires at least: 5.0
11 Tested up to: 7.1.2
12 Requires PHP: 7.4
13 License: GPLv3 or later
14 License URI: https://www.gnu.org/licenses/gpl-3.0.html
15 */
16
17 defined( 'ABSPATH' ) || exit;
18
19 // Load bbPress very early so other plugins (like docy-core) can detect it
20 // This must happen before the Forumax class to ensure proper load order
21 if ( ! class_exists( 'bbPress' ) ) {
22 require_once __DIR__ . '/lib/bbpress/bbpress.php';
23 }
24
25 if ( function_exists( 'bc_fs' ) ) {
26 // Forumax Pro already booted the Freemius SDK. Register this (free) plugin's
27 // file with the shared instance instead of initializing a second time. This
28 // keeps the free/premium pairing working regardless of which plugin loads first.
29 bc_fs()->set_basename( false, __FILE__ );
30 } else {
31 // Create a helper function for easy SDK access.
32 function bc_fs() {
33 global $bc_fs;
34
35 if ( ! isset( $bc_fs ) ) {
36 // Include Freemius SDK.
37 require_once __DIR__ . '/vendor/freemius/wordpress-sdk/start.php';
38
39 $bc_fs = fs_dynamic_init(
40 array(
41 'id' => '10864',
42 'slug' => 'forumax',
43 'premium_slug' => 'forumax-premium',
44 'type' => 'plugin',
45 'public_key' => 'pk_41277ad11125f6e2a1b4e66f40164',
46 'is_premium' => false,
47 'premium_suffix' => 'Pro',
48 'has_premium_version' => true,
49 'has_addons' => false,
50 'has_paid_plans' => true,
51 'parallel_activation' => array(
52 'enabled' => true,
53 'premium_version_basename' => 'forumax-premium/forumax.php',
54 ),
55 'trial' => array(
56 'days' => 14,
57 'is_require_payment' => true,
58 ),
59 'menu' => array(
60 'slug' => 'forumax',
61 'contact' => false,
62 'support' => false,
63 'first-path' => 'admin.php?page=forumax',
64 ),
65 )
66 );
67 }
68
69 return $bc_fs;
70 }
71
72 // Add filter to hide the Freemius badge from the plugin page.
73 bc_fs()->add_filter( 'hide_freemius_powered_by', '__return_true' );
74
75 // Disclose that opting in also pre-fills the in-plugin support chat
76 // (see the Support Assistant class). The on-update screen falls back to this filter.
77 bc_fs()->add_filter( 'connect_message', function ( $message ) {
78 return $message . '<br><br>' . esc_html__( 'Opting in also pre-fills your name and email in the Forumax support chat, so you can get help without typing them. They are only sent to our helpdesk when you open the chat.', 'forumax' );
79 } );
80
81 // Keep the free and premium versions from auto-deactivating each other.
82 bc_fs()->add_filter( 'deactivate_on_activation', '__return_false' );
83
84 // Suppress Freemius update row modification to avoid double notices or licensing nags on the plugins page.
85 add_action(
86 'admin_init',
87 function () {
88 if ( function_exists( 'bc_fs' ) ) {
89 $updater = FS_Plugin_Updater::instance( bc_fs() );
90 $basename = bc_fs()->get_plugin_basename();
91 remove_action( "after_plugin_row_{$basename}", array( $updater, 'catch_plugin_update_row' ), 9 );
92 remove_action( "after_plugin_row_{$basename}", array( $updater, 'edit_and_echo_plugin_update_row' ), 11 );
93 }
94 }
95 );
96
97 // Signal that SDK was initiated.
98 do_action( 'bc_fs_loaded' );
99 }
100
101 require_once __DIR__ . '/autoloader.php';
102
103 /**
104 * Plugin's heart
105 */
106 final class Forumax {
107
108 const VERSION = '2.5.0';
109
110 /**
111 * Class constructor.
112 */
113 public function __construct() {
114
115 $this->define_constants();
116 $this->core_includes();
117
118 register_activation_hook( __FILE__, array( $this, 'activate' ) );
119 register_deactivation_hook( __FILE__, array( $this, 'deactivate' ) );
120 add_action( 'plugins_loaded', array( $this, 'init_plugin' ) );
121 add_action( 'after_setup_theme', array( $this, 'load_csf_files' ), 20 );
122 add_action( 'admin_init', array( $this, 'redirect_to_setup_wizard' ) );
123 add_action( 'upgrader_process_complete', array( $this, 'migrate_plugin_basename' ), 10, 2 );
124
125 // Added Documentation links to plugin row meta
126 add_filter( 'plugin_row_meta', array( $this, 'forumax_row_meta' ), 10, 2 );
127
128 // Prevent deactivation if Forumax Pro is active
129 add_action( 'admin_init', array( $this, 'prevent_deactivation_if_pro_active' ) );
130 add_filter( 'plugin_action_links_' . plugin_basename( __FILE__ ), array( $this, 'modify_deactivate_link' ), 10, 4 );
131
132 /**
133 * Removes admin notices on the Forumax Forum builder page.
134 *
135 * @return void
136 */
137 add_action(
138 'admin_head',
139 function () {
140 // Get the current screen
141 $screen = get_current_screen();
142
143 // Check if the current screen is for your plugin page
144 if ( isset( $_GET['page'] ) && in_array( $_GET['page'], array( 'forumax', 'forumax-builder', 'forumax-settings' ), true ) ) {
145 // Remove admin notices
146 remove_all_actions( 'admin_notices' );
147 remove_all_actions( 'all_admin_notices' );
148
149 // Re-add a specific notice
150 if ( ! forumax_is_premium() && forumax_is_plugin_installed_for_days( 12 ) ) {
151 add_action( 'admin_notices', 'forumax_offer_notice' );
152 }
153 }
154 }
155 );
156 }
157
158 /**
159 * Define Plugin Constants.
160 *
161 * @return void
162 */
163 public function define_constants() {
164 define( 'FORUMAX_VERSION', self::VERSION );
165 define( 'FORUMAX_FILE', __FILE__ );
166 define( 'FORUMAX_DIR', __DIR__ . '/' );
167 define( 'FORUMAX_PATH', FORUMAX_DIR );
168 define( 'FORUMAX_URL', plugins_url( '/', __FILE__ ) );
169 define( 'FORUMAX_ASSETS', FORUMAX_URL . 'assets/' );
170 define( 'FORUMAX_FRONT_ASS', FORUMAX_URL . 'assets/frontend/' );
171 define( 'FORUMAX_ADMIN_ASS', FORUMAX_ASSETS . 'admin/' );
172 define( 'FORUMAX_STYLES', FORUMAX_URL . 'build/styles/' );
173 define( 'FORUMAX_IMG', FORUMAX_ASSETS . 'img/' );
174 define( 'FORUMAX_VEND', FORUMAX_ASSETS . 'vendors/' );
175 }
176
177 /**
178 * File includes.
179 */
180 public function core_includes() {
181 // Smart bbPress nVerify compatibility layer
182 require_once __DIR__ . '/includes/sbv-compatibility.php';
183
184 // Docy Core compatibility layer (fixes Forums widget class not found error)
185 require_once __DIR__ . '/includes/docy-core-compatibility.php';
186
187 // Keep single-topic theme-compat from loading every topic/reply.
188 require_once __DIR__ . '/includes/topic-render-guard.php';
189
190 // Stop EazyDocs is_super_admin() from recursing during author cap checks.
191 require_once __DIR__ . '/includes/eazydocs-compatibility.php';
192
193 require_once __DIR__ . '/includes/functions.php';
194
195 require_once __DIR__ . '/includes/template-functions.php';
196 require_once __DIR__ . '/includes/bbpress-config.php';
197
198 // Full Site Editing (block theme) compatibility – fixes blank page with Twenty Twenty-Five etc.
199 require_once __DIR__ . '/includes/fse-compatibility.php';
200
201 require_once __DIR__ . '/includes/admin/menu/Approve_Topic.php';
202 require_once __DIR__ . '/includes/admin/menu/Create_Forum.php';
203 require_once __DIR__ . '/includes/admin/menu/Create_Topic.php';
204 require_once __DIR__ . '/includes/admin/menu/Delete_Forum.php';
205 require_once __DIR__ . '/includes/admin/menu/Delete_Topic.php';
206 require_once __DIR__ . '/includes/Elementor/Forumax_Widgets.php';
207 require_once __DIR__ . '/includes/ajax_actions.php';
208 include_once ABSPATH . 'wp-admin/includes/plugin.php';
209
210 require_once __DIR__ . '/widgets/widgets.php';
211 require_once __DIR__ . '/includes/Blocks/Blocks_Register.php';
212 new \admin\Blocks\Blocks_Register();
213 require_once __DIR__ . '/includes/Elementor/inc/forum-ajax.php';
214
215 // Core installer notice
216 require_once __DIR__ . '/includes/admin/notices/_notices.php';
217
218 // Register Pro Widgets
219 $theme = wp_get_theme();
220
221 if ( 'Ama' !== $theme->get( 'Name' ) || ! forumax_is_premium() ) {
222 require_once __DIR__ . '/includes/admin/Pro_El_Widget_Map.php';
223 require_once __DIR__ . '/includes/admin/Pro_El_Widget_Service.php';
224 }
225
226 // Hooks
227 require FORUMAX_DIR . 'includes/hooks/actions.php';
228 require FORUMAX_DIR . 'includes/hooks/image_sizes.php';
229 require FORUMAX_DIR . 'includes/login-form.php';
230
231 require FORUMAX_DIR . '/includes/classes/Forumax_Forum_Class.php';
232 }
233
234 /**
235 * Initializing Forumax class.
236 *
237 * @return \Forumax
238 */
239 static function init() {
240 static $instance = false;
241
242 if ( ! $instance ) {
243 $instance = new self();
244 }
245 }
246
247 /**
248 * Actions on plugin activation.
249 *
250 * @return void
251 */
252 public function activate() {
253 $installed = get_option( 'bbpc_installed' );
254 if ( ! $installed ) {
255 update_option( 'bbpc_installed', time() );
256 }
257
258 update_option( 'bbpc_version', FORUMAX_VERSION );
259
260 // Ensure default option for forumax_settings
261 $defaults = array(
262 'is_bbpc_insert_media' => false,
263 );
264
265 $current = get_option( 'bbp_core_settings', array() );
266 $updated = wp_parse_args( $current, $defaults );
267
268 update_option( 'bbp_core_settings', $updated );
269
270 // Migrate old docy-core widgets to Forumax widgets
271 $this->migrate_docy_core_widgets();
272
273 // Set transient to redirect to setup wizard
274 set_transient( 'forumax_activation_redirect', true, 30 );
275 }
276
277 /**
278 * Actions on plugin deactivation.
279 *
280 * @return void
281 */
282 public function deactivate() {
283 wp_clear_scheduled_hook( 'frmx_auto_close_stale_topics' );
284 }
285
286 /**
287 * Redirect to setup wizard after plugin activation.
288 *
289 * @return void
290 */
291 public function redirect_to_setup_wizard() {
292 // Check if we should redirect
293 if ( ! get_transient( 'forumax_activation_redirect' ) ) {
294 return;
295 }
296
297 // Don't redirect if activating multiple plugins or doing ajax
298 if ( isset( $_GET['activate-multi'] ) || wp_doing_ajax() ) {
299 delete_transient( 'forumax_activation_redirect' );
300 return;
301 }
302
303 // Don't redirect if user doesn't have permission
304 if ( ! current_user_can( 'manage_options' ) ) {
305 delete_transient( 'forumax_activation_redirect' );
306 return;
307 }
308
309 // Don't redirect while Freemius SDK is in activation/opt-in mode.
310 // Freemius removes all submenu pages during activation mode, so
311 // redirecting to forumax-setup would hit a non-existent page and
312 // trigger "Sorry, you are not allowed to access this page."
313 // The transient is preserved so the redirect fires after the
314 // user completes or skips the Freemius opt-in.
315 if ( function_exists( 'bc_fs' ) && bc_fs()->is_activation_mode() ) {
316 return;
317 }
318
319 // Delete the transient so we don't redirect again
320 delete_transient( 'forumax_activation_redirect' );
321
322 // Redirect to setup wizard
323 wp_safe_redirect( admin_url( 'admin.php?page=forumax-setup' ) );
324 exit;
325 }
326
327 /**
328 * Migrate plugin basename if the folder name changes during update.
329 *
330 * @param WP_Upgrader $upgrader_object
331 * @param array $options
332 * @return void
333 */
334 public function migrate_plugin_basename( $upgrader_object, $options ) {
335 if ( isset( $options['action'] ) && $options['action'] === 'update' && isset( $options['type'] ) && $options['type'] === 'plugin' ) {
336 $active_plugins = get_option( 'active_plugins' );
337 if ( ! is_array( $active_plugins ) ) {
338 return;
339 }
340
341 $changed = false;
342 $migrations = array(
343 'bbp-core/bbp-core.php' => 'forumax/forumax.php',
344 'bbp-core/forumax.php' => 'forumax/forumax.php',
345 'bbp-core-pro/bbp-core.php' => 'forumax-pro/forumax.php',
346 'forumax-premium/bbp-core.php' => 'forumax-pro/forumax.php',
347 'forumax-premium/forumax.php' => 'forumax-pro/forumax.php',
348 );
349
350 foreach ( $migrations as $old_basename => $new_basename ) {
351 $key = array_search( $old_basename, $active_plugins, true );
352 if ( false !== $key ) {
353 // Only migrate if the new file actually exists.
354 if ( file_exists( WP_PLUGIN_DIR . '/' . $new_basename ) ) {
355 $active_plugins[ $key ] = $new_basename;
356 $changed = true;
357 }
358 }
359 }
360
361 if ( $changed ) {
362 update_option( 'active_plugins', array_values( $active_plugins ) );
363 }
364 }
365 }
366
367 /**
368 * Migrate old Docy Core Forums widgets to Forumax widgets
369 *
370 * This function automatically converts any existing docy-core Forums widgets
371 * to the new Forumax Forums List widgets to ensure seamless transition.
372 *
373 * @return void
374 */
375 private function migrate_docy_core_widgets() {
376 // Get all sidebars and their widgets
377 $sidebars_widgets = get_option( 'sidebars_widgets', array() );
378 $widget_migrated = false;
379
380 // Get old docy-core widget settings
381 // WordPress stores widget settings with lowercase class name and hyphens
382 $old_widget_option_key = 'widget_docycore-wpwidgets-forums';
383 $old_widget_options = get_option( $old_widget_option_key, array() );
384
385 // New Forumax widget option key
386 $new_widget_option_key = 'widget_forumax-wpwidgets-forumax_forums_list';
387 $new_widget_options = get_option( $new_widget_option_key, array() );
388
389 // Loop through each sidebar
390 foreach ( $sidebars_widgets as $sidebar_id => $widgets ) {
391 if ( $sidebar_id === 'wp_inactive_widgets' || $sidebar_id === 'array_version' || ! is_array( $widgets ) ) {
392 continue;
393 }
394
395 // Loop through widgets in this sidebar
396 foreach ( $widgets as $key => $widget_id ) {
397 // WordPress widget ID format: {widget_base_id}-{instance_number}
398 // Example: docycore-wpwidgets-forums-2
399
400 // Check if this is an old docy-core Forums widget
401 // Possible formats:
402 // - docycore-wpwidgets-forums-{number}
403 // - widget_docycore-wpwidgets-forums-{number}
404 if ( preg_match( '/^(widget_)?docycore-wpwidgets-forums-(\d+)$/', $widget_id, $matches ) ) {
405 $instance_number = $matches[2];
406
407 // Check if old widget has settings
408 if ( isset( $old_widget_options[ $instance_number ] ) ) {
409 // Copy settings to new Forumax widget
410 $new_widget_options[ $instance_number ] = $old_widget_options[ $instance_number ];
411
412 // Update the widget ID in sidebar
413 // New format: forumax-wpwidgets-forumax_forums_list-{number}
414 $new_widget_id = 'forumax-wpwidgets-forumax_forums_list-' . $instance_number;
415 $sidebars_widgets[ $sidebar_id ][ $key ] = $new_widget_id;
416
417 $widget_migrated = true;
418
419 // Log migration (for debugging)
420 error_log(
421 sprintf(
422 'Forumax: Migrated widget from "%s" to "%s" in sidebar "%s"',
423 $widget_id,
424 $new_widget_id,
425 $sidebar_id
426 )
427 );
428 }
429 }
430 }
431 }
432
433 // Save updated widget options and sidebars if any widget was migrated
434 if ( $widget_migrated ) {
435 update_option( $new_widget_option_key, $new_widget_options );
436 update_option( 'sidebars_widgets', $sidebars_widgets );
437
438 // Log successful migration
439 error_log( 'Forumax: Widget migration completed successfully' );
440 }
441 }
442
443
444 /**
445 * Initialize the plugin functionality.
446 *
447 * @return void
448 */
449 public function init_plugin() {
450
451 $this->load_features();
452
453 if ( is_admin() ) {
454 new Admin();
455 new admin\Admin_Assets();
456
457 // Helpdesk docs assistant on Forumax admin pages.
458 require_once __DIR__ . '/includes/admin/class-support-assistant.php';
459 \Forumax_Support_Assistant::get_instance();
460
461 // Check for widget migration on every admin load (once per session)
462 // This catches cases where plugins were updated in wrong order
463 add_action( 'admin_init', array( $this, 'check_widget_migration' ), 5 );
464 } elseif ( ! is_admin() ) {
465 new Frontend\Frontend_Assets();
466 }
467
468 // If bbPress is not active, don't load assets and widgets.
469 if ( ! class_exists( 'bbPress' ) || ! class_exists( 'Forumax' ) ) {
470 return;
471 }
472
473 new admin\Elementor\Forumax_Widgets();
474 }
475
476 /**
477 * Check and run widget migration if needed
478 *
479 * This runs on admin_init to catch widgets that need migration
480 * even if the plugin was updated in the wrong order.
481 *
482 * @return void
483 */
484 public function check_widget_migration() {
485
486 /**
487 * forumax list widget id update
488 *
489 * @var mixed
490 */
491
492 $new_id = 'forumax_forums_list';
493 $new_option_name = 'widget_' . $new_id;
494 $new_data = get_option( $new_option_name );
495
496 if ( empty( $new_data ) || ( is_array( $new_data ) && count( $new_data ) <= 1 ) ) {
497
498 $docy_data = get_option( 'widget_forums' );
499
500 $docly_data = get_option( 'widget_doclycore\\wpwidgets\\forums_widget' );
501
502 $ama_data = get_option( 'widget_amacore\\wpwidgets\\forums_widget' );
503
504 if ( ! empty( $docy_data ) && is_array( $docy_data ) && count( $docy_data ) > 1 ) {
505 update_option( $new_option_name, $docy_data );
506 } elseif ( ! empty( $docly_data ) && is_array( $docly_data ) && count( $docly_data ) > 1 ) {
507 update_option( $new_option_name, $docly_data );
508 } elseif ( ! empty( $ama_data ) && is_array( $ama_data ) && count( $ama_data ) > 1 ) {
509 update_option( $new_option_name, $ama_data );
510 }
511 }
512
513 // Check if migration has already been done
514 $migration_done = get_option( 'forumax_widget_migration_done', false );
515
516 if ( $migration_done ) {
517 return; // Already migrated
518 }
519
520 // Check if there are any old docy-core widgets that need migration
521 $sidebars_widgets = get_option( 'sidebars_widgets', array() );
522 $needs_migration = false;
523
524 foreach ( $sidebars_widgets as $sidebar_id => $widgets ) {
525 if ( $sidebar_id === 'wp_inactive_widgets' || $sidebar_id === 'array_version' || ! is_array( $widgets ) ) {
526 continue;
527 }
528
529 foreach ( $widgets as $widget_id ) {
530 if ( preg_match( '/^(widget_)?docycore-wpwidgets-forums-(\d+)$/', $widget_id ) ) {
531 $needs_migration = true;
532 break 2; // Break out of both loops
533 }
534 }
535 }
536
537 if ( $needs_migration ) {
538 // Run migration
539 $this->migrate_docy_core_widgets();
540
541 // Mark as done
542 update_option( 'forumax_widget_migration_done', true );
543
544 // Add admin notice
545 add_action(
546 'admin_notices',
547 function () {
548 ?>
549 <div class="notice notice-success is-dismissible">
550 <p>
551 <strong><?php esc_html_e( 'Forumax:', 'forumax' ); ?></strong>
552 <?php esc_html_e( 'Your widgets have been automatically migrated from Docy Core to Forumax.', 'forumax' ); ?>
553 </p>
554 </div>
555 <?php
556 }
557 );
558 } else {
559 // No migration needed, mark as done
560 update_option( 'forumax_widget_migration_done', true );
561 }
562 }
563
564
565 /**
566 * Include CSF files include
567 */
568 public function load_csf_files() {
569 require FORUMAX_DIR . 'lib/csf/classes/setup.class.php';
570 require FORUMAX_DIR . 'includes/admin/options/settings.php';
571 }
572
573 /**
574 * Load different features.
575 *
576 * @return void
577 */
578 public function load_features() {
579 define( 'FORUMAX_FEAT_PATH', plugin_dir_path( __FILE__ ) . 'includes/features/' );
580
581 if ( forumax_get_opt( 'is_solved_topics', true ) ) {
582 require FORUMAX_FEAT_PATH . 'bbp_solved_topic.php';
583 }
584
585 // Auto Close Stale Topics
586 require FORUMAX_FEAT_PATH . 'forumax_auto_close.php';
587
588 if ( forumax_get_opt( 'is_private_replies', true ) ) {
589 require FORUMAX_FEAT_PATH . 'bbp-private-replies.php';
590 }
591
592 if ( forumax_get_opt( 'is_votes', true ) ) {
593 new features\bbp_voting();
594 }
595
596 if ( forumax_get_opt( 'is_attachment', true ) ) {
597 new features\bbp_attachments();
598 }
599
600 /**
601 * Action hook for Forumax premium plugin to load
602 * premium-only features (Gamification, Nested Replies,
603 * Agree/Disagree Voting, etc.).
604 *
605 * @since 2.3.0
606 */
607 do_action( 'forumax_load_premium_features' );
608
609 // Custom Profile Avatar Upload.
610 require_once FORUMAX_FEAT_PATH . 'frmx-profile-avatar.php';
611
612 // Inline AJAX editing for topics.
613 require_once FORUMAX_FEAT_PATH . 'frmx-inline-edit.php';
614 }
615
616 /**
617 * Documentation links to plugin row meta
618 */
619 public function forumax_row_meta( $links, $file ) {
620 // Check if this is your plugin
621 if ( plugin_basename( __FILE__ ) === $file ) {
622 // Add your custom links
623 $plugin_links = array(
624 '<a href="https://helpdesk.spider-themes.net/docs/forumax-wordpress-plugin/" target="_blank">' . esc_html__( 'Documentation', 'forumax' ) . '</a>',
625 );
626 // Merge the custom links with the existing links
627 $links = array_merge( $links, $plugin_links );
628 }
629
630 return $links;
631 }
632
633 /**
634 * Prevent deactivation of Forumax if Forumax Pro is active
635 * Users must deactivate Forumax Pro first before deactivating Forumax
636 *
637 * @return void
638 */
639 public function prevent_deactivation_if_pro_active() {
640 // Check if we're on the plugins page
641 if ( ! isset( $_SERVER['REQUEST_URI'] ) || strpos( $_SERVER['REQUEST_URI'], 'plugins.php' ) === false ) {
642 return;
643 }
644
645 // Check if user is trying to deactivate this plugin
646 if ( isset( $_GET['action'] ) && $_GET['action'] === 'deactivate' &&
647 isset( $_GET['plugin'] ) && $_GET['plugin'] === plugin_basename( __FILE__ ) ) {
648
649 // Check if Forumax Pro is active
650 if ( is_plugin_active( 'forumax-premium/forumax.php' ) ) {
651 // Prevent deactivation
652 wp_die(
653 '<h1>' . esc_html__( 'Cannot Deactivate Forumax', 'forumax' ) . '</h1>' .
654 '<p>' . esc_html__( 'You cannot deactivate Forumax while Forumax Pro is active.', 'forumax' ) . '</p>' .
655 '<p>' . esc_html__( 'Please deactivate Forumax Pro first, then you can deactivate Forumax.', 'forumax' ) . '</p>',
656 esc_html__( 'Plugin Dependency Error', 'forumax' ),
657 array( 'back_link' => true )
658 );
659 }
660 }
661 }
662
663 /**
664 * Modify the deactivate link to show a disabled state when Forumax Pro is active
665 *
666 * @param array $actions An array of plugin action links.
667 * @param string $plugin_file Path to the plugin file relative to the plugins directory.
668 * @param array $plugin_data An array of plugin data.
669 * @param string $context The plugin context (active, inactive, etc).
670 * @return array Modified action links
671 */
672 public function modify_deactivate_link( $actions, $plugin_file, $plugin_data, $context ) {
673 // Check if Forumax Pro is active
674 if ( is_plugin_active( 'forumax-premium/forumax.php' ) ) {
675 // Remove the default deactivate link
676 if ( isset( $actions['deactivate'] ) ) {
677 unset( $actions['deactivate'] );
678
679 // Add a disabled deactivate message
680 $actions['deactivate_disabled'] = '<span style="color: #a0a5aa; cursor: not-allowed;" title="' .
681 esc_attr__( 'Please deactivate Forumax Pro first', 'forumax' ) . '">' .
682 esc_html__( 'Deactivate', 'forumax' ) .
683 '</span>';
684 }
685 }
686
687 return $actions;
688 }
689 }
690
691 /**
692 * Initialize the Forumax plugin.
693 *
694 * @return \Forumax
695 */
696 function forumax() {
697 return Forumax::init();
698 }
699
700 forumax();