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,24 @@
<?php
namespace WPML\TM\Menu\McSetup;
use WPML\WP\OptionManager;
class CfMetaBoxOption {
const GROUP = 'core';
const CF_META_BOX_OPTION_KEY = 'show_cf_meta_box';
/**
* @return boolean
*/
public static function get() {
return OptionManager::getOr( false, self::GROUP, self::CF_META_BOX_OPTION_KEY );
}
/**
* @param boolean $value
*/
public static function update( $value ) {
OptionManager::updateWithoutAutoLoad( self::GROUP, self::CF_META_BOX_OPTION_KEY, $value );
}
}

View File

@@ -0,0 +1,156 @@
<?php
/**
* @author OnTheGo Systems
*/
class WPML_TM_MCS_ATE_Strings {
const AMS_STATUS_ACTIVE_NOT_ALL_SUBSCRIBED = 'active-not-all-subscribed';
/**
* @var WPML_TM_ATE_Authentication
*/
private $authentication;
private $authentication_data;
/**
* @var WPML_TM_ATE_AMS_Endpoints
*/
private $endpoints;
private $statuses;
/**
* WPML_TM_MCS_ATE constructor.
*
* @param WPML_TM_ATE_Authentication $authentication
* @param WPML_TM_ATE_AMS_Endpoints $endpoints
*/
public function __construct( WPML_TM_ATE_Authentication $authentication, WPML_TM_ATE_AMS_Endpoints $endpoints ) {
$this->authentication = $authentication;
$this->endpoints = $endpoints;
$this->authentication_data = get_option( WPML_TM_ATE_Authentication::AMS_DATA_KEY, array() );
$this->statuses = array(
WPML_TM_ATE_Authentication::AMS_STATUS_NON_ACTIVE => array(
'type' => 'error',
'message' => array(
'status' => __( 'Advanced Translation Editor is not active yet', 'wpml-translation-management' ),
'text' => __(
'Request activation to receive an email with directions to activate the service.',
'wpml-translation-management'
),
),
'button' => __( 'Request activation', 'wpml-translation-management' ),
),
WPML_TM_ATE_Authentication::AMS_STATUS_ENABLED => array(
'type' => 'info',
'message' => array(
'status' => __( 'Advanced Translation Editor is being activated', 'wpml-translation-management' ),
'text' => '',
),
'button' => '',
),
WPML_TM_ATE_Authentication::AMS_STATUS_ACTIVE => array(
'type' => 'success',
'message' => array(
'status' => __( 'Advanced Translation Editor is enabled and active', 'wpml-translation-management' ),
'text' => '',
),
'button' => __( 'Advanced Translation Editor is active', 'wpml-translation-management' ),
),
self::AMS_STATUS_ACTIVE_NOT_ALL_SUBSCRIBED => array(
'type' => 'success',
'message' => array(
'status' => __( "WPML's Advanced Translation Editor is enabled, but not all your translators can use it.", 'wpml-translation-management' ),
'text' => '',
),
'button' => __( 'Advanced Translation Editor is active', 'wpml-translation-management' ),
),
);
}
/**
* @return string|WP_Error
* @throws \InvalidArgumentException
*/
public function get_auto_login() {
$shared = null;
if ( array_key_exists( 'shared', $this->authentication_data ) ) {
$shared = $this->authentication_data['shared'];
}
if ( $shared ) {
$url = $this->endpoints->get_ams_auto_login();
$user = wp_get_current_user();
$user_email = $user->user_email;
return $this->authentication->get_signed_url_with_parameters(
'GET',
$url,
array(
'translation_manager' => $user_email,
'return_url' => WPML_TM_Page::get_translators_url( array( 'refresh_subscriptions' => '1' ) ),
)
);
}
return '#';
}
public function get_status_HTML( $status, $all_users_have_subscription = true ) {
if ( $status === WPML_TM_ATE_Authentication::AMS_STATUS_ACTIVE && ! $all_users_have_subscription ) {
$status = self::AMS_STATUS_ACTIVE_NOT_ALL_SUBSCRIBED;
}
$message = $this->get_status_attribute( $status, 'message' );
return '<strong>' . $message['status'] . '</strong>' . $message['text'];
}
/**
* @return string
*/
public function get_status() {
$ate_status = WPML_TM_ATE_Authentication::AMS_STATUS_NON_ACTIVE;
if ( array_key_exists( 'status', $this->authentication_data ) ) {
$ate_status = $this->authentication_data['status'];
}
return $ate_status;
}
/**
* @param string $attribute
* @param null|mixed $default
*
* @return mixed
*/
public function get_current_status_attribute( $attribute, $default = null ) {
return $this->get_status_attribute( $this->get_status(), $attribute, $default );
}
/**
* @param string $status
* @param string $attribute
* @param null|mixed $default
*
* @return mixed
*/
public function get_status_attribute( $status, $attribute, $default = null ) {
$status_attributes = $this->statuses[ $status ];
if ( array_key_exists( $attribute, $status_attributes ) ) {
return $status_attributes[ $attribute ];
}
return $default;
}
public function get_statuses() {
return $this->statuses;
}
public function get_synchronize_button_text() {
return __( 'Synchronize translators and translation managers', 'wpml-translation-management' );
}
}

