'https://img.youtube.com/vi/%s/mqdefault.jpg', // 320x180 'hqdefault' => 'https://img.youtube.com/vi/%s/hqdefault.jpg', // 480x360 'sddefault' => 'https://img.youtube.com/vi/%s/sddefault.jpg', // 640x480 'maxresdefault' => 'https://img.youtube.com/vi/%s/maxresdefault.jpg', // 1280x720 ]; public static $errors = []; public static function init() { //add_action( 'admin_init', [ self::class, 'init_updater' ] ); // Init plugin updater add_action( 'admin_init', [ self::class, 'settings_api_init' ] ); // Register settings add_action( 'init', [ self::class, 'register_post_type' ] ); // Register custom post type add_filter( 'plugin_action_links', [ self::class, 'plugin_action_links' ], 10, 2 ); // Add actions links on plugins list page add_action( 'plugins_loaded', [ self::class, 'load_textdomain' ] ); // Internationalization add_action( 'admin_enqueue_scripts', [ self::class, 'admin_enqueue_scripts' ] ); // Enqueue admin js/css add_action( 'wp_enqueue_scripts', [ self::class, 'enqueue_scripts' ] ); // Enqueue user js/css // Begin edit form add_action( 'edit_form_after_title', [ self::class, 'edit_form_additional_fields' ] ); // Add custom fields to edit form add_action( 'save_post_' . self::POST_TYPE, [ self::class, 'save_post' ] ); // Save post custom fields add_action( 'admin_notices', [ self::class, 'show_save_errors' ] ); add_filter( 'redirect_post_location', [ self::class, 'set_correct_save_message' ], 10, 2 ); // End edit form //Begin admin list add_filter( 'manage_' . self::POST_TYPE . '_posts_columns', [ self::class, 'posts_columns'] ); // add custom column add_filter( 'manage_edit-' . self::POST_TYPE . '_sortable_columns', [ self::class, 'sortable_columns' ] ); // mark custom column as sorted add_action( 'manage_' . self::POST_TYPE . '_posts_custom_column' , [ self::class, 'posts_custom_column' ] ); // output custom column value add_action( 'pre_get_posts', [ self::class, 'pre_get_posts' ] ); // change default order //End admin list add_shortcode( self::SHORTCODE, [ self::class, 'shortcode' ] ); } public static function init_updater() { include_once 'updater.php'; if ( is_admin() ) { // note the use of is_admin() to double check that this is happening in the admin $__config = include 'updater-config.php'; $config = [ 'slug' => plugin_basename( __FILE__ ), 'updates_url' => "{$__config['updates_url']}/{$__config['plugin_name']}", 'zip_url' => "{$__config['updates_url']}/{$__config['plugin_name']}/{$__config['latest_filename']}", 'sslverify' => true, 'requires' => '4.0', 'tested' => '4.9', 'release_info' => $__config['info_filename'], 'auth_username' => $__config['auth_username'], 'auth_password' => $__config['auth_password'], ]; new WP_Updater( $config ); } } public static function plugin_action_links( $actions, $plugin_file ) { static $plugin; if ( ! isset( $plugin) ) { $plugin = plugin_basename( __FILE__ ); } if ($plugin == $plugin_file) { $url = esc_attr( get_admin_url(null, 'options-general.php' ) ) . '#' . esc_attr( self::$youtube_settings_id ); $settings = [ 'settings' => '' . __( 'Settings', 'General') . '' ]; $actions = array_merge( $settings, $actions ); } return $actions; } /** * Register Settings */ public static function settings_api_init() { // Add the section to reading settings so we can add our fields to it add_settings_section( self::get_meta_key( 'setting_section' ), self::translate( 'Abaninja Videos' ), [ self::class, 'setting_section_callback' ], 'general' ); // Add the field with the names and function to use for our new settings, put it in our new section add_settings_field( self::get_meta_key( 'setting_youtube_api_key' ), self::translate( 'Youtube API Key' ), [ self::class, 'setting_youtube_api_key_callback' ], 'general', self::get_meta_key( 'setting_section' ) ); // Register our setting so that $_POST handling is done for us and our callback function just has to echo the register_setting( 'general', self::get_meta_key( 'setting_youtube_api_key' ) ); } public static function setting_section_callback() { echo ''; } function setting_youtube_api_key_callback() { $name = esc_attr( self::get_meta_key( 'setting_youtube_api_key' ) ); $value = esc_attr( get_option( self::get_meta_key( 'setting_youtube_api_key' ) ) ); echo ''; } /** * Register custom post type */ public static function register_post_type() { $labels = [ 'name' => self::translate( 'Video' ), 'singular_name' => self::translate( 'Video' ), 'add_new' => self::translate( 'Add New' ), 'add_new_item' => self::translate( 'Add New Video' ), 'edit_item' => self::translate( 'Edit Video' ), 'new_item' => self::translate( 'New Video' ), 'view_item' => self::translate( 'View Video' ), 'view_items' => self::translate( 'View Videos' ), 'search_items' => self::translate( 'Search Videos' ), 'not_found' => self::translate( 'No videos found.' ), 'not_found_in_trash' => self::translate( 'No videos found in Trash.' ), 'all_items' => self::translate( 'All Videos' ), 'archives' => self::translate( 'Video Archives' ), 'attributes' => self::translate( 'Video Attributes' ), 'insert_into_item' => self::translate( /** @lang text */ 'Insert into Video' ), 'uploaded_to_this_item' => self::translate( 'Uploaded to this video' ), 'featured_image' => self::translate( 'Featured Image' ), 'set_featured_image' => self::translate( 'Set featured image' ), 'remove_featured_image' => self::translate( 'Remove featured image' ), 'use_featured_image' => self::translate( 'Use as featured image' ), 'filter_items_list' => self::translate( 'Filter videos list' ), 'items_list_navigation' => self::translate( 'Videos list navigation' ), 'items_list' => self::translate( 'Videos list' ), ]; register_post_type( self::POST_TYPE, [ 'labels' => $labels, 'public' => false, 'hierarchical' => false, 'show_ui' => true, 'menu_icon' => 'dashicons-video-alt', 'capability_type' => 'post', 'supports' => [ 'title', 'editor', 'page-attributes' ], ] ); } /** * Internationalization */ public static function load_textdomain() { $plugin_rel_path = basename( dirname( __FILE__ ) ) . '/languages/'; load_plugin_textdomain( self::TEXT_DOMAIN, false, $plugin_rel_path ); } /** * Enqueue admin js/css */ public static function admin_enqueue_scripts() { global $pagenow, $typenow; if ( in_array( $pagenow, [ 'post-new.php', 'post.php' ] ) && self::POST_TYPE == $typenow ) { $suffix = self::get_script_suffix(); $lang = self::get_curr_lang(); wp_enqueue_style( 'anv_admin', plugins_url( "css/admin{$suffix}.css", __FILE__ ) ); wp_enqueue_script( 'anv_edit_form', plugins_url( "js/edit-form{$suffix}.js", __FILE__ ), [ 'jquery' ] ); $vars = [ 'lang' => $lang, 'plugins_url' => plugins_url( '/', __FILE__ ), 'youtube_url_patterns' => self::$youtube_url_patterns, 'youtube_image_url_format' => self::$youtube_image_url_formats['mqdefault'], 'errors' => [ 'video_url_empty' => self::translate( 'Video URL is empty' ), 'unknown_video_url_format' => self::translate( 'Unknown video URL format' ), ], ]; wp_localize_script( 'anv_edit_form', 'anv_edit_form', $vars ); wp_enqueue_media(); } } /** * Enqueue user js/css */ function enqueue_scripts() { $suffix = self::get_script_suffix(); wp_enqueue_style( 'magnific_popup', plugins_url( "css/magnific-popup{$suffix}.css", __FILE__ ) ); wp_enqueue_script( 'magnific_popup', plugins_url( "js/jquery.magnific-popup{$suffix}.js", __FILE__ ), [ 'jquery' ] ); wp_enqueue_style( 'anv_user', plugins_url( "css/user{$suffix}.css", __FILE__ ) ); wp_enqueue_script( 'anv_user', plugins_url( "js/user{$suffix}.js", __FILE__ ), [ 'magnific_popup' ] ); $vars = [ 'youtube_url_patterns' => self::$youtube_url_patterns, 'autoplay_id' => @$_REQUEST['autoplay'], ]; wp_localize_script( 'anv_user', 'anv_user', $vars ); } /** * Add Custom fields to edit form * @param WP_Post $post */ public static function edit_form_additional_fields( $post ) { if ( self::POST_TYPE != $post->post_type ) { return; } $video_url = get_post_meta( $post->ID, self::get_meta_key( 'video_url' ), true ); $image_url = get_post_meta( $post->ID, self::get_meta_key( 'image_url' ), true ); ?>

