first commit

This commit is contained in:
2023-09-12 21:41:04 +02:00
commit 3361a7f053
13284 changed files with 2116755 additions and 0 deletions

View File

@@ -0,0 +1,35 @@
<?php
namespace WPML\AdminMenu;
use WPML\FP\Lst;
use WPML\FP\Obj;
class Redirect implements \IWPML_Backend_Action {
public function add_hooks() {
add_action( 'init', [ $this, 'redirectOldMenuUrls' ] );
}
public function redirectOldMenuUrls() {
$query = $_GET;
$redirections = [
'page' => [
'wpml-translation-management/menu/main.php' => 'tm/menu/main.php',
],
'sm' => [
'translation-services' => 'translators'
]
];
foreach ( $query as $param => $value ) {
$query[ $param ] = Obj::pathOr( $value, [ $param, $value ], $redirections );
}
if ( array_diff_assoc( Lst::flatten( $_GET ), Lst::flatten( $query ) ) ) {
if ( wp_safe_redirect( add_query_arg( $query ), 301, 'WPML' ) ) {
exit;
}
}
}
}

View File

@@ -0,0 +1,203 @@
<?php
/**
* @author OnTheGo Systems
*/
class WPML_Admin_Menu_Item {
private $capability;
private $function;
private $menu_slug;
private $menu_title;
private $order;
private $page_title;
private $parent_slug;
/**
* WPML_Menu_Item constructor.
*
* @param array $args
*
* @throws \InvalidArgumentException
*/
public function __construct( array $args = null ) {
if ( $args ) {
$required_fields = array(
'capability',
'menu_slug',
'menu_title',
'page_title',
);
foreach ( $required_fields as $required_field ) {
if ( ! array_key_exists( $required_field, $args ) ) {
throw new InvalidArgumentException( $required_field . ' is missing.' );
}
}
$fields = array(
'function',
'order',
'parent_slug',
);
$fields = array_merge( $required_fields, $fields );
foreach ( $fields as $field ) {
if ( array_key_exists( $field, $args ) ) {
$this->{$field} = $args[ $field ];
}
}
}
}
/**
* Required by `usort` to remove duplicates, as casts array elements to string
*
* @return string
*/
public function __toString() {
return $this->serialize();
}
public function build( $root_slug ) {
$parent = $root_slug;
if ( $this->get_parent_slug() ) {
$parent = $this->get_parent_slug();
}
add_submenu_page(
$parent,
$this->get_page_title(),
$this->get_menu_title(),
$this->get_capability(),
$this->get_menu_slug(),
$this->get_function()
);
}
/**
* @return mixed
*/
public function get_parent_slug() {
return $this->parent_slug;
}
/**
* @param mixed $parent_slug
*/
public function set_parent_slug( $parent_slug ) {
$this->parent_slug = $parent_slug;
}
/**
* @return mixed
*/
public function get_page_title() {
return $this->page_title;
}
/**
* @param mixed $page_title
*/
public function set_page_title( $page_title ) {
$this->page_title = $page_title;
}
/**
* @return mixed
*/
public function get_menu_title() {
return $this->menu_title;
}
/**
* @param mixed $menu_title
*/
public function set_menu_title( $menu_title ) {
$this->menu_title = $menu_title;
}
/**
* @return mixed
*/
public function get_capability() {
return $this->capability;
}
/**
* @param mixed $capability
*/
public function set_capability( $capability ) {
$this->capability = $capability;
}
/**
* @return mixed
*/
public function get_menu_slug() {
return $this->menu_slug;
}
/**
* @param mixed $menu_slug
*/
public function set_menu_slug( $menu_slug ) {
$this->menu_slug = $menu_slug;
}
/**
* @return mixed
*/
public function get_function() {
return $this->function;
}
/**
* @param mixed $function
*/
public function set_function( $function ) {
$this->function = $function;
}
/**
* @return mixed
*/
public function get_order() {
return $this->order;
}
/**
* @param mixed $order
*/
public function set_order( $order ) {
$this->order = $order;
}
/**
* @return string
*/
private function serialize() {
$function = $this->get_function();
if ( is_callable( $function ) ) {
/**
* "Hash" is for the hash table. That's not an actual hash of the callable, but it should
* be good enough for the scope of this function
*/
$function = spl_object_hash( (object) $function );
}
return wp_json_encode(
array(
'capability' => $this->get_capability(),
'function' => $function,
'menu_slug' => $this->get_menu_slug(),
'menu_title' => $this->get_menu_title(),
'order' => $this->get_order(),
'page_title' => $this->get_page_title(),
'parent_slug' => $this->get_parent_slug(),
),
0,
1
);
}
}