View File

@@ -0,0 +1,127 @@
<?php
use WPML\TM\ATE\ClonedSites\Lock;
/**
* @author OnTheGo Systems
*/
class WPML_TM_MCS_ATE extends WPML_Twig_Template_Loader {
/**
* @var WPML_TM_ATE_Authentication
*/
private $authentication;
private $authentication_data;
/**
* @var WPML_TM_ATE_AMS_Endpoints
*/
private $endpoints;
/**
* @var WPML_TM_MCS_ATE_Strings
*/
private $strings;
private $model = array();
/**
*
* /**
* WPML_TM_MCS_ATE constructor.
*
* @param WPML_TM_ATE_Authentication $authentication
* @param WPML_TM_ATE_AMS_Endpoints $endpoints
*
* @param WPML_TM_MCS_ATE_Strings $strings
*/
public function __construct(
WPML_TM_ATE_Authentication $authentication,
WPML_TM_ATE_AMS_Endpoints $endpoints,
WPML_TM_MCS_ATE_Strings $strings
) {
parent::__construct(
array(
$this->get_template_path(),
)
);
$this->authentication = $authentication;
$this->endpoints = $endpoints;
$this->strings = $strings;
$this->authentication_data = get_option( WPML_TM_ATE_Authentication::AMS_DATA_KEY, array() );
$wpml_support = esc_html__( 'WPML support', 'wpml-translation-management' );
$wpml_support_link = '<a target="_blank" rel="noopener" href="https://wpml.org/forums/forum/english-support/">' . $wpml_support . '</a>';
$this->model = [
'status_button_text' => $this->get_status_button_text(),
'synchronize_button_text' => $this->strings->get_synchronize_button_text(),
'is_ate_communication_locked' => Lock::isLocked(),
'strings' => [
'error_help' => sprintf( esc_html__( 'Please try again in a few minutes. If the problem persists, please contact %s.', 'wpml-translation-management' ), $wpml_support_link ),
],
];
}
/**
* @return string
*/
public function get_template_path() {
return WPML_TM_PATH . '/templates/ATE';
}
public function init_hooks() {
add_action( 'wpml_tm_mcs_' . ICL_TM_TMETHOD_ATE, array( $this, 'render' ) );
add_action( 'wpml_tm_mcs_troubleshooting', [ $this, 'renderTroubleshooting' ] );
}
/**
* @param array $args
*
* @return array
*/
public function get_model( array $args = array() ) {
if ( array_key_exists( 'wizard', $args ) ) {
$this->model['strings']['error_help'] = esc_html__( 'You can continue the Translation Management configuration later by going to WPML -> Settings -> Translation Editor.', 'wpml-translation-management' );
}
return $this->model;
}
public function render() {
echo $this->get_template()
->show( $this->get_model(), 'mcs-ate-controls.twig' );
}
public function renderTroubleshooting() {
echo '<div id="synchronize-ate-ams"></div>';
}
public function get_strings() {
return $this->strings;
}
private function has_translators() {
/** @var TranslationManagement $iclTranslationManagement */
global $iclTranslationManagement;
return $iclTranslationManagement->has_translators();
}
/**
* @return mixed
*/
private function get_status_button_text() {
return $this->strings->get_current_status_attribute( 'button' );
}
/**
* @return array
*/
public function get_script_data() {
return array(
'hasTranslators' => $this->has_translators(),
'currentStatus' => $this->strings->get_status(),
'statuses' => $this->strings->get_statuses(),
);
}
}

View File

@@ -0,0 +1,63 @@
<?php
class WPML_TM_MCS_Custom_Field_Settings_Menu_Factory {
/** @var WPML_Custom_Field_Setting_Factory $setting_factory */
private $setting_factory;
/** @var WPML_UI_Unlock_Button $unlock_button */
private $unlock_button;
/** @var WPML_Custom_Field_Setting_Query_Factory $query_factory */
private $query_factory;
/**
* @return WPML_TM_MCS_Post_Custom_Field_Settings_Menu
*/
public function create_post() {
return new WPML_TM_MCS_Post_Custom_Field_Settings_Menu(
$this->get_setting_factory(),
$this->get_unlock_button(),
$this->get_query_factory()
);
}
/**
* @return WPML_TM_MCS_Term_Custom_Field_Settings_Menu
*/
public function create_term() {
return new WPML_TM_MCS_Term_Custom_Field_Settings_Menu(
$this->get_setting_factory(),
$this->get_unlock_button(),
$this->get_query_factory()
);
}
private function get_setting_factory() {
global $iclTranslationManagement;
if ( null === $this->setting_factory ) {
$this->setting_factory = new WPML_Custom_Field_Setting_Factory( $iclTranslationManagement );
$this->setting_factory->show_system_fields = array_key_exists( 'show_system_fields', $_GET )
? (bool) $_GET['show_system_fields'] : false;
}
return $this->setting_factory;
}
private function get_unlock_button() {
if ( null === $this->unlock_button ) {
$this->unlock_button = new WPML_UI_Unlock_Button();
}
return $this->unlock_button;
}
private function get_query_factory() {
if ( null === $this->query_factory ) {
$this->query_factory = new WPML_Custom_Field_Setting_Query_Factory();
}
return $this->query_factory;
}
}

