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. if ( ! is_admin() ) { new TemplateLoader(); new Shortcodes(); } // Initialize widgets (always needed for admin widget management). new Widgets(); // Initialize AJAX handlers. new Ajax(); // Initialize ActivityPub integration. if ( get_option( 'wp_fedistream_enable_activitypub', 1 ) ) { 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 user library and notifications. new UserLibrary(); new LibraryPage(); new Notifications(); } /** * 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' ) ); } /** * 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; ?>
' . esc_html__( 'Settings saved.', 'wp-fedistream' ) . '
'; } // Get current settings. $enable_activitypub = get_option( 'wp_fedistream_enable_activitypub', 1 ); $enable_woocommerce = get_option( 'wp_fedistream_enable_woocommerce', 0 ); $max_upload_size = get_option( 'wp_fedistream_max_upload_size', 50 ); $default_license = get_option( 'wp_fedistream_default_license', 'all-rights-reserved' ); ?>