File: /var/www/vhosts/uyarreklam.com.tr/httpdocs/Menu.php.tar
var/www/vhosts/uyarreklam.com.tr/httpdocs/wp-content/plugins/optinmonster/OMAPI/Menu.php 0000644 00000036653 15154167340 0025540 0 ustar 00 <?php
/**
* Menu class.
*
* @since 1.0.0
*
* @package OMAPI
* @author Thomas Griffin
*/
// Exit if accessed directly.
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
/**
* Menu class.
*
* @since 1.0.0
*/
class OMAPI_Menu {
/**
* The admin page slug.
*
* @since 2.0.0
*/
const SLUG = 'optin-monster-dashboard';
/**
* Holds the class object.
*
* @since 1.0.0
*
* @var object
*/
public static $instance;
/**
* Path to the file.
*
* @since 1.0.0
*
* @var string
*/
public $file = __FILE__;
/**
* Holds the base class object.
*
* @since 1.0.0
*
* @var OMAPI
*/
public $base;
/**
* The OMAPI_Pages object.
*
* @since 1.9.10
*
* @var OMAPI_Pages
*/
public $pages = null;
/**
* Panel slugs/names.
*
* @since 1.9.0
*
* @var array
*/
public $panels = array();
/**
* Registered page hooks.
*
* @since 1.9.10
*
* @var array
*/
public $hooks = array();
/**
* The OM landing page url.
*
* @since 1.8.4
*/
const LANDING_URL = 'https://optinmonster.com/wp/?utm_source=orgplugin&utm_medium=link&utm_campaign=wpdashboard';
/**
* Primary class constructor.
*
* @since 1.0.0
*
* @param bool $is_testing Whether we are doing integration testing.
*/
public function __construct( $is_testing = false ) {
if ( ! $is_testing ) {
// Set our object.
$this->set();
// Load actions and filters.
add_action( 'admin_menu', array( $this, 'menu' ) );
add_action( 'admin_menu', array( $this, 'after_menu_registration' ), 999 );
// Load custom admin bar menu items.
add_action( 'admin_bar_menu', array( $this, 'admin_bar_menu' ), 999 );
// Load helper body classes.
add_filter( 'admin_body_class', array( $this, 'admin_body_classes' ) );
add_filter( 'plugin_action_links_' . plugin_basename( OMAPI_FILE ), array( $this, 'output_plugin_links' ) );
// Add upgrade link to plugin page.
add_filter( 'plugin_row_meta', array( $this, 'maybe_add_upgrade_link' ), 10, 2 );
}
}
/**
* Sets our object instance and base class instance.
*
* @since 1.0.0
*/
public function set() {
self::$instance = $this;
$this->base = OMAPI::get_instance();
}
/**
* Loads the OptinMonster admin menu.
*
* @since 1.0.0
*/
public function menu() {
if ( ! current_user_can( $this->base->access_capability( self::SLUG ) ) ) {
return;
}
$this->pages = new OMAPI_Pages();
$this->pages->setup();
// Filter to change the menu position if there is any conflict with another menu on the same position.
$menu_position = apply_filters( 'optin_monster_api_menu_position', 26 );
$this->hooks[] = add_menu_page(
'OptinMonster',
'OptinMonster' . $this->notifications_count(),
$this->base->access_capability( self::SLUG ),
self::SLUG,
array( $this->pages, 'render_app_loading_page' ),
$this->icon_svg(),
$menu_position
);
// Just add a placeholder secondary page.
$this->hooks[] = add_submenu_page(
self::SLUG, // parent slug.
__( 'Dashboard', 'optin-monster-api' ), // page title.
__( 'Dashboard', 'optin-monster-api' ), // menu title.
$this->base->access_capability( self::SLUG ),
self::SLUG,
array( $this->pages, 'render_app_loading_page' )
);
$this->hooks = array_merge( $this->hooks, $this->pages->register_submenu_pages( self::SLUG ) );
// Register our old api page and redirect to the new dashboard.
$hook = add_submenu_page(
self::SLUG . '-hidden',
'OptinMonster',
'OptinMonster',
$this->base->access_capability( self::SLUG ),
'optin-monster-api-settings',
'__return_null'
);
add_action( 'load-' . $hook, array( $this, 'redirect_to_dashboard' ) );
global $submenu;
if ( $submenu ) {
// Register link under the "Dashboard" menu for "Marketing Education" which directs to the "University".
// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$submenu['index.php'][] = array(
esc_html__( 'Marketing Education', 'optin-monster-api' ),
$this->base->access_capability( self::SLUG ),
esc_url_raw( OMAPI_Urls::university() ),
);
// Register link under the appearance menu for "Popup Builder".
// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$submenu['themes.php'][] = array(
esc_html__( 'Popup Builder', 'optin-monster-api' ),
$this->base->access_capability( self::SLUG ),
esc_url_raw( OMAPI_Urls::templates() ),
);
}
// Maybe add custom CSS for our menu upgrade link.
if ( $this->base->can_show_upgrade() ) {
add_action( 'admin_footer', array( $this, 'add_upgrade_link_css' ) );
}
}
/**
* Loads custom items in the WP admin bar menu.
*
* @since 2.6.12
*
* @param object $admin_bar The WP admin bar object.
*/
public function admin_bar_menu( $admin_bar ) {
if ( ! current_user_can( $this->base->access_capability( self::SLUG ) ) ) {
return;
}
$admin_bar->add_node(
array(
'id' => 'om-new-campaign',
'title' => esc_html__( 'Popup', 'optin-monster-api' ),
'href' => esc_url_raw( OMAPI_Urls::templates() ),
'parent' => 'new-content',
)
);
}
/**
* Get the Archie SVG, and maybe encode it.
*
* @since 1.0.0
*
* @param string $fill Color of Archie.
* @param bool $return_encoded Whether the svg shoud be base_64 encoded.
*
* @return string Archie SVG.
*/
public function icon_svg( $fill = '#a0a5aa', $return_encoded = true ) {
$icon = file_get_contents( plugin_dir_path( OMAPI_FILE ) . '/assets/css/images/icons/archie-icon.svg' );
$icon = str_replace( 'fill="currentColor"', 'fill="' . $fill . '"', $icon );
if ( $return_encoded ) {
// phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode
$icon = 'data:image/svg+xml;base64,' . base64_encode( $icon );
}
return $icon;
}
/**
* Handles enqueueing assets for registered pages, and ensuring about page is at bottom.
*
* @since 1.9.10
*
* @return void
*/
public function after_menu_registration() {
if ( ! current_user_can( $this->base->access_capability( self::SLUG ) ) ) {
return;
}
global $submenu;
// Make sure the about page is still the last page.
if ( isset( $submenu[ self::SLUG ] ) ) {
$after = array();
$at_end = array( 'optin-monster-about', 'optin-monster-upgrade', 'optin-monster-bfcm' );
foreach ( $submenu[ self::SLUG ] as $key => $menu ) {
// phpcs:ignore WordPress.PHP.StrictInArray.MissingTrueStrict
if ( isset( $menu[2] ) && in_array( $menu[2], $at_end ) ) {
$after[] = $menu;
unset( $submenu[ self::SLUG ][ $key ] );
}
}
// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$submenu[ self::SLUG ] = array_values( $submenu[ self::SLUG ] );
foreach ( $after as $menu ) {
// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$submenu[ self::SLUG ][] = $menu;
}
}
// Load settings page assets.
foreach ( $this->hooks as $hook ) {
if ( ! empty( $hook ) ) {
add_action( 'load-' . $hook, array( $this, 'assets' ) );
}
}
}
/**
* Add pages to plugin action links in the Plugins table.
*
* @since 1.9.10
*
* @param array $links Default plugin action links.
*
* @return array $links Amended plugin action links.
*/
public function output_plugin_links( $links ) {
// Maybe add an upgrade link to the plugin links.
$upgrade_links = array();
if ( $this->base->can_show_upgrade() ) {
$upgrade_links[] = sprintf( '<a class="om-plugin-upgrade-link" href="%s">%s</a>', OMAPI_Urls::upgrade( 'plugin_action_link' ), 'vbp_pro' === $this->base->get_level() ? __( 'Upgrade to Growth', 'optin-monster-api' ) : __( 'Upgrade to Pro', 'optin-monster-api' ) );
}
$new_links = $this->base->get_api_credentials()
? array(
sprintf( '<a href="%s">%s</a>', OMAPI_Urls::campaigns(), __( 'Campaigns', 'optin-monster-api' ) ),
sprintf( '<a href="%s">%s</a>', OMAPI_Urls::settings(), __( 'Settings', 'optin-monster-api' ) ),
)
: array(
sprintf( '<a href="%s">%s</a>', OMAPI_Urls::onboarding(), __( 'Get Started', 'optin-monster-api' ) ),
);
$links = array_merge( $upgrade_links, $new_links, $links );
return $links;
}
/**
* Add upgrade link to the plugin row.
*
* @since 2.4.0
*
* @param array $links Default plugin row links.
* @param string $file The plugin file.
*
* @return array The links array.
*/
public function maybe_add_upgrade_link( $links, $file ) {
if ( plugin_basename( OMAPI_FILE ) === $file ) {
// If user upgradeable or not registered yet, let's put an upgrade link.
if ( $this->base->can_show_upgrade() ) {
$label = 'vbp_pro' === $this->base->get_level()
? __( 'Upgrade to Growth', 'optin-monster-api' )
: __( 'Upgrade to Pro', 'optin-monster-api' );
$upgrade_link = sprintf(
'<a class="om-plugin-upgrade-link" href="%s" aria-label="%s" target="_blank" rel="noopener">%s</a>',
esc_url_raw( OMAPI_Urls::upgrade( 'plugin_row_meta' ) ),
$label,
$label
);
// Maybe show the the BF item in the plugins description.
$pages = new OMAPI_Pages();
$bfcm_item = $pages->should_show_bfcf_menu_item();
if ( $bfcm_item ) {
$bflink = sprintf(
'<a class="om-plugin-bf-link" href="%s" style="font-weight: 700; color: #ff0000;">%s</a>',
esc_url( $bfcm_item['redirect'] ),
esc_html( $bfcm_item['alternate-name'] )
);
$links[] = $bflink;
}
array_splice( $links, 1, 0, array( $upgrade_link ) );
}
}
return $links;
}
/**
* Adds om admin body classes
*
* @since 1.3.4
*
* @param array $classes Body classes.
*
* @return array
*/
public function admin_body_classes( $classes ) {
$classes .= ' omapi-screen ';
if ( $this->base->get_api_key_errors() ) {
$classes .= ' omapi-has-api-errors ';
}
return $classes;
}
/**
* Check if we're on one of the OM menu/sub-menu pages.
*
* @since 1.9.0
*
* @return boolean
*/
public function is_om_page() {
if ( ! is_admin() ) {
return false;
}
if ( function_exists( 'get_current_screen' ) ) {
$screen = get_current_screen();
$page = $screen->id;
if ( false !== strpos( $page, 'toplevel_page_optin-monster-' ) ) {
return true;
}
if ( ! empty( $screen->parent_base ) && false !== strpos( $screen->parent_base, 'optin-monster-' ) ) {
return true;
}
} else {
// phpcs:ignore WordPress.Security.NonceVerification.Recommended
$page = isset( $_GET['page'] ) ? sanitize_key( wp_unslash( $_GET['page'] ) ) : '';
}
return false !== strpos( $page, 'optin-monster' );
}
/**
* Loads assets for the settings page.
*
* @since 1.0.0
*/
public function assets() {
add_action( 'admin_enqueue_scripts', array( $this, 'styles' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'scripts' ) );
add_filter( 'admin_footer_text', array( $this, 'footer' ) );
add_action( 'in_admin_header', array( $this, 'output_plugin_screen_banner' ) );
add_action( 'admin_enqueue_scripts', array( $this, 'fix_plugin_js_conflicts' ), 100 );
add_action( 'admin_print_footer_scripts', array( $this, 'fix_plugin_js_conflicts' ), 100 );
}
/**
* Register and enqueue settings page specific CSS.
*
* @since 1.0.0
*/
public function styles() {
$version = $this->base->asset_version();
$prefix = $this->base->plugin_slug . '-';
wp_enqueue_style( $prefix . 'font-awesome', $this->base->url . 'assets/css/font-awesome.min.css', array(), $version );
wp_enqueue_style( $prefix . 'common', $this->base->url . 'assets/dist/css/common.min.css', array( $prefix . 'font-awesome' ), $version );
// Run a hook to load in custom styles.
do_action( 'optin_monster_api_admin_styles' );
}
/**
* Register and enqueue settings page specific JS.
*
* @since 1.0.0
*/
public function scripts() {
$version = $this->base->asset_version();
wp_register_script(
$this->base->plugin_slug . '-admin',
$this->base->url . 'assets/dist/js/admin.min.js',
array( 'jquery' ),
$version,
true
);
wp_enqueue_script( $this->base->plugin_slug . '-admin' );
// Run a hook to load in custom styles.
do_action( 'optin_monster_api_admin_scripts' );
}
/**
* Deque specific scripts that cause conflicts on settings page. E.g.
* - optimizely
* - bigcommerce
* - learnpress
*
* @since 1.1.5.9
*/
public function fix_plugin_js_conflicts() {
if ( $this->is_om_page() ) {
global $wp_scripts;
$remove = array(
'lp-',
'optimizely',
'bigcommerce-',
);
foreach ( $wp_scripts->queue as $script ) {
foreach ( $remove as $search ) {
if ( 0 === strpos( $script, $search ) ) {
// Dequeue scripts that might cause our settings not to work properly.
wp_dequeue_script( $script );
}
}
}
}
}
/**
* Customizes the footer text on the OptinMonster settings page.
*
* @since 1.0.0
*
* @param string $text The default admin footer text.
* @return string $text Amended admin footer text.
*/
public function footer( $text ) {
$url = 'https://wordpress.org/support/plugin/optinmonster/reviews?filter=5#new-post';
/* translators: %1$s - OptinMonster plugin support url */
$text = sprintf( __( 'Please rate <strong>OptinMonster</strong> <a href="%1$s" target="_blank" rel="noopener">★★★★★</a> on <a href="%1$s" target="_blank" rel="noopener noreferrer">WordPress.org</a> to help us spread the word. Thank you from the OptinMonster team!', 'optin-monster-api' ), $url );
return $text;
}
/**
* Echo out plugin header banner
*
* @since 1.1.5.2
*/
public function output_plugin_screen_banner() {
$path = 'vue/dist';
$dir = trailingslashit( dirname( $this->base->file ) ) . $path;
$loader = new OMAPI_AssetLoader( $dir );
$logo = '#';
$help = '#';
$list = $loader->getAssetsList( $dir );
foreach ( $list as $item ) {
if (
false !== strpos( $item, 'logo-om' )
&& preg_match( '/\.svg$/', $item )
) {
$logo = $loader->getAssetUri( trim( $item, '/' ), $this->base->url . $path );
}
if ( false !== strpos( $item, '/help-circle.' ) ) {
$help = $loader->getAssetUri( trim( $item, '/' ), $this->base->url . $path );
}
}
$this->base->output_view( 'plugin-banner.php', compact( 'logo', 'help' ) );
}
/**
* Get the parent slug (contextual based on beta being enabled).
*
* @since 1.9.10
*
* @return string
*/
public function parent_slug() {
return self::SLUG;
}
/**
* Redirects to main OM page.
*
* @since 1.9.10
*
* @param array $args Array of query args.
*
* @return void
*/
public function redirect_to_dashboard( $args = array() ) {
$url = OMAPI_Urls::dashboard( $args );
wp_safe_redirect( esc_url_raw( $url ) );
exit;
}
/**
* Add the notifications bubble to the menu.
*
* @since 2.0.0
*
* @return string Notifications bubble markup.
*/
public function notifications_count() {
$count = apply_filters( 'optin_monster_api_notifications_count', 0, $this );
$count = absint( $count );
$html = '';
if ( $count ) {
$html .= sprintf(
' <span class="om-notifications-count update-plugins count-%1$d"><span class="plugin-count">%2$s</span></span>',
$count,
esc_html( number_format_i18n( $count ) )
);
}
add_action( 'admin_footer', array( $this, 'add_jiggle_css' ) );
return $html;
}
/**
* Output the css that jiggles the OM notification count bubble.
*
* @since 2.0.0
*/
public function add_jiggle_css() {
$this->base->output_min_css( 'jiggle-css.php' );
}
/**
* Output the css that highlights the OM upgrade menu link.
*
* @since 2.6.12
*/
public function add_upgrade_link_css() {
$this->base->output_min_css( 'upgrade-link-css.php' );
}
}
uyarreklam.com.tr/httpdocs/wp-content/plugins/woocommerce/src/Admin/Features/Navigation/Menu.php 0000644 00000054435 15155130276 0032063 0 ustar 00 var/www/vhosts <?php
/**
* WooCommerce Navigation Menu
*
* @package Woocommerce Navigation
*/
namespace Automattic\WooCommerce\Admin\Features\Navigation;
use Automattic\WooCommerce\Admin\Features\Navigation\Favorites;
use Automattic\WooCommerce\Admin\Features\Navigation\Screen;
use Automattic\WooCommerce\Admin\Features\Navigation\CoreMenu;
/**
* Contains logic for the WooCommerce Navigation menu.
*/
class Menu {
/**
* Class instance.
*
* @var Menu instance
*/
protected static $instance = null;
/**
* Array index of menu capability.
*
* @var int
*/
const CAPABILITY = 1;
/**
* Array index of menu callback.
*
* @var int
*/
const CALLBACK = 2;
/**
* Array index of menu callback.
*
* @var int
*/
const SLUG = 3;
/**
* Array index of menu CSS class string.
*
* @var int
*/
const CSS_CLASSES = 4;
/**
* Array of usable menu IDs.
*/
const MENU_IDS = array(
'primary',
'favorites',
'plugins',
'secondary',
);
/**
* Store menu items.
*
* @var array
*/
protected static $menu_items = array();
/**
* Store categories with menu item IDs.
*
* @var array
*/
protected static $categories = array(
'woocommerce' => array(),
);
/**
* Registered callbacks or URLs with migration boolean as key value pairs.
*
* @var array
*/
protected static $callbacks = array();
/**
* Get class instance.
*/
final public static function instance() {
if ( ! static::$instance ) {
static::$instance = new static();
}
return static::$instance;
}
/**
* Init.
*/
public function init() {
add_action( 'admin_menu', array( $this, 'add_core_items' ), 100 );
add_filter( 'admin_enqueue_scripts', array( $this, 'enqueue_data' ), 20 );
add_filter( 'admin_menu', array( $this, 'migrate_core_child_items' ), PHP_INT_MAX - 1 );
add_filter( 'admin_menu', array( $this, 'migrate_menu_items' ), PHP_INT_MAX - 2 );
}
/**
* Convert a WordPress menu callback to a URL.
*
* @param string $callback Menu callback.
* @return string
*/
public static function get_callback_url( $callback ) {
// Return the full URL.
if ( strpos( $callback, 'http' ) === 0 ) {
return $callback;
}
$pos = strpos( $callback, '?' );
$file = $pos > 0 ? substr( $callback, 0, $pos ) : $callback;
if ( file_exists( ABSPATH . "/wp-admin/$file" ) ) {
return $callback;
}
return 'admin.php?page=' . $callback;
}
/**
* Get the parent key if one exists.
*
* @param string $callback Callback or URL.
* @return string|null
*/
public static function get_parent_key( $callback ) {
global $submenu;
if ( ! $submenu ) {
return null;
}
// This is already a parent item.
if ( isset( $submenu[ $callback ] ) ) {
return null;
}
foreach ( $submenu as $key => $menu ) {
foreach ( $menu as $item ) {
if ( $item[ self::CALLBACK ] === $callback ) {
return $key;
}
}
}
return null;
}
/**
* Adds a top level menu item to the navigation.
*
* @param array $args Array containing the necessary arguments.
* $args = array(
* 'id' => (string) The unique ID of the menu item. Required.
* 'title' => (string) Title of the menu item. Required.
* 'url' => (string) URL or callback to be used. Required.
* 'order' => (int) Menu item order.
* 'migrate' => (bool) Whether or not to hide the item in the wp admin menu.
* 'menuId' => (string) The ID of the menu to add the category to.
* ).
*/
private static function add_category( $args ) {
if ( ! isset( $args['id'] ) || isset( self::$menu_items[ $args['id'] ] ) ) {
return;
}
$defaults = array(
'id' => '',
'title' => '',
'order' => 100,
'migrate' => true,
'menuId' => 'primary',
'isCategory' => true,
);
$menu_item = wp_parse_args( $args, $defaults );
$menu_item['title'] = wp_strip_all_tags( wp_specialchars_decode( $menu_item['title'] ) );
unset( $menu_item['url'] );
unset( $menu_item['capability'] );
if ( ! isset( $menu_item['parent'] ) ) {
$menu_item['parent'] = 'woocommerce';
$menu_item['backButtonLabel'] = __(
'WooCommerce Home',
'woocommerce'
);
}
self::$menu_items[ $menu_item['id'] ] = $menu_item;
self::$categories[ $menu_item['id'] ] = array();
self::$categories[ $menu_item['parent'] ][] = $menu_item['id'];
if ( isset( $args['url'] ) ) {
self::$callbacks[ $args['url'] ] = $menu_item['migrate'];
}
}
/**
* Adds a child menu item to the navigation.
*
* @param array $args Array containing the necessary arguments.
* $args = array(
* 'id' => (string) The unique ID of the menu item. Required.
* 'title' => (string) Title of the menu item. Required.
* 'parent' => (string) Parent menu item ID.
* 'capability' => (string) Capability to view this menu item.
* 'url' => (string) URL or callback to be used. Required.
* 'order' => (int) Menu item order.
* 'migrate' => (bool) Whether or not to hide the item in the wp admin menu.
* 'menuId' => (string) The ID of the menu to add the item to.
* 'matchExpression' => (string) A regular expression used to identify if the menu item is active.
* ).
*/
private static function add_item( $args ) {
if ( ! isset( $args['id'] ) ) {
return;
}
if ( isset( self::$menu_items[ $args['id'] ] ) ) {
error_log( // phpcs:ignore
sprintf(
/* translators: 1: Duplicate menu item path. */
esc_html__( 'You have attempted to register a duplicate item with WooCommerce Navigation: %1$s', 'woocommerce' ),
'`' . $args['id'] . '`'
)
);
return;
}
$defaults = array(
'id' => '',
'title' => '',
'capability' => 'manage_woocommerce',
'url' => '',
'order' => 100,
'migrate' => true,
'menuId' => 'primary',
);
$menu_item = wp_parse_args( $args, $defaults );
$menu_item['title'] = wp_strip_all_tags( wp_specialchars_decode( $menu_item['title'] ) );
$menu_item['url'] = self::get_callback_url( $menu_item['url'] );
if ( ! isset( $menu_item['parent'] ) ) {
$menu_item['parent'] = 'woocommerce';
}
$menu_item['menuId'] = self::get_item_menu_id( $menu_item );
self::$menu_items[ $menu_item['id'] ] = $menu_item;
self::$categories[ $menu_item['parent'] ][] = $menu_item['id'];
if ( isset( $args['url'] ) ) {
self::$callbacks[ $args['url'] ] = $menu_item['migrate'];
}
}
/**
* Get an item's menu ID from its parent.
*
* @param array $item Item args.
* @return string
*/
public static function get_item_menu_id( $item ) {
$favorites = Favorites::get_all( get_current_user_id() );
if ( is_array( $favorites ) && ! empty( $favorites ) && in_array( $item['id'], $favorites, true ) ) {
return 'favorites';
}
if ( isset( $item['parent'] ) && isset( self::$menu_items[ $item['parent'] ] ) ) {
$menu_id = self::$menu_items[ $item['parent'] ]['menuId'];
return 'favorites' === $menu_id
? 'plugins'
: $menu_id;
}
return $item['menuId'];
}
/**
* Adds a plugin category.
*
* @param array $args Array containing the necessary arguments.
* $args = array(
* 'id' => (string) The unique ID of the menu item. Required.
* 'title' => (string) Title of the menu item. Required.
* 'url' => (string) URL or callback to be used. Required.
* 'migrate' => (bool) Whether or not to hide the item in the wp admin menu.
* 'order' => (int) Menu item order.
* ).
*/
public static function add_plugin_category( $args ) {
$category_args = array_merge(
$args,
array(
'menuId' => 'plugins',
)
);
if ( ! isset( $category_args['parent'] ) ) {
unset( $category_args['order'] );
}
$menu_id = self::get_item_menu_id( $category_args );
if ( ! in_array( $menu_id, array( 'plugins', 'favorites' ), true ) ) {
return;
}
$category_args['menuId'] = $menu_id;
self::add_category( $category_args );
}
/**
* Adds a plugin item.
*
* @param array $args Array containing the necessary arguments.
* $args = array(
* 'id' => (string) The unique ID of the menu item. Required.
* 'title' => (string) Title of the menu item. Required.
* 'parent' => (string) Parent menu item ID.
* 'capability' => (string) Capability to view this menu item.
* 'url' => (string) URL or callback to be used. Required.
* 'migrate' => (bool) Whether or not to hide the item in the wp admin menu.
* 'order' => (int) Menu item order.
* 'matchExpression' => (string) A regular expression used to identify if the menu item is active.
* ).
*/
public static function add_plugin_item( $args ) {
if ( ! isset( $args['parent'] ) ) {
unset( $args['order'] );
}
$item_args = array_merge(
$args,
array(
'menuId' => 'plugins',
)
);
$menu_id = self::get_item_menu_id( $item_args );
if ( 'plugins' !== $menu_id ) {
return;
}
self::add_item( $item_args );
}
/**
* Adds a plugin setting item.
*
* @param array $args Array containing the necessary arguments.
* $args = array(
* 'id' => (string) The unique ID of the menu item. Required.
* 'title' => (string) Title of the menu item. Required.
* 'capability' => (string) Capability to view this menu item.
* 'url' => (string) URL or callback to be used. Required.
* 'migrate' => (bool) Whether or not to hide the item in the wp admin menu.
* ).
*/
public static function add_setting_item( $args ) {
unset( $args['order'] );
if ( isset( $args['parent'] ) || isset( $args['menuId'] ) ) {
error_log( // phpcs:ignore
sprintf(
/* translators: 1: Duplicate menu item path. */
esc_html__( 'The item ID %1$s attempted to register using an invalid option. The arguments `menuId` and `parent` are not allowed for add_setting_item()', 'woocommerce' ),
'`' . $args['id'] . '`'
)
);
}
$item_args = array_merge(
$args,
array(
'menuId' => 'secondary',
'parent' => 'woocommerce-settings',
)
);
self::add_item( $item_args );
}
/**
* Get menu item templates for a given post type.
*
* @param string $post_type Post type to add.
* @param array $menu_args Arguments merged with the returned menu items.
* @return array
*/
public static function get_post_type_items( $post_type, $menu_args = array() ) {
$post_type_object = get_post_type_object( $post_type );
if ( ! $post_type_object || ! $post_type_object->show_in_menu ) {
return;
}
$parent = isset( $menu_args['parent'] ) ? $menu_args['parent'] . '-' : '';
$match_expression = isset( $_GET['post'] ) && get_post_type( intval( $_GET['post'] ) ) === $post_type // phpcs:ignore WordPress.Security.NonceVerification
? '(edit.php|post.php)'
: null;
return array(
'default' => array_merge(
array(
'title' => esc_attr( $post_type_object->labels->menu_name ),
'capability' => $post_type_object->cap->edit_posts,
'id' => $parent . $post_type,
'url' => "edit.php?post_type={$post_type}",
'matchExpression' => $match_expression,
),
$menu_args
),
'all' => array_merge(
array(
'title' => esc_attr( $post_type_object->labels->all_items ),
'capability' => $post_type_object->cap->edit_posts,
'id' => "{$parent}{$post_type}-all-items",
'url' => "edit.php?post_type={$post_type}",
'order' => 10,
'matchExpression' => $match_expression,
),
$menu_args
),
'new' => array_merge(
array(
'title' => esc_attr( $post_type_object->labels->add_new ),
'capability' => $post_type_object->cap->create_posts,
'id' => "{$parent}{$post_type}-add-new",
'url' => "post-new.php?post_type={$post_type}",
'order' => 20,
),
$menu_args
),
);
}
/**
* Get menu item templates for a given taxonomy.
*
* @param string $taxonomy Taxonomy to add.
* @param array $menu_args Arguments merged with the returned menu items.
* @return array
*/
public static function get_taxonomy_items( $taxonomy, $menu_args = array() ) {
$taxonomy_object = get_taxonomy( $taxonomy );
if ( ! $taxonomy_object || ! $taxonomy_object->show_in_menu ) {
return;
}
$parent = isset( $menu_args['parent'] ) ? $menu_args['parent'] . '-' : '';
$product_type_query = ! empty( $taxonomy_object->object_type )
? "&post_type={$taxonomy_object->object_type[0]}"
: '';
$match_expression = 'term.php'; // Match term.php pages.
$match_expression .= "(?=.*[?|&]taxonomy={$taxonomy}(&|$|#))"; // Lookahead to match a taxonomy URL param.
$match_expression .= '|'; // Or.
$match_expression .= 'edit-tags.php'; // Match edit-tags.php pages.
$match_expression .= "(?=.*[?|&]taxonomy={$taxonomy}(&|$|#))"; // Lookahead to match a taxonomy URL param.
return array(
'default' => array_merge(
array(
'title' => esc_attr( $taxonomy_object->labels->menu_name ),
'capability' => $taxonomy_object->cap->edit_terms,
'id' => $parent . $taxonomy,
'url' => "edit-tags.php?taxonomy={$taxonomy}{$product_type_query}",
'matchExpression' => $match_expression,
),
$menu_args
),
'all' => array_merge(
array(
'title' => esc_attr( $taxonomy_object->labels->all_items ),
'capability' => $taxonomy_object->cap->edit_terms,
'id' => "{$parent}{$taxonomy}-all-items",
'url' => "edit-tags.php?taxonomy={$taxonomy}{$product_type_query}",
'matchExpression' => $match_expression,
'order' => 10,
),
$menu_args
),
);
}
/**
* Add core menu items.
*/
public function add_core_items() {
$categories = CoreMenu::get_categories();
foreach ( $categories as $category ) {
self::add_category( $category );
}
$items = CoreMenu::get_items();
foreach ( $items as $item ) {
if ( isset( $item['is_category'] ) && $item['is_category'] ) {
self::add_category( $item );
} else {
self::add_item( $item );
}
}
}
/**
* Add an item or taxonomy.
*
* @param array $menu_item Menu item.
*/
public function add_item_and_taxonomy( $menu_item ) {
if ( in_array( $menu_item[2], CoreMenu::get_excluded_items(), true ) ) {
return;
}
$menu_item[2] = htmlspecialchars_decode( $menu_item[2] );
// Don't add already added items.
$callbacks = self::get_callbacks();
if ( array_key_exists( $menu_item[2], $callbacks ) ) {
return;
}
// Don't add these Product submenus because they are added elsewhere.
if ( in_array( $menu_item[2], array( 'product_importer', 'product_exporter', 'product_attributes' ), true ) ) {
return;
}
self::add_plugin_item(
array(
'title' => $menu_item[0],
'capability' => $menu_item[1],
'id' => sanitize_title( $menu_item[0] ),
'url' => $menu_item[2],
)
);
// Determine if migrated items are a taxonomy or post_type. If they are, register them.
$parsed_url = wp_parse_url( $menu_item[2] );
$query_string = isset( $parsed_url['query'] ) ? $parsed_url['query'] : false;
if ( $query_string ) {
$query = array();
parse_str( $query_string, $query );
if ( isset( $query['taxonomy'] ) ) {
Screen::register_taxonomy( $query['taxonomy'] );
} elseif ( isset( $query['post_type'] ) ) {
Screen::register_post_type( $query['post_type'] );
}
}
}
/**
* Migrate any remaining WooCommerce child items.
*
* @param array $menu Menu items.
* @return array
*/
public function migrate_core_child_items( $menu ) {
global $submenu;
if ( ! isset( $submenu['woocommerce'] ) && ! isset( $submenu['edit.php?post_type=product'] ) ) {
return $menu;
}
$main_items = isset( $submenu['woocommerce'] ) ? $submenu['woocommerce'] : array();
$product_items = isset( $submenu['edit.php?post_type=product'] ) ? $submenu['edit.php?post_type=product'] : array();
foreach ( $main_items as $key => $menu_item ) {
self::add_item_and_taxonomy( $menu_item );
// phpcs:disable
if ( ! isset( $menu_item[ self::CSS_CLASSES ] ) ) {
$submenu['woocommerce'][ $key ][] .= ' hide-if-js';
} else if ( strpos( $submenu['woocommerce'][ $key ][ self::CSS_CLASSES ], 'hide-if-js' ) !== false ) {
continue;
} else {
$submenu['woocommerce'][ $key ][ self::CSS_CLASSES ] .= ' hide-if-js';
}
// phpcs:enable
}
foreach ( $product_items as $key => $menu_item ) {
self::add_item_and_taxonomy( $menu_item );
}
return $menu;
}
/**
* Check if a menu item's callback is registered in the menu.
*
* @param array $menu_item Menu item args.
* @return bool
*/
public static function has_callback( $menu_item ) {
if ( ! $menu_item || ! isset( $menu_item[ self::CALLBACK ] ) ) {
return false;
}
$callback = $menu_item[ self::CALLBACK ];
if (
isset( self::$callbacks[ $callback ] ) &&
self::$callbacks[ $callback ]
) {
return true;
}
if (
isset( self::$callbacks[ self::get_callback_url( $callback ) ] ) &&
self::$callbacks[ self::get_callback_url( $callback ) ]
) {
return true;
}
return false;
}
/**
* Hides all WP admin menus items and adds screen IDs to check for new items.
*/
public static function migrate_menu_items() {
global $menu, $submenu;
foreach ( $menu as $key => $menu_item ) {
if ( self::has_callback( $menu_item ) ) {
// Disable phpcs since we need to override submenu classes.
// Note that `phpcs:ignore WordPress.Variables.GlobalVariables.OverrideProhibited` does not work to disable this check.
// phpcs:disable
$menu[ $key ][ self::CSS_CLASSES ] .= ' hide-if-js';
// phps:enable
continue;
}
// WordPress core menus make the parent item the same URL as the first child.
$has_children = isset( $submenu[ $menu_item[ self::CALLBACK ] ] ) && isset( $submenu[ $menu_item[ self::CALLBACK ] ][0] );
$first_child = $has_children ? $submenu[ $menu_item[ self::CALLBACK ] ][0] : null;
if ( 'woocommerce' !== $menu_item[2] && self::has_callback( $first_child ) ) {
// Disable phpcs since we need to override submenu classes.
// Note that `phpcs:ignore WordPress.Variables.GlobalVariables.OverrideProhibited` does not work to disable this check.
// phpcs:disable
$menu[ $key ][ self::CSS_CLASSES ] .= ' hide-if-js';
// phps:enable
}
}
// Remove excluded submenu items
if ( isset( $submenu['woocommerce'] ) ) {
foreach ( $submenu['woocommerce'] as $key => $submenu_item ) {
if ( in_array( $submenu_item[ self::CALLBACK ], CoreMenu::get_excluded_items(), true ) ) {
if ( isset( $submenu['woocommerce'][ $key ][ self::CSS_CLASSES ] ) ) {
$submenu['woocommerce'][ $key ][ self::CSS_CLASSES ] .= ' hide-if-js';
} else {
$submenu['woocommerce'][ $key ][] = 'hide-if-js';
}
}
}
}
foreach ( $submenu as $parent_key => $parent ) {
foreach ( $parent as $key => $menu_item ) {
if ( self::has_callback( $menu_item ) ) {
// Disable phpcs since we need to override submenu classes.
// Note that `phpcs:ignore WordPress.Variables.GlobalVariables.OverrideProhibited` does not work to disable this check.
// phpcs:disable
if ( ! isset( $menu_item[ self::SLUG ] ) ) {
$submenu[ $parent_key ][ $key ][] = '';
}
if ( ! isset( $menu_item[ self::CSS_CLASSES ] ) ) {
$submenu[ $parent_key ][ $key ][] .= ' hide-if-js';
} else {
$submenu[ $parent_key ][ $key ][ self::CSS_CLASSES ] .= ' hide-if-js';
}
// phps:enable
}
}
}
foreach ( array_keys( self::$callbacks ) as $callback ) {
Screen::add_screen( $callback );
}
}
/**
* Add a callback to identify and hide pages in the WP menu.
*/
public static function hide_wp_menu_item( $callback ) {
self::$callbacks[ $callback ] = true;
}
/**
* Get registered menu items.
*
* @return array
*/
public static function get_items() {
return apply_filters( 'woocommerce_navigation_menu_items', self::$menu_items );
}
/**
* Get registered menu items.
*
* @return array
*/
public static function get_category_items( $category ) {
if ( ! isset( self::$categories[ $category ] ) ) {
return array();
}
$menu_item_ids = self::$categories[ $category ];
$category_menu_items = array();
foreach ( $menu_item_ids as $id ) {
if ( isset( self::$menu_items[ $id ] ) ) {
$category_menu_items[] = self::$menu_items[ $id ];
}
}
return apply_filters( 'woocommerce_navigation_menu_category_items', $category_menu_items );
}
/**
* Get registered callbacks.
*
* @return array
*/
public static function get_callbacks() {
return apply_filters( 'woocommerce_navigation_callbacks', self::$callbacks );
}
/**
* Gets the menu item data mapped by category and menu ID.
*
* @return array
*/
public static function get_mapped_menu_items() {
$menu_items = self::get_items();
$mapped_items = array();
// Sort the items by order and title.
$order = array_column( $menu_items, 'order' );
$title = array_column( $menu_items, 'title' );
array_multisort( $order, SORT_ASC, $title, SORT_ASC, $menu_items );
foreach ( $menu_items as $id => $menu_item ) {
$category_id = $menu_item[ 'parent' ];
$menu_id = $menu_item[ 'menuId' ];
if ( ! isset( $mapped_items[ $category_id ] ) ) {
$mapped_items[ $category_id ] = array();
foreach ( self::MENU_IDS as $available_menu_id ) {
$mapped_items[ $category_id ][ $available_menu_id ] = array();
}
}
// Incorrect menu ID.
if ( ! isset( $mapped_items[ $category_id ][ $menu_id ] ) ) {
continue;
}
// Remove the item if the user cannot access it.
if ( isset( $menu_item[ 'capability' ] ) && ! current_user_can( $menu_item[ 'capability' ] ) ) {
continue;
}
$mapped_items[ $category_id ][ $menu_id ][] = $menu_item;
}
return $mapped_items;
}
/**
* Add the menu to the page output.
*
* @param array $menu Menu items.
* @return array
*/
public function enqueue_data( $menu ) {
$data = array(
'menuItems' => array_values( self::get_items() ),
'rootBackUrl' => get_dashboard_url(),
);
wp_add_inline_script( WC_ADMIN_APP, 'window.wcNavigation = ' . wp_json_encode( $data ), 'before' );
}
}