View File

@@ -0,0 +1,302 @@
<?php
use WPML\TM\Menu\McSetup\CfMetaBoxOption;
abstract class WPML_TM_MCS_Custom_Field_Settings_Menu {
/** @var WPML_Custom_Field_Setting_Factory $settings_factory */
protected $settings_factory;
/** @var WPML_UI_Unlock_Button $unlock_button_ui */
private $unlock_button_ui;
/** @var WPML_Custom_Field_Setting_Query_Factory $query_factory */
private $query_factory;
/** @var WPML_Custom_Field_Setting_Query $query */
private $query;
/** @var string[] Custom field keys */
private $custom_fields_keys;
/** @var int $total_keys */
private $total_keys;
/** @var array Custom field options */
private $custom_field_options;
/** @var int Initial setting of items per page */
const ITEMS_PER_PAGE = 20;
public function __construct(
WPML_Custom_Field_Setting_Factory $settings_factory,
WPML_UI_Unlock_Button $unlock_button_ui,
WPML_Custom_Field_Setting_Query_Factory $query_factory
) {
$this->settings_factory = $settings_factory;
$this->unlock_button_ui = $unlock_button_ui;
$this->query_factory = $query_factory;
$this->custom_field_options = array(
WPML_IGNORE_CUSTOM_FIELD => __( "Don't translate", 'wpml-translation-management' ),
WPML_COPY_CUSTOM_FIELD => __( 'Copy from original to translation', 'wpml-translation-management' ),
WPML_COPY_ONCE_CUSTOM_FIELD => __( 'Copy once', 'wpml-translation-management' ),
WPML_TRANSLATE_CUSTOM_FIELD => __( 'Translate', 'wpml-translation-management' ),
);
}
/**
* This will fetch the data from DB
* depending on the user inputs (pagination/search)
*
* @param array $args
*/
public function init_data( array $args = array() ) {
if ( null === $this->custom_fields_keys ) {
$args = array_merge(
array(
'hide_system_fields' => ! $this->settings_factory->show_system_fields,
'items_per_page' => self::ITEMS_PER_PAGE,
'page' => 1,
),
$args
);
$this->custom_fields_keys = $this->get_query()->get( $args );
$this->total_keys = $this->get_query()->get_total_rows();
if ( $this->custom_fields_keys ) {
natcasesort( $this->custom_fields_keys );
}
}
}
/**
* @return string
*/
public function render() {
ob_start();
?>
<div class="wpml-section wpml-section-<?php echo esc_attr( $this->kind_shorthand() ); ?>-translation"
id="ml-content-setup-sec-<?php echo esc_attr( $this->kind_shorthand() ); ?>">
<div class="wpml-section-header">
<h3><?php echo esc_html( $this->get_title() ); ?></h3>
<p>
<?php
// We need htmlspecialchars() here only for testing, as DOMDocument::loadHTML() cannot parse url with '&'.
$toggle_system_fields = array(
'url' => htmlspecialchars(
add_query_arg(
array(
'show_system_fields' => ! $this->settings_factory->show_system_fields,
),
admin_url( 'admin.php?page=' . WPML_TM_FOLDER . WPML_Translation_Management::PAGE_SLUG_SETTINGS ) . '#ml-content-setup-sec-' . $this->kind_shorthand()
)
),
'text' => $this->settings_factory->show_system_fields ?
__( 'Hide system fields', 'wpml-translation-management' ) :
__( 'Show system fields', 'wpml-translation-management' ),
);
?>
<a href="<?php echo esc_url( $toggle_system_fields['url'] ); ?>"><?php echo esc_html( $toggle_system_fields['text'] ); ?></a>
</p>
</div>
<div class="wpml-section-content wpml-section-content-wide">
<form
id="icl_<?php echo esc_attr( $this->kind_shorthand() ); ?>_translation"
data-type="<?php echo esc_attr( $this->kind_shorthand() ); ?>"
name="icl_<?php echo esc_attr( $this->kind_shorthand() ); ?>_translation"
class="wpml-custom-fields-settings" action="">
<?php wp_nonce_field( 'icl_' . $this->kind_shorthand() . '_translation_nonce', '_icl_nonce' ); ?>
<?php
if ( empty( $this->custom_fields_keys ) ) {
?>
<p class="no-data-found">
<?php echo esc_html( $this->get_no_data_message() ); ?>
</p>
<?php
} else {
if ( esc_attr( $this->kind_shorthand() ) === 'cf' ) {
?>
<label><input type="checkbox" <?php if ( CfMetaBoxOption::get() ) : ?> checked="checked"
<?php endif; ?>id="show_cf_meta_box" name="translate_media"
value="1"/>&nbsp;<?php esc_html_e( 'Show "Multilingual Content Setup" meta box on post edit screen.', 'sitepress' ); ?>
</label>
<?php
}
?>
<div class="wpml-flex-table wpml-translation-setup-table wpml-margin-top-sm">
<?php echo $this->render_heading(); ?>
<div class="wpml-flex-table-body">
<?php
$this->render_body();
?>
</div>
</div>
<?php
$this->render_pagination( self::ITEMS_PER_PAGE, 1 );
?>
<p class="buttons-wrap">
<span class="icl_ajx_response"
id="icl_ajx_response_<?php echo esc_attr( $this->kind_shorthand() ); ?>"></span>
<input type="submit" class="button-primary"
value="<?php echo esc_attr__( 'Save', 'wpml-translation-management' ); ?>"/>
</p>
<?php
}
?>
</form>
</div>
<!-- .wpml-section-content -->
</div> <!-- .wpml-section -->
<?php
return ob_get_clean();
}
/**
* @return string
*/
abstract protected function kind_shorthand();
/**
* @return string
*/
abstract protected function get_title();
abstract protected function get_meta_type();
/**
* @param string $key
*
* @return WPML_Custom_Field_Setting
*/
abstract protected function get_setting( $key );
private function render_radio( $cf_key, $html_disabled, $status, $ref_status ) {
ob_start();
?>
<input type="radio" name="<?php echo $this->get_radio_name( $cf_key ); ?>"
value="<?php echo esc_attr( $ref_status ); ?>"
title="<?php echo esc_attr( $ref_status ); ?>" <?php echo $html_disabled; ?>
<?php
if ( $status == $ref_status ) :
?>
checked<?php endif; ?> />
<?php
return ob_get_clean();
}
private function get_radio_name( $cf_key ) {
return 'cf[' . esc_attr( base64_encode( $cf_key ) ) . ']';
}
private function get_unlock_name( $cf_key ) {
return 'cf_unlocked[' . esc_attr( base64_encode( $cf_key ) ) . ']';
}
/**
* @return string header and footer of the setting table
*/
private function render_heading() {
ob_start();
?>
<div class="wpml-flex-table-header wpml-flex-table-sticky">
<?php $this->render_search(); ?>
<div class="wpml-flex-table-row">
<div class="wpml-flex-table-cell name">
<?php echo esc_html( $this->get_column_header( 'name' ) ); ?>
</div>
<div class="wpml-flex-table-cell text-center">
<?php echo esc_html__( "Don't translate", 'wpml-translation-management' ); ?>
</div>
<div class="wpml-flex-table-cell text-center">
<?php echo esc_html_x( 'Copy', 'Verb', 'wpml-translation-management' ); ?>
</div>
<div class="wpml-flex-table-cell text-center">
<?php echo esc_html__( 'Copy once', 'wpml-translation-management' ); ?>
</div>
<div class="wpml-flex-table-cell text-center">
<?php echo esc_html__( 'Translate', 'wpml-translation-management' ); ?>
</div>
</div>
</div>
<?php
return ob_get_clean();
}
/**
* Render search box for Custom Field Settings.
*
* @param string $search_string Search String.
*/
public function render_search( $search_string = '' ) {
$search = new WPML_TM_MCS_Search_Factory();
echo $search->create( $search_string )->render();
}
/**
* Render body of Custom Field Settings.
*/
public function render_body() {
foreach ( $this->custom_fields_keys as $cf_key ) {
$setting = $this->get_setting( $cf_key );
$status = $setting->status();
$html_disabled = $setting->is_read_only() && ! $setting->is_unlocked() ? 'disabled="disabled"' : '';
?>
<div class="wpml-flex-table-row">
<div class="wpml-flex-table-cell name">
<?php
$this->unlock_button_ui->render( $setting->is_read_only(), $setting->is_unlocked(), $this->get_radio_name( $cf_key ), $this->get_unlock_name( $cf_key ) );
echo esc_html( $cf_key );
?>
</div>
<?php
foreach ( $this->custom_field_options as $ref_status => $title ) {
?>
<div class="wpml-flex-table-cell text-center">
<?php
echo $this->render_radio( $cf_key, $html_disabled, $status, $ref_status );
?>
</div>
<?php
}
?>
</div>
<?php
}
}
/**
* Render pagination for Custom Field Settings.
*
* @param int $items_per_page Items per page to display.
* @param int $current_page Which page to display.
*/
public function render_pagination( $items_per_page, $current_page ) {
$pagination = new WPML_TM_MCS_Pagination_Render_Factory( $items_per_page );
echo $pagination->create( $this->total_keys, $current_page )->render();
}
abstract public function get_no_data_message();
abstract public function get_column_header( $id );
/**
* @return WPML_Custom_Field_Setting_Query
*/
private function get_query() {
if ( null === $this->query ) {
$this->query = $this->query_factory->create( $this->get_meta_type() );
}
return $this->query;
}
}

