Active add-ons. */ public static function get_active(): array { $plugin_files = (array) get_option( 'active_plugins', [] ); if ( is_multisite() ) { // Network activations are stored as plugin file => activation time. $plugin_files = array_merge( $plugin_files, array_keys( (array) get_site_option( 'active_sitewide_plugins', [] ) ) ); } $addons = []; foreach ( array_unique( $plugin_files ) as $plugin_file ) { // Entries in both options are active by definition, so we only need // the epicforms-* prefix check here. Avoid is_plugin_active(): it // lives in wp-admin/includes/plugin.php and is undefined in the // REST context, causing a fatal. if ( 0 !== strpos( $plugin_file, 'epicforms-' ) ) { continue; } $name = explode( '/', $plugin_file )[0]; $url = plugins_url( '/dist/main.js', WP_PLUGIN_DIR . '/' . $plugin_file ); // dist/main.js is the one add-on file without a content hash in its // name, so version it by mtime: otherwise browsers keep running the // old entry (and its old chunk references) after an add-on update. $mtime = @filemtime( WP_PLUGIN_DIR . '/' . $name . '/dist/main.js' ); // phpcs:ignore WordPress.PHP.NoSilencedErrors.Discouraged -- a missing build is not an error here. $addons[ $name ] = [ 'name' => $name, 'url' => false !== $mtime ? add_query_arg( 'ver', $mtime, $url ) : $url, ]; } return $addons; } }