View File

@@ -0,0 +1,265 @@
<?php
class WPML_Admin_Menu_Root {
private $capability;
private $function;
private $icon_url;
private $items = array();
private $menu_id;
private $menu_title;
private $page_title;
private $position;
/**
* WPML_Menu_Root constructor.
*
* @param array|null $args
*
* @throws \InvalidArgumentException
*/
public function __construct( array $args = null ) {
if ( $args ) {
$required_fields = array(
'capability',
'menu_id',
'menu_title',
'page_title',
);
foreach ( $required_fields as $required_field ) {
if ( ! array_key_exists( $required_field, $args ) ) {
throw new InvalidArgumentException( $required_field . ' is missing.' );
}
}
$fields = array(
'function',
'icon_url',
'position',
);
$fields = array_merge( $required_fields, $fields );
foreach ( $fields as $field ) {
if ( array_key_exists( $field, $args ) ) {
$this->{$field} = $args[ $field ];
}
}
}
}
public function build() {
do_action( 'wpml_admin_menu_configure', $this->get_menu_id() );
$this->adjust_items();
$root_slug = $this->get_menu_slug();
add_menu_page(
$this->get_page_title(),
$this->get_menu_title(),
$this->get_capability(),
$root_slug,
$this->get_function(),
$this->get_icon_url(),
$this->get_position()
);
do_action( 'wpml_admin_menu_root_configured', $this->get_menu_id(), $root_slug );
/** @var WPML_Admin_Menu_Item $menu_item */
foreach ( $this->items as $menu_item ) {
$menu_item = apply_filters( 'wpml_menu_item_before_build', $menu_item, $root_slug );
$menu_item->build( $root_slug );
}
}
private function adjust_items() {
if ( $this->items && count( $this->items ) > 1 ) {
$menu_items = $this->items;
$menu_items = array_unique( $menu_items );
$menu_items = array_map( array( $this, 'menu_order_fixer' ), $menu_items );
/**
* Error suppression is required because of https://bugs.php.net/bug.php?id=50688
* which makes PHPUnit (or every case where xDebug is involved) to cause a
* `PHP Warning: usort(): Array was modified by the user comparison function`
*/
@usort( $menu_items, array( $this, 'menu_order_sorter' ) );
$this->items = $menu_items;
}
}
/**
* @return string
*/
public function get_menu_slug() {
$top_menu = null;
if ( $this->items ) {
$this->adjust_items();
$top_menu = $this->items[0]->get_menu_slug();
}
return $top_menu;
}
/**
* @return string
*/
public function get_page_title() {
return $this->page_title;
}
/**
* @param string $page_title
*/
public function set_page_title( $page_title ) {
$this->page_title = $page_title;
}
/**
* @return string
*/
public function get_menu_id() {
return $this->menu_id;
}
/**
* @return string
*/
public function get_menu_title() {
return $this->menu_title;
}
/**
* @param string $menu_title
*/
public function set_menu_title( $menu_title ) {
$this->menu_title = $menu_title;
}
/**
* @return string
*/
public function get_capability() {
return $this->capability;
}
/**
* @param string $capability
*/
public function set_capability( $capability ) {
$this->capability = $capability;
}
/**
* @return null|callable
*/
public function get_function() {
return $this->function;
}
/**
* @param null|callable $function
*/
public function set_function( $function ) {
$this->function = $function;
}
/**
* @return string
*/
public function get_icon_url() {
return $this->icon_url;
}
/**
* @param string $icon_url
*/
public function set_icon_url( $icon_url ) {
$this->icon_url = $icon_url;
}
/**
* @return array
*/
public function get_items() {
return $this->items;
}
/**
* @return int
*/
public function get_position() {
return $this->position;
}
/**
* @param int $position
*/
public function set_position( $position ) {
$this->position = $position;
}
public function init_hooks() {
add_action( 'wpml_admin_menu_register_item', array( $this, 'register_menu_item' ) );
add_action( 'admin_menu', array( $this, 'build' ) );
add_action( 'set_wpml_root_menu_capability', [ $this, 'set_capability' ], 10, 1 );
}
/**
* @param WPML_Admin_Menu_Item $item
*
* @return WPML_Admin_Menu_Item
*/
public function menu_order_fixer( WPML_Admin_Menu_Item $item ) {
static $last_order = WPML_Main_Admin_Menu::MENU_ORDER_MAX;
if ( $item->get_order() === null ) {
$item->set_order( $last_order + 1 );
}
if ( $last_order < PHP_INT_MAX ) {
$last_order = $item->get_order();
}
return $item;
}
/**
* @param WPML_Admin_Menu_Item $a
* @param WPML_Admin_Menu_Item $b
*
* @return int
*/
public function menu_order_sorter( WPML_Admin_Menu_Item $a, WPML_Admin_Menu_Item $b ) {
$order_a = $a->get_order() === null ? 0 : $a->get_order();
$order_b = $b->get_order() === null ? 0 : $b->get_order();
if ( $order_a < $order_b ) {
return - 1;
}
if ( $order_a === $order_b ) {
return 0;
}
return 1;
}
/**
* @param WPML_Admin_Menu_Item|array $item
*
* @throws \InvalidArgumentException
*/
public function register_menu_item( $item ) {
if ( is_array( $item ) ) {
$item = new WPML_Admin_Menu_Item( $item );
}
$this->add_item( $item );
}
public function add_item( WPML_Admin_Menu_Item $item ) {
$this->items[] = $item;
return $this;
}
}