View File

@@ -0,0 +1,16 @@
<?php
/**
* Class WPML_TM_MCS_Pagination_Ajax_Factory
*/
class WPML_TM_MCS_Pagination_Ajax_Factory implements IWPML_AJAX_Action_Loader {
/**
* Create MCS Pagination.
*
* @return WPML_TM_MCS_Pagination_Ajax
*/
public function create() {
return new WPML_TM_MCS_Pagination_Ajax( new WPML_TM_MCS_Custom_Field_Settings_Menu_Factory() );
}
}

View File

@@ -0,0 +1,66 @@
<?php
use WPML\TM\Menu\McSetup\CfMetaBoxOption;
/**
* Class WPML_TM_MCS_Pagination_Ajax
*/
class WPML_TM_MCS_Pagination_Ajax {
/** @var WPML_TM_MCS_Custom_Field_Settings_Menu_Factory */
private $menu_factory;
public function __construct( WPML_TM_MCS_Custom_Field_Settings_Menu_Factory $menu_factory ) {
$this->menu_factory = $menu_factory;
}
/**
* Define Ajax hooks.
*/
public function add_hooks() {
add_action( 'wp_ajax_wpml_update_mcs_cf', array( $this, 'update_mcs_cf' ) );
}
/**
* Update custom fields form.
*/
public function update_mcs_cf() {
if ( isset( $_POST['nonce'] ) && wp_verify_nonce( $_POST['nonce'], 'icl_' . $_POST['type'] . '_translation_nonce' ) ) {
$args = array(
'items_per_page' => intval( $_POST['items_per_page'] ),
'page' => intval( $_POST['paged'] ),
'search' => isset( $_POST['search'] ) ? sanitize_text_field( $_POST['search'] ) : '',
'hide_system_fields' => ! isset( $_POST['show_system_fields'] ) || ! filter_var( $_POST['show_system_fields'], FILTER_VALIDATE_BOOLEAN ),
'show_cf_meta_box' => isset( $_POST['show_cf_meta_box'] ) && filter_var( $_POST['show_cf_meta_box'], FILTER_VALIDATE_BOOLEAN ),
);
$menu_item = null;
if ( 'cf' === $_POST['type'] ) {
$menu_item = $this->menu_factory->create_post();
CfMetaBoxOption::update( $args['show_cf_meta_box'] );
} elseif ( 'tcf' === $_POST['type'] ) {
$menu_item = $this->menu_factory->create_term();
}
if ( $menu_item ) {
$result = array();
ob_start();
$menu_item->init_data( $args );
$menu_item->render_body();
$result['body'] = ob_get_clean();
ob_start();
$menu_item->render_pagination( $args['items_per_page'], $args['page'] );
$result['pagination'] = ob_get_clean();
wp_send_json_success( $result );
}
}
wp_send_json_error(
array(
'message' => __( 'Invalid Request.', 'wpml-translation-management' ),
)
);
}
}

