menu label. * * @return array */ private static function pages() { $pages = array( 'dashboard' => __( 'Dashboard', 'youwall' ), 'connect' => __( 'Connect', 'youwall' ), 'display' => __( 'Display', 'youwall' ), 'style' => __( 'Style', 'youwall' ), ); if ( self::pro_visible() ) { $pages['pro'] = __( 'Pro', 'youwall' ); } return $pages; } /** * What Pro adds: icon, title, description. * * @return array */ private static function pro_features() { return array( array( 'featured', __( 'Featured player', 'youwall' ), __( 'A big player with an "Up next" list beside it.', 'youwall' ) ), array( 'playlist', __( 'Playlists', 'youwall' ), __( 'Show any public playlist, like a course or a series.', 'youwall' ) ), array( 'popular', __( 'Most viewed', 'youwall' ), __( 'A button that sorts a feed by views instead of date.', 'youwall' ) ), ); } /** * Admin page slug for a page key. * * @param string $key Page key. * @return string */ private static function slug( $key ) { return 'dashboard' === $key ? self::PAGE : self::PAGE . '-' . $key; } /** * Page URL. * * @param string $key Page key. * @return string */ public static function url( $key = 'dashboard' ) { return admin_url( 'admin.php?page=' . self::slug( $key ) ); } /** * YouWall menu with submenus. */ public static function menu() { self::$hooks[] = add_menu_page( __( 'YouWall', 'youwall' ), __( 'YouWall', 'youwall' ), 'manage_options', self::PAGE, array( __CLASS__, 'page' ), self::MENU_ICON, 58 ); foreach ( self::pages() as $key => $label ) { self::$hooks[] = add_submenu_page( self::PAGE, $label . ' ‹ ' . __( 'YouWall', 'youwall' ), $label, 'manage_options', self::slug( $key ), array( __CLASS__, 'page' ) ); } } /** * Register the option. */ public static function register() { register_setting( self::GROUP, YouWall_Settings::OPTION, array( 'type' => 'array', 'sanitize_callback' => array( 'YouWall_Settings', 'sanitize' ), 'default' => YouWall_Settings::defaults(), ) ); } /** * "Settings" link on the Plugins screen. * * @param array $links Links. * @return array */ public static function action_links( $links ) { array_unshift( $links, '' . esc_html__( 'Settings', 'youwall' ) . '' ); if ( ! self::pro_active() && '' !== self::pro_url() ) { $links[] = '' . esc_html__( 'Get Pro', 'youwall' ) . ''; } return $links; } /** * Load assets on our pages only. * * @param string $hook Screen hook. */ public static function assets( $hook ) { if ( ! in_array( $hook, self::$hooks, true ) ) { return; } wp_enqueue_style( 'wp-color-picker' ); wp_enqueue_style( 'youwall-admin', YOUWALL_URL . 'assets/admin.css', array(), YOUWALL_VERSION . '.' . filemtime( YOUWALL_DIR . 'assets/admin.css' ) ); wp_enqueue_script( 'youwall-admin', YOUWALL_URL . 'assets/admin.js', array( 'jquery', 'wp-color-picker' ), YOUWALL_VERSION . '.' . filemtime( YOUWALL_DIR . 'assets/admin.js' ), true ); wp_localize_script( 'youwall-admin', 'youwallAdmin', array( 'ajaxUrl' => admin_url( 'admin-ajax.php' ), 'nonce' => wp_create_nonce( 'youwall_admin' ), 'i18n' => array( 'testing' => __( 'Checking…', 'youwall' ), 'clearing' => __( 'Clearing…', 'youwall' ), 'copied' => __( 'Copied', 'youwall' ), 'copy' => __( 'Copy', 'youwall' ), 'show' => __( 'Show', 'youwall' ), 'hide' => __( 'Hide', 'youwall' ), 'failed' => __( 'Something went wrong. Please reload the page and try again.', 'youwall' ), ), ) ); } /* ── Layout ──────────────────────────────────────────────────────── */ /** * Render the current page. */ public static function page() { if ( ! current_user_can( 'manage_options' ) ) { return; } // phpcs:ignore WordPress.Security.NonceVerification.Recommended -- only picks which page to show. $slug = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : self::PAGE; $current = 'dashboard'; foreach ( array_keys( self::pages() ) as $key ) { if ( self::slug( $key ) === $slug ) { $current = $key; } } $icons = array( 'dashboard' => 'grid', 'connect' => 'plug', 'display' => 'layout', 'style' => 'palette', 'pro' => 'star', ); ?>

  1. 3

>
  1. ' . esc_html__( 'Google Cloud Console', 'youwall' ) . '' ); ?>
  2. ' . esc_html__( 'YouTube Data API v3', 'youwall' ) . '' ); ?>
  3. ' . esc_html__( 'Credentials', 'youwall' ) . '' ); ?>

label. * @param string $help Help text. */ private static function select( $key, $label, $options, $help = '' ) { $id = 'youwall-' . $key; $value = (string) YouWall_Settings::get( $key ); ?> /> %s

', esc_attr( $id . '-help' ), esc_html( $help ) ); } } /** * Inline SVG line icons. * * @param string $name Icon name. * @param int $size Size in px. * @return string */ private static function icon( $name, $size = 20 ) { $paths = array( 'logo' => '', 'grid' => '', 'plug' => '', 'layout' => '', 'palette' => '', 'check' => '', 'refresh' => '', 'shorts' => '', 'videos' => '', 'slider' => '', 'tabs' => '', 'star' => '', 'featured' => '', 'playlist' => '', 'popular' => '', 'external' => '', ); $body = isset( $paths[ $name ] ) ? $paths[ $name ] : ''; $svg = sprintf( '', absint( $size ), $body, 'logo' === $name ? '10 8 46 48' : '0 0 24 24' // The logo is drawn on a 64-unit grid. ); $allow = array( 'svg' => array( 'class' => true, 'width' => true, 'height' => true, 'viewbox' => true, 'fill' => true, 'stroke' => true, 'stroke-width' => true, 'stroke-linecap' => true, 'stroke-linejoin' => true, 'aria-hidden' => true, 'focusable' => true, ), 'path' => array( 'd' => true, 'fill' => true, 'stroke' => true, ), 'rect' => array( 'x' => true, 'y' => true, 'width' => true, 'height' => true, 'rx' => true, ), 'polygon' => array( 'points' => true, 'fill' => true, 'fill-opacity' => true, 'stroke' => true, ), 'circle' => array( 'cx' => true, 'cy' => true, 'r' => true, ), ); return wp_kses( $svg, $allow ); } /* ── AJAX ────────────────────────────────────────────────────────── */ /** * Check the key and channel typed on the Connect page (before saving). */ public static function ajax_test() { check_ajax_referer( 'youwall_admin', 'nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( array( 'message' => __( 'You are not allowed to do this.', 'youwall' ) ), 403 ); } $key = isset( $_POST['api_key'] ) ? preg_replace( '/[^A-Za-z0-9_\-]/', '', sanitize_text_field( wp_unslash( $_POST['api_key'] ) ) ) : ''; $channel = isset( $_POST['channel'] ) ? sanitize_text_field( wp_unslash( $_POST['channel'] ) ) : ''; if ( '' === $key || '' === $channel ) { wp_send_json_error( array( 'message' => __( 'Enter both the API key and the channel first.', 'youwall' ) ) ); } $api = new YouWall_API( $key ); $result = $api->test_connection( $channel ); if ( is_wp_error( $result ) ) { wp_send_json_error( array( 'message' => $result->get_error_message() ) ); } wp_send_json_success( array( /* translators: %s: YouTube channel name. */ 'message' => sprintf( __( 'Connected to “%s”. Click Save to keep these settings.', 'youwall' ), $result['title'] ), ) ); } /** * Clear saved results. */ public static function ajax_clear_cache() { check_ajax_referer( 'youwall_admin', 'nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( array( 'message' => __( 'You are not allowed to do this.', 'youwall' ) ), 403 ); } YouWall_Settings::clear_cache(); wp_send_json_success( array( 'message' => __( 'Done. Feeds will show fresh results on the next page load.', 'youwall' ) ) ); } /** * Hide the Pro card for this user. */ public static function ajax_dismiss_pro() { check_ajax_referer( 'youwall_admin', 'nonce' ); if ( ! current_user_can( 'manage_options' ) ) { wp_send_json_error( null, 403 ); } update_user_meta( get_current_user_id(), 'youwall_pro_dismissed', 1 ); wp_send_json_success(); } }