menu_title ) ) { $this->menu_title = $this->page_title; } $this->hooks(); } /** * Add hooks to register the page and output content. * * @return void */ public function hooks() { add_action( 'admin_menu', array( $this, 'add_page' ) ); $page = isset( $_GET['page'] ) ? sanitize_text_field( wp_unslash( $_GET['page'] ) ) : ''; // phpcs:ignore WordPress.Security.NonceVerification.Recommended // Only load if we are actually on the desired page. if ( $this->page_slug !== $page ) { return; } if ( ! current_user_can( $this->capability ) ) { wp_die( esc_html__( 'You do not have permission to access this page.', 'insert-headers-and-footers' ) ); } remove_all_actions( 'admin_notices' ); remove_all_actions( 'all_admin_notices' ); add_action( 'wpcode_admin_page', array( $this, 'output' ) ); add_action( 'wpcode_admin_page', array( $this, 'output_footer' ) ); add_action( 'admin_enqueue_scripts', array( $this, 'page_scripts' ) ); add_filter( 'admin_body_class', array( $this, 'page_specific_body_class' ) ); add_filter( 'wpcode_admin_js_data', array( $this, 'maybe_add_library_data' ) ); add_action( 'admin_init', array( $this, 'maybe_redirect_to_click' ) ); $this->setup_views(); $this->set_current_view(); $this->page_hooks(); } /** * Get the post type for this page. * * @return string */ public function get_post_type() { return wpcode_get_post_type(); } /** * Override in child class to define page-specific hooks that will run only * after checks have been passed. * * @return void */ public function page_hooks() { } /** * Add the submenu page. * * @return void */ public function add_page() { add_submenu_page( 'wpcode', $this->page_title, $this->menu_title, $this->capability, $this->page_slug, array( wpcode()->admin_page_loader, 'admin_menu_page', ) ); } /** * If the page has views, this is where you should assign them to $this->views. * * @return void */ protected function setup_views() { } /** * Set the current view from the query param also checking it's a registered view for this page. * * @return void */ protected function set_current_view() { // phpcs:disable WordPress.Security.NonceVerification.Recommended if ( ! isset( $_GET['view'] ) ) { return; } $view = sanitize_text_field( wp_unslash( $_GET['view'] ) ); // phpcs:enable WordPress.Security.NonceVerification.Recommended if ( array_key_exists( $view, $this->views ) ) { $this->view = $view; } } /** * Output the page content. * * @return void */ public function output() { $this->output_header(); ?>
output_content(); do_action( "wpcode_admin_page_content_{$this->page_slug}", $this ); ?>
output_header_left(); ?>
output_header_right(); ?>
output_header_bottom(); ?>
maybe_output_message(); ?>
logo_image( 'wpcode-help-logo' ); ?>
    get_categories_accordion(); $support_url = wpcode_utm_url( 'https://wpcode.com/contact/', 'help-overlay', 'support-url' ); ?>

    ' . absint( wpcode()->notifications->get_count() ) . '' ); ?>

    ' . absint( wpcode()->notifications->get_dismissed_count() ) . '' ); ?>

  • logo_image(); } /** * Logo image. * * @param string $id Id of the image. * * @return void */ public function logo_image( $id = 'wpcode-header-logo' ) { $logo = get_wpcode_icon( 'logo-text', 132, 33, '0 0 132 33', $id ); if ( wpcode()->settings->get_option( 'dark_mode' ) ) { $logo = str_replace( '11293E', 'CCCCCC', $logo ); } echo wp_kses( $logo, wpcode_get_icon_allowed_tags() ); } /** * Top right area of the header, by default the notifications and help icons. * * @return void */ public function output_header_right() { $notifications_count = wpcode()->notifications->get_count(); $dismissed_count = wpcode()->notifications->get_dismissed_count(); $data_count = ''; if ( $notifications_count > 0 ) { $data_count = sprintf( 'data-count="%d"', absint( $notifications_count ) ); } echo ''; echo $this->get_checkbox_toggle( wpcode_testing_mode_enabled(), 'wpcode-toggle-testing-mode', '', '', esc_html__( 'Testing Mode', 'insert-headers-and-footers' ) ); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped echo ''; ?> get_error_message(); $success_message = $this->get_success_message(); ?>

    message_error ) ? $this->message_error : false; } /** * If no message is set return false otherwise return the message string. * * @return false|string */ public function get_success_message() { return ! empty( $this->message_success ) ? $this->message_success : false; } /** * This is the main page content and you can't get away without it. * * @return void */ abstract public function output_content(); /** * If you need to page-specific scripts override this function. * Hooked to 'admin_enqueue_scripts'. * * @return void */ public function page_scripts() { } /** * Set a success message to display it in the appropriate place. * Let's use a function so if we decide to display multiple messages in the * same instance it's easy to change the variable to an array. * * @param string $message The message to store as success message. * * @return void */ public function set_success_message( $message ) { $this->message_success = $message; } /** * Set an error message to display it in the appropriate place. * Let's use a function so if we decide to display multiple messages in the * same instance it's easy to change the variable to an array. * * @param string $message The message to store as error message. * * @return void */ public function set_error_message( $message ) { $this->message_error = $message; } /** * Add a page-specific body class using the page slug variable. * Add a body class specific to the plugin version (lite/pro). * * @param string $body_class The body class to append. * * @return string */ public function page_specific_body_class( $body_class ) { $body_class .= ' ' . $this->page_slug . ' '; if ( ! class_exists( 'WPCode_Premium' ) ) { $body_class .= ' wpcode-lite-version '; } else { $body_class .= ' wpcode-pro-version '; } return $body_class; } /** * Get the page url to be used in a form action. * * @return string */ public function get_page_action_url() { $args = array( 'page' => $this->page_slug, ); if ( ! empty( $this->view ) ) { $args['view'] = $this->view; } if ( ! empty( $this->snippet_id ) ) { $args['snippet_id'] = $this->snippet_id; } return add_query_arg( $args, $this->admin_url( 'admin.php' ) ); } /** * Metabox-style layout for admin pages. * * @param string $title The metabox title. * @param string $content The metabox content. * @param string $help The helper text (optional) - if set, a help icon will show up next to the title. * * @return void */ public function metabox( $title, $content, $help = '' ) { // translators: %s is the title of the metabox. $button_title = sprintf( __( 'Collapse Metabox %s', 'insert-headers-and-footers' ), $title ) ?>
    help_icon( $help ); ?>
    >

    library->get_used_library_snippets(); $button_text = __( 'Use snippet', 'insert-headers-and-footers' ); $pill_text = ''; $pill_class = 'blue'; if ( isset( $snippet['button_text'] ) ) { $button_text = $snippet['button_text']; } if ( isset( $snippet['button_icon'] ) ) { $button_text = get_wpcode_icon( $snippet['button_icon'], 16, 16, '0 96 960 960' ) . ' ' . $button_text; } if ( ! empty( $snippet ) ) { if ( empty( $snippet['url'] ) ) { if ( ! empty( $used_library_snippets[ $snippet['library_id'] ] ) ) { $url = wpcode()->library->get_edit_snippet_url( $used_library_snippets[ $snippet['library_id'] ] ); $button_text = __( 'Edit snippet', 'insert-headers-and-footers' ); $pill_text = __( 'Used', 'insert-headers-and-footers' ); } else { $url = wpcode()->library->get_install_snippet_url( $snippet['library_id'] ); } } else { $url = $snippet['url']; } $title = $snippet['title']; $description = $snippet['note']; } $id = $snippet['library_id']; $button_2_text = ''; if ( ! empty( $snippet['code'] ) ) { $button_2_text = __( 'Preview', 'insert-headers-and-footers' ); } $categories = isset( $snippet['categories'] ) ? $snippet['categories'] : array(); $button_2 = array( 'text' => $button_2_text, 'class' => 'wpcode-button wpcode-button-secondary wpcode-library-preview-button', ); if ( ! empty( $snippet['needs_auth'] ) ) { $unlock_text = __( 'Connect to library to unlock (Free)', 'insert-headers-and-footers' ); if ( isset( $snippet['needs_auth_text'] ) ) { $unlock_text = $snippet['needs_auth_text']; } $button_1 = array( 'tag' => 'button', 'text' => get_wpcode_icon( 'lock', 17, 22, '0 0 17 22' ) . $unlock_text, 'class' => 'wpcode-button wpcode-item-use-button wpcode-start-auth wpcode-button-icon', ); } else { $button_1 = array( 'tag' => 'a', 'url' => $url, 'text' => $button_text, ); } if ( ! empty( $snippet['pill_text'] ) ) { $pill_text = $snippet['pill_text']; } if ( ! empty( $snippet['pill_class'] ) ) { $pill_class = $snippet['pill_class']; } $extra_classes = array(); if ( ! empty( $snippet['extra_classes'] ) && is_array( $snippet['extra_classes'] ) ) { $extra_classes = $snippet['extra_classes']; } $this->get_list_item( $id, $title, $description, $button_1, $button_2, $categories, $pill_text, $pill_class, $category, $extra_classes ); } /** * Get a list item markup, used for library & generators. * * @param string $id The id used for the data-id param (used for filtering). * @param string $title The title of the item. * @param string $description The item description. * @param array $button_1 The first button config (@see get_list_item_button). * @param array $button_2 The second button config (@see get_list_item_button). * @param array $categories The categories of this object (for filtering). * @param string $pill_text (optional) Display a "pill" with some text in the top right corner. * @param string $pill_class (optional) Custom CSS class for the pill. * @param string $selected_category (optional) Slug of the category selected by default. * @param array $extra_classes (optional) Extra classes to add to the list item. * * @return void */ public function get_list_item( $id, $title, $description, $button_1, $button_2 = array(), $categories = array(), $pill_text = '', $pill_class = 'blue', $selected_category = '*', $extra_classes = array() ) { $item_class = array( 'wpcode-list-item', ); if ( ! empty( $pill_text ) ) { $item_class[] = 'wpcode-list-item-has-pill'; } if ( ! empty( $extra_classes ) ) { $item_class = array_merge( $item_class, $extra_classes ); } $style = ''; if ( '*' !== $selected_category && ! in_array( $selected_category, $categories, true ) ) { $style = 'display:none;'; } $button_1 = wp_parse_args( $button_1, array( 'tag' => 'a', 'class' => 'wpcode-button wpcode-item-use-button', ) ); $button_2 = wp_parse_args( $button_2, array( 'class' => 'wpcode-button wpcode-button-secondary', ) ); ?>
  • get_list_item_top_actions( $id ); ?>
  • 'button', 'url' => '', 'text' => '', 'class' => 'wpcode-button', 'attributes' => array(), ) ); if ( empty( $button_settings['text'] ) ) { return; } $button_settings['class'] = esc_attr( $button_settings['class'] ); $parsed_attributes = "class='{$button_settings['class']}' "; if ( ! empty( $button_settings['url'] ) && 'a' === $button_settings['tag'] ) { $parsed_attributes .= 'href="' . esc_url( $button_settings['url'] ) . '" '; } if ( ! empty( $button_settings['attributes'] ) ) { foreach ( $button_settings['attributes'] as $key => $value ) { $parsed_attributes .= esc_attr( $key ) . '="' . esc_attr( $value ) . '"'; } } if ( $echo ) { printf( '<%1$s %2$s>%3$s', $button_settings['tag'], // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped $parsed_attributes, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped wp_kses( $button_settings['text'], wpcode_get_icon_allowed_tags() ) ); } else { return sprintf( '<%1$s %2$s>%3$s', $button_settings['tag'], // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped $parsed_attributes, // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped wp_kses( $button_settings['text'], wpcode_get_icon_allowed_tags() ) ); } } /** * Output the library markup from an array of categories and an array of snippets. * * @param array $categories The snippet categories to show. * @param array $snippets The snippets to show. * @param string $item_method The method in the current class for items output. * * @return void */ public function get_library_markup( $categories, $snippets, $item_method = 'get_library_snippet_item', $type = 'library' ) { $selected_category = isset( $categories[0]['slug'] ) ? $categories[0]['slug'] : '*'; $count = 0; foreach ( $snippets as $snippet ) { if ( isset( $snippet['needs_auth'] ) && empty( $snippet['skip_count'] ) ) { ++ $count; } } $categories = $this->add_item_counts( $categories, $snippets ); $categories = $this->add_available_category_label( $categories, $snippets, $count ); $snippets = $this->add_available_category_to_snippets( $snippets ); ?>
    get_items_list_sidebar( $categories, __( 'All Snippets', 'insert-headers-and-footers' ), __( 'Search Snippets', 'insert-headers-and-footers' ), $selected_category, $count ); ?>
    %s', esc_html__( 'We encountered a problem loading the Snippet Library items, please try again later.', 'insert-headers-and-footers' ) ); ?>
    $category ) { if ( ! isset( $category['slug'] ) ) { continue; } $categories[ $category_id ]['count'] = isset( $category_counts[ $category['slug'] ] ) ? $category_counts[ $category['slug'] ] : 0; } return $categories; } /** * Create a dynamic category for the available snippets. This goes through all the snippets * and counts how many of them need auth to be used, if there are any, it adds the category that shows * how many are available. * * @param array $categories The categories to add the available category to. * @param array $snippets The snippets to count. * * @return array */ public function add_available_category_label( $categories, $snippets, $total ) { if ( wpcode()->library_auth->has_auth() ) { return $categories; } $need_auth_count = 0; foreach ( $snippets as $snippet ) { if ( ! empty( $snippet['needs_auth'] ) ) { ++ $need_auth_count; } } if ( $need_auth_count > 0 ) { $categories = array_merge( array( array( 'name' => __( 'Available Snippets', 'insert-headers-and-footers' ), 'slug' => 'available', 'count' => $total - $need_auth_count, ), ), $categories ); } return $categories; } /** * For snippets that don't need auth, add an extra category "available" to allow easy filtering. * * @param array $snippets The snippets to add the category to. * * @return array */ public function add_available_category_to_snippets( $snippets ) { foreach ( $snippets as $key => $snippet ) { if ( empty( $snippet['needs_auth'] ) ) { $snippets[ $key ]['categories'][] = 'available'; } } return $snippets; } /** * Get the items list sidebar with optional search form. * * @param array $categories The array of categories to display as filters - each item needs to have the "slug" and "name" keys. * @param string $all_text Text to display on the all items button in the categories list. * @param string $search_label The search label, if left empty the search form is hidden. * @param string $selected_category Slug of the category selected by default. * @param int $all_count (optional) The number of items in the all category. * * @return void */ public function get_items_list_sidebar( $categories, $all_text = '', $search_label = '', $selected_category = '', $all_count = 0 ) { ?>

    set_setting( 'readOnly', 'nocursor' ); $editor->set_setting( 'gutters', array() ); $editor->register_editor( 'wpcode-code-preview' ); $editor->init_editor(); } /** * Load library data in JS. * * @param array $data The library data. * * @return array */ public function maybe_add_library_data( $data ) { if ( $this->show_library ) { $data['library'] = wpcode()->library->get_data(); } return $data; } /** * Get the full URL for a view of an admin page. * * @param string $view The view slug. * * @return string */ public function get_view_link( $view ) { return add_query_arg( array( 'page' => $this->page_slug, 'view' => $view, ), $this->admin_url( 'admin.php' ) ); } /** * Get an upsell box markup. * * @param string $title The main upsell box title. * @param string $text The text displayed under the title. * @param string $button_1 The main CTA button. * @param string $button_2 The text link below the main CTA. * @param array $features A list of features to display below the text. * * @return string */ public static function get_upsell_box( $title, $text = '', $button_1 = array(), $button_2 = array(), $features = array() ) { $container_class = array( 'wpcode-upsell-box', ); if ( ! empty( $features ) ) { $container_class[] = 'wpcode-upsell-box-with-features'; } $html = sprintf( '
    ', esc_attr( implode( ' ', $container_class ) ) ); $html .= '
    '; $html .= sprintf( '

    %s

    ', wp_kses_post( $title ) ); if ( ! empty( $text ) ) { $html .= sprintf( '
    %s
    ', wp_kses_post( $text ) ); } if ( ! empty( $features ) ) { $html .= ''; } $button_1 = wp_parse_args( $button_1, array( 'tag' => 'a', 'text' => '', 'url' => wpcode_utm_url( 'https://wpcode.com/lite/' ), 'class' => 'wpcode-button wpcode-button-orange wpcode-button-large', 'attributes' => array( 'target' => '_blank', ), ) ); $button_2 = wp_parse_args( $button_2, array( 'tag' => 'a', 'text' => '', 'url' => wpcode_utm_url( 'https://wpcode.com/lite/' ), 'class' => 'wpcode-upsell-button-text', 'attributes' => array( 'target' => '_blank', ), ) ); $html .= '
    '; // .wpcode-upsell-text-content $html .= '
    '; if ( ! empty( $button_1['text'] ) ) { $html .= self::get_list_item_button( $button_1, false ); } if ( ! empty( $button_2['text'] ) ) { $html .= '
    '; $html .= self::get_list_item_button( $button_2, false ); } $html .= '
    '; // .wpcode-upsell-buttons $html .= '
    '; return $html; } /** * Banner to highlight that connecting to the library gives you access to more snippets. * * @return void */ public function library_connect_banner_template() { if ( wpcode()->library_auth->has_auth() ) { return; } if ( ! current_user_can( 'wpcode_manage_settings' ) ) { return; } $data = wpcode()->library->get_data(); $count = 0; if ( ! empty( $data['snippets'] ) ) { $count = count( $data['snippets'] ); } ?> page_slug ) { // Don't redirect this page to avoid an infinite loop. return; } if ( false !== get_transient( 'wpcode_deploy_snippet_id' ) ) { // Don't delete the transient here, it will be deleted in the 1-click page. wp_safe_redirect( $this->admin_url( 'admin.php?page=wpcode-click' ) ); exit; } } /** * Get a text field markup. * * @param string $id The id of the text field. * @param string $value The value of the text field. * @param string $description The description of the text field. * @param bool $wide Whether the text field should be wide. * @param string $type The type of the text field. * * @return string */ public function get_input_text( $id, $value = '', $description = '', $wide = false, $type = 'text' ) { $allowed_types = array( 'text', 'email', 'url', 'number', 'password', ); if ( in_array( $type, $allowed_types, true ) ) { $type = esc_attr( $type ); } else { $type = 'text'; } $class = 'wpcode-regular-text'; if ( $wide ) { $class .= ' wpcode-wide-text'; } if ( 'text' !== $type ) { $class .= ' wpcode-input-' . $type; } $markup = ''; if ( ! empty( $description ) ) { $markup .= '

    ' . wp_kses_post( $description ) . '

    '; } return $markup; } /** * Get an email field. * * @param string $id The id of the text field. * @param string $value The value of the text field. * @param string $description The description of the text field. * @param bool $wide Whether the text field should be wide. * * @return string */ public function get_input_email( $id, $value = '', $description = '', $wide = false ) { return $this->get_input_text( $id, $value, $description, $wide, 'email' ); } /** * Get an admin URL. * * @param string $path The path to append to the admin URL. * * @return string */ public function admin_url( $path ) { return admin_url( $path ); } }