View File

@@ -0,0 +1,42 @@
<?php
/**
* Class WPML_TM_MCS_Pagination_Render_Factory
*/
class WPML_TM_MCS_Pagination_Render_Factory {
/**
* @var int Items per page
*/
private $items_per_page;
/**
* WPML_TM_MCS_Pagination_Render_Factory constructor.
*
* @param int $items_per_page
*/
public function __construct( $items_per_page ) {
$this->items_per_page = $items_per_page;
}
/**
* @param $items_per_page
* @param $total_items
* @param int $current_page
*
* @return WPML_TM_MCS_Pagination_Render
*/
public function create( $total_items, $current_page = 1 ) {
$pagination = new WPML_Admin_Pagination();
$pagination->set_items_per_page( $this->items_per_page );
$pagination->set_total_items( $total_items );
$pagination->set_current_page( $current_page );
$template = new WPML_Twig_Template_Loader(
array(
WPML_TM_PATH . '/templates/menus/mcsetup',
)
);
return new WPML_TM_MCS_Pagination_Render( $template->get_template(), $pagination );
}
}

View File

@@ -0,0 +1,169 @@
<?php
/**
* WPML_TM_MCS_Pagination_Render class file.
*
* @package wpml-translation-management
*/
/**
* Class WPML_TM_MCS_Pagination_Render
*/
class WPML_TM_MCS_Pagination_Render {
/**
* Twig template path.
*/
const TM_MCS_PAGINATION_TEMPLATE = 'tm-mcs-pagination.twig';
/**
* Twig template service.
*
* @var IWPML_Template_Service
*/
private $template;
/**
* Admin pagination instance.
*
* @var WPML_Admin_Pagination
*/
private $pagination;
/**
* Items per page.
*
* @var int Items per page
*/
private $items_per_page;
/**
* Total items.
*
* @var int Total items
*/
private $total_items;
/**
* Current page number.
*
* @var int Current page
*/
private $current_page;
/**
* Total number of pages.
*
* @var int Total pages
*/
private $total_pages;
/**
* WPML_TM_MCS_Pagination_Render constructor.
*
* @param IWPML_Template_Service $template Twig template service.
* @param WPML_Admin_Pagination $pagination Admin pagination object.
*/
public function __construct( IWPML_Template_Service $template, WPML_Admin_Pagination $pagination ) {
$this->template = $template;
$this->pagination = $pagination;
$this->items_per_page = $pagination->get_items_per_page();
$this->total_items = $pagination->get_total_items();
$this->current_page = $pagination->get_current_page();
$this->total_pages = $pagination->get_total_pages();
}
/**
* Get twig model.
*
* @return array
*/
private function get_model() {
$from = min( ( $this->current_page - 1 ) * $this->items_per_page + 1, $this->total_items );
$to = min( $this->current_page * $this->items_per_page, $this->total_items );
if ( - 1 === $this->current_page ) {
$from = min( 1, $this->total_items );
$to = $this->total_items;
}
$model = array(
'strings' => array(
'displaying' => __( 'Displaying', 'wpml-translation-management' ),
'of' => __( 'of', 'wpml-translation-management' ),
'display_all' => __( 'Display all results', 'wpml-translation-management' ),
'display_less' => __( 'Display 20 results per page', 'wpml-translation-management' ),
'nothing_found' => __( 'Nothing found', 'wpml-translation-management' ),
),
'pagination' => $this->pagination,
'from' => number_format_i18n( $from ),
'to' => number_format_i18n( $to ),
'current_page' => $this->current_page,
'total_items' => $this->total_items,
'total_items_i18n' => number_format_i18n( $this->total_items ),
'total_pages' => $this->total_pages,
'paginate_links' => $this->paginate_links(),
'select' => array( 10, 20, 50, 100 ),
'select_value' => $this->items_per_page,
);
return $model;
}
/**
* Render model via twig.
*
* @return mixed
*/
public function render() {
return $this->template->show( $this->get_model(), self::TM_MCS_PAGINATION_TEMPLATE );
}
/**
* Paginate links.
*
* @return array
*/
public function paginate_links() {
$page_links = array();
if ( - 1 === $this->current_page ) {
return $page_links;
}
if ( $this->total_pages < 2 ) {
return $page_links;
}
$end_size = 1;
$mid_size = 2;
$dots = false;
for ( $n = 1; $n <= $this->total_pages; $n ++ ) {
if ( $n === $this->current_page ) {
$page_links[] = array(
'class' => 'current',
'number' => number_format_i18n( $n ),
);
} else {
if (
$n <= $end_size ||
( $this->current_page && $n >= $this->current_page - $mid_size && $n <= $this->current_page + $mid_size ) ||
$n > $this->total_pages - $end_size
) {
$page_links[] = array(
'class' => '',
'number' => number_format_i18n( $n ),
);
$dots = true;
} elseif ( $dots ) {
$page_links[] = array(
'class' => 'dots',
'number' => '…',
);
$dots = false;
}
}
}
return $page_links;
}
}