Example:

ID}" ); wp_nonce_field($action, $name); } /** * Save post custom fields * @param $post_ID */ public static function save_post( $post_ID ) { $nonce_name = self::get_meta_key( 'wpnonce' ); $nonce_action = self::get_meta_key( "save_{$post_ID}" ); if ( ! isset( $_POST[$nonce_name] ) || ! wp_verify_nonce( $_POST[$nonce_name], $nonce_action ) ) { return; } if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) { return; } if ( ! current_user_can( 'edit_post', $post_ID ) ) { return; } if ( isset( $_POST['post_type'] ) && self::POST_TYPE === $_POST['post_type'] ) { $fields = [ 'video_url', 'image_url' ]; foreach ( $fields as $field ) { $value = @$_POST[$field]; if ( is_callable( [ self::class, "sanitize_{$field}" ] ) ) { $value = call_user_func( [ self::class, "sanitize_{$field}" ], $value ); } update_post_meta( $post_ID, self::get_meta_key( $field ), $value ); } $video_id = self::fetch_video_id( $_POST['video_url'] ); if ( $video_id ) { update_post_meta( $post_ID, self::get_meta_key( 'video_id' ), $video_id ); $video_duration = self::get_video_duration( $video_id ); if ( $video_duration ) { update_post_meta( $post_ID, self::get_meta_key( 'video_duration' ), $video_duration ); } else { delete_post_meta( $post_ID, self::get_meta_key( 'video_duration' ) ); } } else { self::$errors[] = self::translate( "Can't fetch Video ID from entered URL" ); } } if ( ! empty( self::$errors ) ) { $error = new WP_Error(); foreach ( self::$errors as $code => $message ) { $error->add( $code, $message ); } set_transient( self::get_transient_key( 'save_post_error', $post_ID ), $error, 45 ); remove_action( 'save_post_' . self::POST_TYPE, [ self::class, __FUNCTION__ ] ); // unhook this function to prevent indefinite loop wp_update_post( [ 'ID' => $post_ID, 'post_status' => 'draft' ] ); // update the post to change post status remove_action( 'save_post_' . self::POST_TYPE, [ self::class, __FUNCTION__ ] ); // re-hook this function again } } public static function set_correct_save_message( $location, $post_id ) { if ( isset( $_POST['publish'] ) ) { // if post was published... $status = get_post_status( $post_id ); //obtain current post status if ( $status == 'draft' ) { // the post was 'published', but if it is still a draft, display draft message (10). $location = add_query_arg( 'message', 10, $location ); } } return $location; } public static function show_save_errors() { $transient = self::get_transient_key( 'save_post_error', @$_GET['post'] ); /** @var WP_Error $error */ $error = get_transient( $transient ); if ( $error ) { foreach ( $error->get_error_codes() as $code ) { ?>

