PluginProbe
Forumax – AI Powered Advanced Community Forum Plugin / trunk
Forumax – AI Powered Advanced Community Forum Plugin vtrunk
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 2.1.0 All 29 releases
bbp-core / forumax.php

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

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