View File

@@ -0,0 +1,54 @@
<?php
class WPML_TM_MCS_Post_Custom_Field_Settings_Menu extends WPML_TM_MCS_Custom_Field_Settings_Menu {
/**
* @return string
*/
protected function get_meta_type() {
return WPML_Custom_Field_Setting_Query_Factory::TYPE_POSTMETA;
}
/**
* @param string $key
*
* @return WPML_Post_Custom_Field_Setting
*/
protected function get_setting( $key ) {
return $this->settings_factory->post_meta_setting( $key );
}
/**
* @return string
*/
protected function get_title() {
return __( 'Custom Fields Translation', 'wpml-translation-management' );
}
/**
* @return string
*/
protected function kind_shorthand() {
return 'cf';
}
/**
* @return string
*/
public function get_no_data_message() {
return __( 'No custom fields found. It is possible that they will only show up here after you add more posts after installing a new plugin.', 'wpml-translation-management' );
}
/**
* @param string $id
*
* @return string
*/
public function get_column_header( $id ) {
$header = $id;
if('name' === $id) {
$header = __( 'Custom fields', 'wpml-translation-management' );
}
return $header;
}
}

View File

@@ -0,0 +1,23 @@
<?php
/**
* Class WPML_TM_MCS_Search_Factory
*/
class WPML_TM_MCS_Search_Factory {
/**
* Create MCS Search.
*
* @param string $search_string
*
* @return WPML_TM_MCS_Search_Render
*/
public function create( $search_string = '' ) {
$template = new WPML_Twig_Template_Loader(
array(
WPML_TM_PATH . '/templates/menus/mcsetup',
)
);
return new WPML_TM_MCS_Search_Render( $template->get_template(), $search_string );
}
}

View File