get_error_message( $code ); ?>

menu_order; break; case 'shortcode': echo "[abaninja_video id={$post->ID}]"; break; } } public static function pre_get_posts( WP_Query $query ) { if( ! $query->is_main_query() || self::POST_TYPE != $query->get( 'post_type' ) ) { return; // Nothing to do } $orderby = strtolower( $query->get( 'orderby') ); if ( '' === $orderby) { $query->set( 'orderby', 'menu_order' ); $query->set( 'order', 'ASC' ); } } public static function sanitize_video_url( $value ) { $value = trim( $value ); if ( '' !== $value ) { $value = esc_url_raw( $value ); if ( ! self::fetch_video_id( $value ) ) { self::$errors[] = self::translate( 'Video URL is in wrong format' ); } } else { self::$errors[] = self::translate( 'Video URL is required' ); } return $value; } public static function sanitize_image_url( $value ) { $value = trim( $value ); if ( '' !== $value ) { $value = esc_url_raw( $value ); if ( ! wp_http_validate_url( $value ) ) { self::$errors[] = self::translate( 'Image URL is in wrong format' ); } } else { self::$errors[] = self::translate( 'Image URL is required' ); } return $value; } public static function get_meta_key( $name ) { return '_'. self::POST_TYPE . '_' . $name; } public static function get_transient_key( $key, $post_id ) { $user_id = get_current_user_id(); return self::get_meta_key( "{$key}_{$post_id}_{$user_id}" ); } public static function get_curr_lang() { $lang = apply_filters( 'wpml_current_language', null ); if ( ! $lang ) { return self::DEFAULT_LANG; } return $lang; } public static function get_script_suffix() { //return SCRIPT_DEBUG ? '' : '.min'; return ''; } public static function translate( $text, $text_domain = self::TEXT_DOMAIN ) { return __( $text, $text_domain ); } public static function fetch_video_id( $youtube_url ) { $youtube_url = trim($youtube_url); if ( $youtube_url ) { $matches = []; foreach ( self::$youtube_url_patterns as $pattern ) { if ( preg_match( "/{$pattern}/", $youtube_url, $matches ) ) { return $matches[1]; } } } return false; } public static function get_video_duration( $video_id ) { $youtube_api_key = get_option( self::get_meta_key( 'setting_youtube_api_key' ) ); $url = sprintf( self::$youtube_api_url, $video_id, $youtube_api_key ); $ch = curl_init( $url ); curl_setopt( $ch, CURLOPT_SSL_VERIFYHOST, false ); curl_setopt( $ch, CURLOPT_SSL_VERIFYPEER, true ); curl_setopt( $ch, CURLOPT_RETURNTRANSFER, true ); $json = curl_exec( $ch ); curl_close( $ch ); if ( $json && ( $json = json_decode( $json, true ) ) && ! empty( $json['items'] ) ) { $video = reset( $json['items'] ); return self::covtime( $video['contentDetails']['duration'] ); } return false; } public static function covtime( $youtube_time ) { $start = new DateTime( '1970-01-01' ); // Unix epoch $start->add( new DateInterval( $youtube_time ) ); $result = $start->format( 'H:i:s' ); if ( 0 === strpos( $result, '00:' ) ) { // remove 00 hours $result = substr( $result, 3 ); } $result = ltrim( $result, '0' ); return $result; } public static function shortcode( $atts ) { $atts = shortcode_atts( [ 'id' => null, ], $atts, self::SHORTCODE ); $output = ''; if ( null !== $atts['id'] ) { $post = get_post( $atts['id'] ); if ( $post ) { $video_id = get_post_meta( $post->ID, self::get_meta_key( 'video_id' ), true); $video_url = get_post_meta( $post->ID, self::get_meta_key( 'video_url' ), true); $image_url = get_post_meta( $post->ID, self::get_meta_key( 'image_url' ), true); ob_start(); ?>

post_title ); ?>

post_content; ?>
self::POST_TYPE, 'posts_per_page' => -1, 'order' => 'ASC', 'orderby' => 'menu_order', ] ); if ( $query->have_posts() ) { ob_start(); echo '