View File

@@ -0,0 +1,204 @@
<?php
/**
* @author OnTheGo Systems
*/
class WPML_Main_Admin_Menu {
const MENU_ORDER_LANGUAGES = 100;
const MENU_ORDER_THEMES_AND_PLUGINS_LOCALIZATION = 200;
const MENU_ORDER_TAXONOMY_TRANSLATION = 900;
const MENU_ORDER_SETTINGS = 9900;
const MENU_ORDER_MAX = 10000;
/** @var string */
private $languages_menu_slug;
/**
* @var WPML_Admin_Menu_Root
*/
private $root;
/**
* @var SitePress
*/
private $sitepress;
/**
* WPML_Menu_Main constructor.
*
* @param SitePress $sitepress
*
* @throws \InvalidArgumentException
*/
public function __construct( SitePress $sitepress ) {
$this->sitepress = $sitepress;
$this->languages_menu_slug = WPML_PLUGIN_FOLDER . '/menu/languages.php';
}
/**
* @throws \InvalidArgumentException
*/
public function configure() {
$this->root = new WPML_Admin_Menu_Root(
array(
'menu_id' => 'WPML',
'page_title' => __( 'WPML', 'sitepress' ),
'menu_title' => __( 'WPML', 'sitepress' ),
'capability' => 'wpml_manage_languages',
'menu_slug',
'function' => null,
'icon_url' => ICL_PLUGIN_URL . '/res/img/icon16.png',
)
);
$this->root->init_hooks();
if ( $this->sitepress->is_setup_complete() ) {
$this->languages();
do_action( 'icl_wpml_top_menu_added' );
if ( $this->is_wpml_setup_completed() ) {
$this->themes_and_plugins_localization();
if ( ! $this->is_tm_active() ) {
$this->translation_options();
}
}
$this->taxonomy_translation();
do_action( 'wpml_core_admin_menus_added' );
} else {
$this->wizard();
}
$this->support();
do_action( 'wpml_core_admin_menus_completed' );
}
/**
* @throws \InvalidArgumentException
*/
private function languages() {
$menu = new WPML_Admin_Menu_Item();
$menu->set_order( self::MENU_ORDER_LANGUAGES );
$menu->set_page_title( __( 'Languages', 'sitepress' ) );
$menu->set_menu_title( __( 'Languages', 'sitepress' ) );
$menu->set_capability( 'wpml_manage_languages' );
$menu->set_menu_slug( $this->languages_menu_slug );
$this->root->add_item( $menu );
}
private function wizard() {
$menu = new WPML_Admin_Menu_Item();
$menu->set_order( self::MENU_ORDER_LANGUAGES );
$menu->set_page_title( __( 'WPML Setup', 'sitepress' ) );
$menu->set_menu_title( __( 'Setup', 'sitepress' ) );
$menu->set_capability( 'wpml_manage_languages' );
$menu->set_menu_slug( WPML_PLUGIN_FOLDER . '/menu/setup.php' );
$this->root->add_item( $menu );
}
/**
* @return bool
*/
private function is_wpml_setup_completed() {
return $this->sitepress->get_setting( 'existing_content_language_verified' )
&& 2 <= count( $this->sitepress->get_active_languages() );
}
/**
* @throws \InvalidArgumentException
*/
private function themes_and_plugins_localization() {
$menu = new WPML_Admin_Menu_Item();
$menu->set_order( self::MENU_ORDER_THEMES_AND_PLUGINS_LOCALIZATION );
$menu->set_page_title( __( 'Theme and plugins localization', 'sitepress' ) );
$menu->set_menu_title( __( 'Theme and plugins localization', 'sitepress' ) );
$menu->set_capability( 'wpml_manage_theme_and_plugin_localization' );
$menu->set_menu_slug( WPML_PLUGIN_FOLDER . '/menu/theme-localization.php' );
$this->root->add_item( $menu );
}
/**
* @return bool
*/
private function is_tm_active() {
return $this->sitepress->get_wp_api()->defined( 'WPML_TM_VERSION' );
}
/**
* @throws \InvalidArgumentException
*/
private function translation_options() {
$menu = new WPML_Admin_Menu_Item();
$menu->set_order( self::MENU_ORDER_SETTINGS );
$menu->set_page_title( __( 'Settings', 'sitepress' ) );
$menu->set_menu_title( __( 'Settings', 'sitepress' ) );
$menu->set_capability( 'wpml_manage_translation_options' );
$menu->set_menu_slug( WPML_PLUGIN_FOLDER . '/menu/translation-options.php' );
$this->root->add_item( $menu );
}
/**
* @throws \InvalidArgumentException
*/
private function taxonomy_translation() {
$menu = new WPML_Admin_Menu_Item();
$menu->set_order( self::MENU_ORDER_TAXONOMY_TRANSLATION );
$menu->set_page_title( __( 'Taxonomy translation', 'sitepress' ) );
$menu->set_menu_title( __( 'Taxonomy translation', 'sitepress' ) );
$menu->set_capability( 'wpml_manage_taxonomy_translation' );
$menu->set_menu_slug( WPML_PLUGIN_FOLDER . '/menu/taxonomy-translation.php' );
$menu->set_function( array( $this->sitepress, 'taxonomy_translation_page' ) );
$this->root->add_item( $menu );
}
/**
* @throws \InvalidArgumentException
*/
private function support() {
$menu_slug = WPML_PLUGIN_FOLDER . '/menu/support.php';
$menu = new WPML_Admin_Menu_Item();
$menu->set_order( self::MENU_ORDER_MAX );
$menu->set_page_title( __( 'Support', 'sitepress' ) );
$menu->set_menu_title( __( 'Support', 'sitepress' ) );
$menu->set_capability( 'wpml_manage_support' );
$menu->set_menu_slug( $menu_slug );
$this->root->add_item( $menu );
$this->troubleshooting_menu( $menu_slug );
$this->debug_information_menu( $menu_slug );
}
/**
* @param string $parent_slug
*
* @throws \InvalidArgumentException
*/
private function troubleshooting_menu( $parent_slug ) {
$menu = new WPML_Admin_Menu_Item();
$menu->set_parent_slug( $parent_slug );
$menu->set_page_title( __( 'Troubleshooting', 'sitepress' ) );
$menu->set_menu_title( __( 'Troubleshooting', 'sitepress' ) );
$menu->set_capability( 'wpml_manage_troubleshooting' );
$menu->set_menu_slug( WPML_PLUGIN_FOLDER . '/menu/troubleshooting.php' );
$this->root->add_item( $menu );
}
/**
* @param string $parent_slug
*
* @throws \InvalidArgumentException
*/
private function debug_information_menu( $parent_slug ) {
$menu = new WPML_Admin_Menu_Item();
$menu->set_parent_slug( $parent_slug );
$menu->set_page_title( __( 'Debug information', 'sitepress' ) );
$menu->set_menu_title( __( 'Debug information', 'sitepress' ) );
$menu->set_capability( 'wpml_manage_troubleshooting' );
$menu->set_menu_slug( WPML_PLUGIN_FOLDER . '/menu/debug-information.php' );
$this->root->add_item( $menu );
}
}