@@ -0,0 +1,58 @@
<?php
/**
* Class WPML_TM_MCS_Search_Render
*/
class WPML_TM_MCS_Search_Render {
/**
* Twig template path.
*/
const TM_MCS_SEARCH_TEMPLATE = 'tm-mcs-search.twig';
/**
* @var IWPML_Template_Service
*/
private $template;
/**
* @var string Search string
*/
private $search_string;
/**
* WPML_TM_MCS_Search_Render constructor.
*
* @param IWPML_Template_Service $template Twig template service.
* @param string $search_string Search string.
*/
public function __construct( IWPML_Template_Service $template, $search_string ) {
$this->template = $template;
$this->search_string = $search_string;
}
/**
* Get twig model.
*
* @return array
*/
public function get_model() {
$model = array(
'strings' => array(
'search_for' => __( 'Search for', 'wpml-translation-management' ),
),
'search_string' => $this->search_string,
);
return $model;
}
/**
* Render model via twig.
*
* @return mixed
*/
public function render() {
return $this->template->show( $this->get_model(), self::TM_MCS_SEARCH_TEMPLATE );
}
}

View File

@@ -0,0 +1,50 @@
<?php
abstract class WPML_TM_MCS_Section_UI {
private $id;
private $title;
public function __construct( $id, $title ) {
$this->id = $id;
$this->title = $title;
}
/**
* @return mixed
*/
public function get_id() {
return $this->id;
}
public function add_hooks() {
add_filter( 'wpml_mcsetup_navigation_links', array( $this, 'mcsetup_navigation_links' ) );
}
public function mcsetup_navigation_links( array $mcsetup_sections ) {
$mcsetup_sections[ $this->id ] = esc_html( $this->title );
return $mcsetup_sections;
}
public function render() {
$output = '';
$output .= '<div class="wpml-section" id="' . esc_attr( $this->id ) . '">';
$output .= '<div class="wpml-section-header">';
$output .= '<h3>' . esc_html( $this->title ) . '</h3>';
$output .= '</div>';
$output .= '<div class="wpml-section-content">';
$output .= $this->render_content();
$output .= '</div>';
$output .= '</div>';
return $output;
}
/**
* @return string
*/
abstract protected function render_content();
}

View File

@@ -0,0 +1,55 @@
<?php
class WPML_TM_MCS_Term_Custom_Field_Settings_Menu extends WPML_TM_MCS_Custom_Field_Settings_Menu {
/**
* @return string
*/
protected function get_meta_type() {
return WPML_Custom_Field_Setting_Query_Factory::TYPE_TERMMETA;
}
/**
* @param string $key
*
* @return WPML_Term_Custom_Field_Setting
*/
protected function get_setting( $key ) {
return $this->settings_factory->term_meta_setting( $key );
}
/**
* @return string
*/
protected function get_title() {
return __( 'Custom Term Meta Translation', 'wpml-translation-management' );
}
/**
* @return string
*/
protected function kind_shorthand() {
return 'tcf';
}
/**
* @return string
*/
public function get_no_data_message() {
return __( 'No term meta found. It is possible that they will only show up here after you add/create them.', 'wpml-translation-management' );
}
/**
* @param string $id
*
* @return string
*/
public function get_column_header( $id ) {
$header = $id;
if ( 'name' === $id ) {
$header = __( 'Term Meta', 'wpml-translation-management' );
}
return $header;
}
}

View File

@@ -0,0 +1,52 @@
<?php
class WPML_TM_Options_Ajax {
const NONCE_TRANSLATED_DOCUMENT = 'wpml-translated-document-options-nonce';
private $sitepress;
public function __construct( SitePress $sitepress ) {
$this->sitepress = $sitepress;
}
public function ajax_hooks() {
add_action( 'wp_ajax_wpml_translated_document_options', array( $this, 'wpml_translated_document_options' ) );
}
public function wpml_translated_document_options() {
if ( ! $this->is_valid_request() ) {
wp_send_json_error();
} else {
$settings = $this->sitepress->get_settings();
if ( array_key_exists( 'document_status', $_POST ) ) {
$settings['translated_document_status'] = filter_var( $_POST['document_status'], FILTER_SANITIZE_NUMBER_INT, FILTER_NULL_ON_FAILURE );
}
if ( array_key_exists( 'page_url', $_POST ) ) {
$settings['translated_document_page_url'] = filter_var( $_POST['page_url'], FILTER_SANITIZE_FULL_SPECIAL_CHARS, FILTER_NULL_ON_FAILURE );
}
if ( $settings ) {
$this->sitepress->save_settings( $settings );
}
wp_send_json_success();
}
}
private function is_valid_request() {
$valid_request = true;
if ( ! array_key_exists( 'nonce', $_POST ) ) {
$valid_request = false;
}
if ( $valid_request ) {
$nonce = $_POST['nonce'];
$nonce_is_valid = wp_verify_nonce( $nonce, self::NONCE_TRANSLATED_DOCUMENT );
if ( ! $nonce_is_valid ) {
$valid_request = false;
}
}
return $valid_request;
}
}

View File

