array( 10, 'dashicons-email-alt' ), 'soglasno' => array( 20, 'dashicons-shield-alt' ), 'yasno' => array( 30, 'dashicons-editor-spellcheck' ), 'propusk' => array( 40, 'dashicons-smartphone' ), 'zashita-24-7' => array( 50, 'dashicons-shield' ), ); /** @var bool Этот плагин создал пункт WP-ADDON и показывает страницу «Обзор». */ private static $owner = false; public static function init() { add_action( 'admin_menu', array( __CLASS__, 'parent' ), 9 ); add_action( 'admin_menu', array( __CLASS__, 'sort' ), 999 ); add_action( 'admin_enqueue_scripts', array( __CLASS__, 'styles' ) ); } /** Хук страницы плагина внутри WP-ADDON. */ public static function hook( $slug ) { return self::PARENT . '_page_' . $slug; } /** Создаёт пункт WP-ADDON и страницу «Обзор», если их ещё не создал другой плагин семейства. */ public static function parent() { global $admin_page_hooks; if ( ! empty( $admin_page_hooks[ self::PARENT ] ) ) { return; } self::$owner = true; add_menu_page( 'WP-ADDON', 'WP-ADDON', self::CAP, self::PARENT, array( __CLASS__, 'render' ), self::icon(), 81 ); add_submenu_page( self::PARENT, __( 'Плагины WP-ADDON', 'propusk' ), __( 'Обзор', 'propusk' ), self::CAP, self::PARENT, array( __CLASS__, 'render' ), 0 ); } /** * Добавляет страницу плагина в WP-ADDON. * * @return string|false Хук страницы. */ public static function add_page( $page_title, $menu_title, $slug, $callback ) { return add_submenu_page( self::PARENT, $page_title, $menu_title, self::CAP, $slug, $callback ); } private static function position( $slug ) { if ( self::PARENT === $slug ) { return 0; } return array_key_exists( $slug, self::ORDER ) ? self::ORDER[ $slug ][0] : 100; } /** Порядок пунктов внутри WP-ADDON не зависит от того, какой плагин загрузился первым. */ public static function sort() { global $submenu; if ( empty( $submenu[ self::PARENT ] ) || ! is_array( $submenu[ self::PARENT ] ) ) { return; } $items = array_values( $submenu[ self::PARENT ] ); $keys = array(); foreach ( $items as $i => $item ) { $keys[ $i ] = array( self::position( (string) $item[2] ), $i ); } uksort( $items, static function ( $a, $b ) use ( $keys ) { return $keys[ $a ] <=> $keys[ $b ]; } ); $submenu[ self::PARENT ] = array_values( $items ); // phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited -- сортировка своего пункта меню. } private static function icon() { $svg = ''; return 'data:image/svg+xml;base64,' . base64_encode( $svg ); // phpcs:ignore WordPress.PHP.DiscouragedPHPFunctions.obfuscation_base64_encode -- иконка меню в формате, который понимает WordPress. } public static function styles( $hook ) { if ( ! self::$owner || 'toplevel_page_' . self::PARENT !== $hook ) { return; } wp_register_style( 'prps-wpaddon-hub', false, array(), PRPS_VERSION ); wp_enqueue_style( 'prps-wpaddon-hub' ); wp_add_inline_style( 'prps-wpaddon-hub', '.wpaddon-hub{max-width:1100px}.wpaddon-hub__lead{font-size:14px;color:#50575e;max-width:720px;margin:4px 0 24px}' . '.wpaddon-hub__grid{display:grid;grid-template-columns:repeat(auto-fill,minmax(300px,1fr));gap:16px}' . '.wpaddon-card{background:#fff;border:1px solid #dcdcde;border-radius:10px;padding:20px;display:flex;flex-direction:column;gap:10px}' . '.wpaddon-card__head{display:flex;align-items:center;gap:10px}.wpaddon-card__head .dashicons{font-size:24px;width:24px;height:24px;color:#2271b1}' . '.wpaddon-card h2{margin:0;font-size:16px}.wpaddon-card p{margin:0;color:#50575e}' . '.wpaddon-card__meta{font-size:12px;color:#787c82;display:flex;gap:8px;align-items:center}' . '.wpaddon-badge{display:inline-block;padding:1px 8px;border-radius:999px;background:#e7f5ec;color:#00703c;font-weight:600}' . '.wpaddon-card__actions{margin-top:auto;display:flex;gap:8px;flex-wrap:wrap}.wpaddon-hub__foot{margin-top:24px;color:#50575e}' ); } /** Плагины семейства по пунктам меню WP-ADDON и их заголовкам. */ private static function plugins() { global $submenu; if ( ! function_exists( 'get_plugins' ) ) { require_once ABSPATH . 'wp-admin/includes/plugin.php'; } $installed = get_plugins(); $out = array(); foreach ( (array) ( $submenu[ self::PARENT ] ?? array() ) as $item ) { $slug = (string) $item[2]; if ( self::PARENT === $slug ) { continue; } $file = $slug . '/' . $slug . '.php'; $header = $installed[ $file ] ?? array(); $out[] = array( 'name' => wp_strip_all_tags( (string) $item[0] ), 'desc' => (string) ( $header['Description'] ?? '' ), 'version' => (string) ( $header['Version'] ?? '' ), 'url' => admin_url( 'admin.php?page=' . $slug ), 'pro' => is_plugin_active( $slug . '-pro/' . $slug . '-pro.php' ), 'pro_url' => 'https://wp-addon.ru/' . $slug . '/#pricing', 'icon' => array_key_exists( $slug, self::ORDER ) ? self::ORDER[ $slug ][1] : 'dashicons-admin-plugins', ); } return $out; } /** Страница «Обзор»: установленные плагины семейства. */ public static function render() { if ( ! current_user_can( self::CAP ) ) { return; } echo '
' . esc_html__( 'Плагины wp-addon.ru, которые установлены на этом сайте. Здесь собраны их настройки: откройте нужный плагин или перейдите к нему через меню слева.', 'propusk' ) . '
'; echo '' . esc_html( $p['desc'] ) . '
'; echo ''; echo '' . wp_kses_post( sprintf( /* translators: %s: ссылка на сайт */ __( 'Все плагины и подписка Pro — на сайте %s.', 'propusk' ), 'wp-addon.ru' ) ) . '
'; echo '