hook_wordpress_actions(); VideoPressHQCaps::init(); VideoPressHQPostStatus::init(); } private function hook_wordpress_actions() { add_action( 'init', array( $this, 'init' ) ); add_action( 'after_switch_theme', array( $this, 'after_switch_theme' ) ); add_action( 'after_setup_theme', array( $this, 'after_setup_theme' ) ); add_action( 'pre_get_posts', array( $this, 'customize_search' ) ); add_filter( 'show_admin_bar', '__return_false' ); add_filter( 'wpcom_better_footer_credit_link', array( $this, 'wpcom_better_footer_credit_link' ) ); add_filter( 'get_the_archive_title', array( $this, 'get_the_archive_title' ), 10, 3 ); add_filter( 'wp_theme_json_data_user', array( $this, 'filter_theme_json_data' ) ); add_action( 'template_redirect', array( $this, 'empty_state_detector' ) ); add_action( self::ACTION_UPDATE_THEME_VERSION, function() { flush_rewrite_rules( true ); } ); VideoPressHQPlaylist::register_hooks(); // disable the wpcom launch banner add_filter( 'wpcom_register_banners', '__return_false' ); } public function init() { $this->init_post_types(); $this->init_taxonomies(); $this->init_blocks(); $this->init_pages(); $this->init_edit_rewrites(); $this->maybe_flush_rewrites(); $this->enqueue_js(); $this->init_og_tags(); $this->update_theme_version(); } private function update_theme_version() { $installed_theme_version = get_option( self::THEME_VERSION_OPTION, false ); if ( self::THEME_VERSION !== $installed_theme_version ) { do_action( self::ACTION_UPDATE_THEME_VERSION, $installed_theme_version, self::THEME_VERSION ); update_option( self::THEME_VERSION_OPTION, self::THEME_VERSION ); } } public function after_setup_theme() { $this->load_textdomain(); $this->hook_styles(); } public function load_textdomain() { load_theme_textdomain( 'videopress-hq', get_template_directory() . '/languages' ); } private function hook_styles() { // Editor requires add_editor_style to be called add_editor_style( 'style.css' ); add_action( 'wp_head', function () { wp_enqueue_style( 'videopress-hq-global-style', get_stylesheet_uri(), array(), self::THEME_VERSION ); wp_add_inline_style( 'videopress-hq-global-style', '.vphq-icon { display: block; width: 24px; height: 24px }' . '.vphq-icon.vphq-icon-playlist::after { content: url("' . esc_attr( get_template_directory_uri() . '/assets/images/icon-playlist.svg' ) . '"); }' . '.vphq-icon.vphq-icon-category::after { content: url("' . esc_attr( get_template_directory_uri() . '/assets/images/icon-file.svg' ) . '"); }' . '.vphq-icon.vphq-icon-hamburger::after { content: url("' . esc_attr( get_template_directory_uri() . '/assets/images/icon-hamburger.svg' ) . '"); }' . '.vphq-icon.vphq-icon-close-small::after { content: url("' . esc_attr( get_template_directory_uri() . '/assets/images/icon-close-small.svg' ) . '"); }' ); } ); } private function enqueue_js() { wp_enqueue_script( 'videopress-iframe-api', 'https://v0.wordpress.com/js/videojs/videopress-iframe-api.js', array(), false, true ); wp_enqueue_script( self::GLOBAL_FUNCTIONS_SCRIPT_ID, get_template_directory_uri() . '/assets/js/functions.js', array(), self::THEME_VERSION, true ); wp_enqueue_script( self::GLOBAL_JS_SCRIPT_ID, get_template_directory_uri() . '/assets/js/global.js', array( self::GLOBAL_FUNCTIONS_SCRIPT_ID ), self::THEME_VERSION, true ); } private function init_post_types() { register_post_type( self::POST_TYPE_VIDEO, array( 'labels' => array( 'name' => __( 'Videos', 'videopress-hq' ), 'singular_name' => __( 'Video', 'videopress-hq' ), 'menu_name' => __( 'Videos', 'videopress-hq' ), ), 'description' => __( 'VideoPress HQ custom post type', 'videopress-hq' ), 'public' => true, 'hierarchical' => false, 'exclude_from_search' => false, 'publicly_queryable' => true, 'show_ui' => true, 'show_in_menu' => true, 'show_in_nav_menus' => true, 'show_in_admin_bar' => true, 'show_in_rest' => true, 'has_archive' => 'videos', 'rewrite' => array( 'slug' => 'video' ), 'capability_type' => array( 'vp_video', 'vp_videos', 'vp_playlist', 'vp_playlists' ), 'map_meta_cap' => true, 'taxonomies' => array( 'category', 'post_tag', VideoPressHQPlaylist::TAXONOMY_NAME ), 'supports' => array( 'title', 'editor', 'comments', 'revisions', 'author', 'page-attributes', 'thumbnail', ), ) ); } private function init_taxonomies() { VideoPressHQPlaylist::register_taxonomy( self::POST_TYPE_VIDEO ); } private function init_pages() { VideoPressHQCustomAdminPage::register(); } private function init_blocks() { add_filter( 'block_categories_all', function ( $block_categories ) { $block_categories[] = array( 'slug' => 'videopress-hq', 'title' => __( 'VideoPress HQ', 'videopress-hq' ), ); return $block_categories; } ); VideoPressHQBlockVideoMeta::register(); VideoPressHQBlockVideoPosterLink::register(); VideoPressHQBlockAdminMenu::register(); VideoPressHQBlockCategoriesMenu::register(); VideoPressHQBlockDateHumanDiff::register(); VideoPressHQBlockVideoStat::register(); VideoPressHQBlockThemeImage::register(); VideoPressHQBlockTrialBar::register(); VideoPressHQBlockVideoQueryLoop::register(); VideoPressHQBlockPlaylist::register(); VideoPressHQBlockEditLink::register(); VideoPressHQBlockPlaylistList::register(); VideoPressHQBlockPostContent::register(); VideoPressHQBlockCustomMainMenu::register(); } function init_edit_rewrites() { add_filter( 'query_vars', function ( $vars ) { $vars[] = 'vp-custom-page'; $vars[] = 'playlist_id'; return $vars; } ); $admin_pages = vphq_get_custom_admin_pages(); foreach ( $admin_pages as $key => $params ) { if ( is_string( $params ) ) { add_rewrite_rule( '^manage/' . $key . '$', $params, 'top' ); } elseif ( isset( $params['rule'] ) ) { $pattern = is_string( $params['rule'] ) ? $key : $params['rule']['pattern']; $rewrite = is_string( $params['rule'] ) ? $params['rule'] : $params['rule']['rewrite']; $prefix = isset( $params['no_prefix'] ) && $params['no_prefix'] ? '' : 'manage/'; add_rewrite_rule( '^' . $prefix . $pattern . '$', $rewrite, 'top' ); } } // public rewrite rules // one off rewrite for public playlists list. If we need more of these we should do something more generic. add_rewrite_rule( '^playlists$', 'index.php?vp-custom-page=public-playlists', 'top' ); add_action( 'template_include', function( $template ) { global $_wp_current_template_content; if ( 'public-playlists' === get_query_var( 'vp-custom-page' ) ) { ob_start(); block_template_part( 'header' ); include VPHQ_ROOT . '/templates/page-playlists.html'; block_template_part( 'footer' ); $_wp_current_template_content = ob_get_clean(); } return $template; } ); } public function maybe_flush_rewrites() { if ( 'yes' === get_option( 'videopress_hq_flush_rewrite_rules' ) ) { update_option( 'videopress_hq_flush_rewrite_rules', 'no' ); flush_rewrite_rules( true ); } } public function after_switch_theme() { if ( 'yes' !== get_option( 'videopress_hq_flush_rewrite_rules' ) ) { update_option( 'videopress_hq_flush_rewrite_rules', 'yes' ); } $this->add_video_post_type_to_sharing_options(); $this->prevent_atomic_transfer(); } /** * Ensures the vp_video post type is in the "sharing-options" site option when activating this theme. * If the setting is present, then likes will be enabled for this post type. */ public function add_video_post_type_to_sharing_options() { $sharing_option = get_option( 'sharing-options' ); if ( ! isset( $sharing_option['global']['show'] ) || ! is_array( $sharing_option['global']['show'] ) ) { return; } if ( ! in_array( self::POST_TYPE_VIDEO, $sharing_option['global']['show'], true ) ) { array_push( $sharing_option['global']['show'], self::POST_TYPE_VIDEO ); update_option( 'sharing-options', $sharing_option ); } } private function prevent_atomic_transfer() { if ( ! defined( 'IS_WPCOM' ) || ! IS_WPCOM ) { return; } $blog_id = wpcom_get_blog_id(); add_blog_sticker( 'blocked-from-atomic-transfer', 'New VideoPress HQ', get_current_user_id(), $blog_id ); } public function customize_search( $query ) { if ( $query->is_archive() && $query->is_category() ) { $query->set( 'post_type', self::POST_TYPE_VIDEO ); $query->set( 'posts_per_page', 12 ); } elseif ( $query && $query->is_search() && ! is_admin() ) { $search_term = trim( $query->get( 's' ) ); if ( ':related-videos' === $search_term ) { $query->set( 's', '' ); return $this->customize_related_videos( $query ); } elseif ( ':exclude-current-video-id' === $search_term ) { $query->set( 's', '' ); return $this->exclude_current_video_id( $query ); } elseif ( ! is_admin() ) { $query->set( 'post_type', self::POST_TYPE_VIDEO ); $query->set( 'posts_per_page', 12 ); } } return $query; } private function customize_related_videos( $query ) { $post_id = get_the_ID(); if ( false === $post_id ) { return $query; } $post = get_post( $post_id ); if ( ! $post ) { return $query; } $query->set( 'post_type', self::POST_TYPE_VIDEO ); if ( $post->post_category ) { $query->set( 'category__in', $post->post_category ); } return $this->exclude_current_video_id( $query ); } private function exclude_current_video_id( $query ) { $post_id = get_the_ID(); if ( false === $post_id ) { return $query; } $query->set( 'post__not_in', array( $post_id ) ); return $query; } public function wpcom_better_footer_credit_link() { return ''; } public function init_og_tags() { add_filter( 'jetpack_open_graph_tags', function ( $og_tags ) { global $post; if ( ! is_a( $post, 'WP_Post' ) ) { return $og_tags; } if ( empty( $post ) || empty( $post->ID ) ) { return $og_tags; } $post_id = $post->ID; $video_guid = get_post_meta( $post_id, 'guid', true ); if ( empty( $video_guid ) ) { return $og_tags; } $video_info = video_get_info_by_guid( $video_guid ); if ( empty( $video_info ) ) { return $og_tags; } $width = $video_info->width; $height = $video_info->height; $post_thumbnail = get_the_post_thumbnail_url( $post_id ); $video_embed_url = sprintf( 'https://videopress.com/embed/%s', $video_guid ); // get "best" adaptive streaming playlist if available $video_adaptive_playlist = null; if ( defined( 'IS_WPCOM' ) && IS_WPCOM ) { $file_url_base_https = "https://videos.files.wordpress.com/{$video_info->guid}/"; $adaptive_playlist_key = video_find_largest_adaptive_playlist_key( $video_info ); if ( null !== $adaptive_playlist_key ) { $video_adaptive_playlist = $file_url_base_https . $video_info->{ $adaptive_playlist_key }; } } if ( empty( $post_thumbnail ) ) { $video_details = videopress_hq_get_video_details( $video_guid ); $post_thumbnail = $video_details->poster ?? ''; } if ( ! empty( $post_thumbnail ) ) { $og_tags['og:image'] = $post_thumbnail; $og_tags['twitter:image'] = $post_thumbnail; } if ( ! empty( $og_tags['og:image'] ) ) { $og_tags['og:image:alt'] = $og_tags['og:title']; } $og_tags['twitter:card'] = 'player'; $og_tags['twitter:player'] = $video_embed_url; $og_tags['twitter:player:width'] = $width; $og_tags['twitter:player:height'] = $height; $og_tags['og:video:type'] = 'text/html'; $og_tags['og:video'] = array( $video_embed_url, $video_adaptive_playlist ); $og_tags['og:video:secure_url'] = array( $video_embed_url, $video_adaptive_playlist ); $og_tags['og:video:width'] = $width; $og_tags['og:video:height'] = $height; return $og_tags; }, 11 ); // after wpcom_twitter_cards_tags } public function filter_theme_json_data( $user_json ) { $custom_colors_option = vphq_get_site_custom_colors(); if ( ! is_array( $custom_colors_option ) || empty( $custom_colors_option ) ) { return $user_json; } $theme_json = WP_Theme_JSON_Resolver::get_theme_data(); $theme_data = $theme_json->get_data(); $theme_colors = $theme_data['settings']['color']['palette'] ?? array(); foreach ( $theme_colors as $idx => $theme_color ) { $color_slug = $theme_color['slug']; $custom_color = sanitize_hex_color_with_alpha( $custom_colors_option[ $color_slug ] ?? '' ); if ( ! empty( $custom_color ) ) { $theme_colors[ $idx ]['color'] = $custom_color; } } return $user_json->update_with( array( 'version' => $theme_data['version'], 'settings' => array( 'color' => array( 'palette' => $theme_colors, ), ), ) ); } /** * Detects empty state of the site by checking the cached post count by status * collection (only include published posts) and redirects to the onboarding page. * * Only runs on the homepage. Since custom admin pages are handled by index.php, * we also need to check that the custom page param doesn't have a value. * * @return void */ public function empty_state_detector() { $custom_page_param = get_query_var( 'vp-custom-page' ); if ( is_front_page() && empty( $custom_page_param ) && current_user_can( VideoPressHQCaps::CAP_PUBLISH_VIDEO ) ) { $num_videos = wp_count_posts( 'vp_video' ); if ( empty( $num_videos->publish ) ) { wp_redirect( vphq_admin_page_link( 'onboarding' ) ); die(); } } } public function get_the_archive_title( $title, $original_title, $prefix ) { if ( is_post_type_archive() ) { $title = post_type_archive_title( '', false ); return sprintf( /* translators: %s: Archive title */ _x( 'All %s', 'archive title', 'videopress-hq' ), $title ); } return $title; } }