@@ -0,0 +1,72 @@
<?php
class WPML_TM_Pickup_Mode_Ajax {
const NONCE_PICKUP_MODE = 'wpml_save_translation_pickup_mode';
/**
* @var SitePress
*/
private $sitepress;
/**
* @var WPML_Update_PickUp_Method
*/
private $update_pickup_mode;
/**
* @var WPML_Pro_Translation
*/
private $icl_pro_translation;
public function __construct( SitePress $sitepress, WPML_Pro_Translation $icl_pro_translation ) {
$this->sitepress = $sitepress;
$this->icl_pro_translation = $icl_pro_translation;
$this->update_pickup_mode = new WPML_Update_PickUp_Method( $this->sitepress );
}
public function ajax_hooks() {
add_action( 'wp_ajax_wpml_save_translation_pickup_mode', array( $this, 'wpml_save_translation_pickup_mode' ) );
}
public function wpml_save_translation_pickup_mode() {
try {
if ( ! $this->is_valid_request() ) {
throw new InvalidArgumentException('Request is not valid');
}
if ( ! array_key_exists('pickup_mode', $_POST ) ) {
throw new InvalidArgumentException();
}
$available_pickup_modes = array( 0, 1 );
$pickup_mode = filter_var( $_POST['pickup_mode'], FILTER_SANITIZE_NUMBER_INT, FILTER_NULL_ON_FAILURE );
if ( ! in_array( (int) $pickup_mode, $available_pickup_modes, true ) ) {
throw new InvalidArgumentException();
}
$data['icl_translation_pickup_method'] = $pickup_mode;
$this->update_pickup_mode->update_pickup_method( $data, $this->icl_pro_translation->get_current_project() );
wp_send_json_success();
} catch ( InvalidArgumentException $e ) {
wp_send_json_error();
}
}
private function is_valid_request() {
$valid_request = true;
if ( ! array_key_exists( 'nonce', $_POST ) ) {
$valid_request = false;
}
if ( $valid_request ) {
$nonce = $_POST['nonce'];
$nonce_is_valid = wp_verify_nonce( $nonce, self::NONCE_PICKUP_MODE );
if ( ! $nonce_is_valid ) {
$valid_request = false;
}
}
return $valid_request;
}
}

View File

@@ -0,0 +1,64 @@
<?php
class WPML_Translate_Link_Targets_UI extends WPML_TM_MCS_Section_UI {
const ID = 'ml-content-setup-sec-links-target';
/** @var WPDB $wpdb */
private $wpdb;
/** @var WPML_Pro_Translation $pro_translation */
private $pro_translation;
/** @var WPML_WP_API $wp_api */
private $wp_api;
/** @var SitePress $sitepress */
private $sitepress;
public function __construct( $title, $wpdb, $sitepress, $pro_translation ) {
parent::__construct( self::ID, $title );
$this->wpdb = $wpdb;
$this->pro_translation = $pro_translation;
$this->sitepress = $sitepress;
}
/**
* @return string
*/
protected function render_content() {
$output = '';
$main_message = __( 'Adjust links in posts so they point to the translated content', 'wpml-translation-management' );
$complete_message = __( 'All posts have been processed. %s links were changed to point to the translated content.', 'wpml-translation-management' );
$string_count = 0;
$posts = new WPML_Translate_Link_Targets_In_Posts_Global( new WPML_Translate_Link_Target_Global_State( $this->sitepress ), $this->wpdb, $this->pro_translation );
$post_count = $posts->get_number_to_be_fixed();
if ( defined( 'WPML_ST_VERSION' ) ) {
$strings = new WPML_Translate_Link_Targets_In_Strings_Global( new WPML_Translate_Link_Target_Global_State( $this->sitepress ), $this->wpdb, $this->wp_api, $this->pro_translation );
$string_count = $strings->get_number_to_be_fixed();
$main_message = __( 'Adjust links in posts and strings so they point to the translated content', 'wpml-translation-management' );
$complete_message = __( 'All posts and strings have been processed. %s links were changed to point to the translated content.', 'wpml-translation-management' );
}
$data_attributes = array(
'post-message' => esc_attr__( 'Processing posts... %1$s of %2$s done.', 'wpml-translation-management' ),
'post-count' => $post_count,
'string-message' => esc_attr__( 'Processing strings... %1$s of %2$s done.', 'wpml-translation-management' ),
'string-count' => $string_count,
'complete-message' => esc_attr( $complete_message ),
);
$output .= '<p>' . $main_message . '</p>';
$output .= '<button id="wpml-scan-link-targets" class="button-secondary"';
foreach ( $data_attributes as $key => $value ) {
$output .= ' data-' . $key . '="' . $value . '"';
}
$output .= '>' . esc_html__( 'Scan now and adjust links', 'wpml-translation-management' ) . '</button>';
$output .= '<span class="spinner"> </span>';
$output .= '<p class="results"> </p>';
$output .= wp_nonce_field( 'WPML_Ajax_Update_Link_Targets', 'wpml-translate-link-targets', true, false );
return $output;
}
}