init_twig(); $this->init_components(); $this->init_hooks(); $this->load_textdomain(); } /** * Prevent cloning. * * @return void */ private function __clone() {} /** * Prevent unserialization. * * @throws \Exception Always throws to prevent unserialization. * @return void */ public function __wakeup(): void { throw new \Exception( 'Cannot unserialize singleton' ); } /** * Initialize Twig template engine. * * @return void */ private function init_twig(): void { $loader = new \Twig\Loader\FilesystemLoader( WP_FEDISTREAM_PATH . 'templates' ); $this->twig = new \Twig\Environment( $loader, array( 'cache' => WP_FEDISTREAM_PATH . 'cache/twig', 'auto_reload' => WP_DEBUG, ) ); // Add WordPress escaping functions. $this->twig->addFunction( new \Twig\TwigFunction( 'esc_html', 'esc_html' ) ); $this->twig->addFunction( new \Twig\TwigFunction( 'esc_attr', 'esc_attr' ) ); $this->twig->addFunction( new \Twig\TwigFunction( 'esc_url', 'esc_url' ) ); $this->twig->addFunction( new \Twig\TwigFunction( 'esc_js', 'esc_js' ) ); $this->twig->addFunction( new \Twig\TwigFunction( 'wp_nonce_field', 'wp_nonce_field', array( 'is_safe' => array( 'html' ) ) ) ); $this->twig->addFunction( new \Twig\TwigFunction( '__', '__' ) ); $this->twig->addFunction( new \Twig\TwigFunction( '_e', '_e' ) ); } /** * Initialize plugin components. * * @return void */ private function init_components(): void { // Initialize post types. $this->post_types['artist'] = new Artist(); $this->post_types['album'] = new Album(); $this->post_types['track'] = new Track(); $this->post_types['playlist'] = new Playlist(); // Initialize taxonomies. $this->taxonomies['genre'] = new Genre(); $this->taxonomies['mood'] = new Mood(); $this->taxonomies['license'] = new License(); // Initialize admin components. if ( is_admin() ) { new ListColumns(); } // Initialize frontend components (only if licensed). if ( ! is_admin() && LicenseManager::is_license_valid() ) { new TemplateLoader(); new Shortcodes(); } elseif ( ! is_admin() ) { // Register shortcodes that show license message. new Shortcodes( true ); // Unlicensed mode. } // Initialize widgets (always needed for admin widget management). new Widgets(); // Initialize AJAX handlers. new Ajax(); // Initialize ActivityPub integration (only if licensed and enabled). if ( get_option( 'wp_fedistream_enable_activitypub', 1 ) && LicenseManager::is_license_valid() ) { new ActivityPubIntegration(); new ActivityPubRestApi(); } // Initialize WooCommerce integration. if ( get_option( 'wp_fedistream_enable_woocommerce', 0 ) && $this->is_woocommerce_active() ) { new WooCommerceIntegration(); new DigitalDelivery(); new StreamingAccess(); } // Initialize Prometheus integration. if ( get_option( 'wp_fedistream_enable_prometheus', 0 ) && $this->is_prometheus_active() ) { new PrometheusIntegration(); } // Initialize user library and notifications. new UserLibrary(); new LibraryPage(); new Notifications(); // Initialize license manager. LicenseManager::get_instance(); } /** * Initialize WordPress hooks. * * @return void */ private function init_hooks(): void { add_action( 'init', array( $this, 'maybe_install_defaults' ), 20 ); add_action( 'admin_menu', array( $this, 'add_admin_menu' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_admin_assets' ) ); add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_frontend_assets' ) ); // Add settings link to plugins page. add_filter( 'plugin_action_links_' . WP_FEDISTREAM_BASENAME, array( $this, 'add_plugin_action_links' ) ); } /** * Add action links to the plugins page. * * @param array $links Existing action links. * @return array Modified action links. */ public function add_plugin_action_links( array $links ): array { $settings_link = sprintf( '%s', esc_url( admin_url( 'admin.php?page=fedistream-settings' ) ), esc_html__( 'Settings', 'wp-fedistream' ) ); $dashboard_link = sprintf( '%s', esc_url( admin_url( 'admin.php?page=fedistream' ) ), esc_html__( 'Dashboard', 'wp-fedistream' ) ); // Add our links at the beginning. array_unshift( $links, $dashboard_link, $settings_link ); return $links; } /** * Maybe install default taxonomy terms. * * @return void */ public function maybe_install_defaults(): void { Installer::install_defaults(); } /** * Load plugin textdomain. * * @return void */ private function load_textdomain(): void { load_plugin_textdomain( 'wp-fedistream', false, dirname( WP_FEDISTREAM_BASENAME ) . '/languages' ); } /** * Add admin menu. * * @return void */ public function add_admin_menu(): void { // Main menu. add_menu_page( __( 'FediStream', 'wp-fedistream' ), __( 'FediStream', 'wp-fedistream' ), 'edit_fedistream_tracks', 'fedistream', array( $this, 'render_dashboard_page' ), 'dashicons-format-audio', 30 ); // Dashboard submenu. add_submenu_page( 'fedistream', __( 'Dashboard', 'wp-fedistream' ), __( 'Dashboard', 'wp-fedistream' ), 'edit_fedistream_tracks', 'fedistream', array( $this, 'render_dashboard_page' ) ); // Artists submenu. add_submenu_page( 'fedistream', __( 'Artists', 'wp-fedistream' ), __( 'Artists', 'wp-fedistream' ), 'edit_fedistream_artists', 'edit.php?post_type=fedistream_artist' ); // Albums submenu. add_submenu_page( 'fedistream', __( 'Albums', 'wp-fedistream' ), __( 'Albums', 'wp-fedistream' ), 'edit_fedistream_albums', 'edit.php?post_type=fedistream_album' ); // Tracks submenu. add_submenu_page( 'fedistream', __( 'Tracks', 'wp-fedistream' ), __( 'Tracks', 'wp-fedistream' ), 'edit_fedistream_tracks', 'edit.php?post_type=fedistream_track' ); // Playlists submenu. add_submenu_page( 'fedistream', __( 'Playlists', 'wp-fedistream' ), __( 'Playlists', 'wp-fedistream' ), 'edit_fedistream_playlists', 'edit.php?post_type=fedistream_playlist' ); // Genres submenu. add_submenu_page( 'fedistream', __( 'Genres', 'wp-fedistream' ), __( 'Genres', 'wp-fedistream' ), 'manage_fedistream_genres', 'edit-tags.php?taxonomy=fedistream_genre' ); // Settings submenu. add_submenu_page( 'fedistream', __( 'Settings', 'wp-fedistream' ), __( 'Settings', 'wp-fedistream' ), 'manage_fedistream_settings', 'fedistream-settings', array( $this, 'render_settings_page' ) ); } /** * Render dashboard page. * * @return void */ public function render_dashboard_page(): void { // Get stats. $artist_count = wp_count_posts( 'fedistream_artist' )->publish ?? 0; $album_count = wp_count_posts( 'fedistream_album' )->publish ?? 0; $track_count = wp_count_posts( 'fedistream_track' )->publish ?? 0; $playlist_count = wp_count_posts( 'fedistream_playlist' )->publish ?? 0; ?>
handle_settings_save( $current_tab ); // Get current settings. $enable_activitypub = get_option( 'wp_fedistream_enable_activitypub', 1 ); $enable_woocommerce = get_option( 'wp_fedistream_enable_woocommerce', 0 ); $enable_prometheus = get_option( 'wp_fedistream_enable_prometheus', 0 ); $max_upload_size = get_option( 'wp_fedistream_max_upload_size', 50 ); $default_license = get_option( 'wp_fedistream_default_license', 'all-rights-reserved' ); // License settings. $license_key = LicenseManager::get_license_key(); $license_server_url = LicenseManager::get_server_url(); $license_status = LicenseManager::get_cached_status(); $license_data = LicenseManager::get_cached_data(); $last_check = LicenseManager::get_last_check(); $tabs = array( 'license' => __( 'License', 'wp-fedistream' ), 'settings' => __( 'Default Settings', 'wp-fedistream' ), 'integrations' => __( 'Integrations', 'wp-fedistream' ), ); ?>' . esc_html__( 'License settings saved.', 'wp-fedistream' ) . '
' . esc_html__( 'Settings saved.', 'wp-fedistream' ) . '
' . esc_html__( 'Integration settings saved.', 'wp-fedistream' ) . '