first commit
This commit is contained in:
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_API_Hook_Copy_Post_To_Language
|
||||
*/
|
||||
class WPML_API_Hook_Copy_Post_To_Language implements IWPML_Action {
|
||||
|
||||
/** @var WPML_Post_Duplication $post_duplication */
|
||||
private $post_duplication;
|
||||
|
||||
public function __construct( WPML_Post_Duplication $post_duplication ) {
|
||||
$this->post_duplication = $post_duplication;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_filter( 'wpml_copy_post_to_language', array( $this, 'copy_post_to_language' ), 10, 3 );
|
||||
}
|
||||
|
||||
public function copy_post_to_language( $post_id, $target_language, $mark_as_duplicate ) {
|
||||
$duplicate_post_id = $this->post_duplication->make_duplicate( $post_id, $target_language );
|
||||
|
||||
if( ! $mark_as_duplicate ) {
|
||||
delete_post_meta( $duplicate_post_id, '_icl_lang_duplicate_of' );
|
||||
}
|
||||
|
||||
return $duplicate_post_id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_API_Hook_Links
|
||||
*
|
||||
* This class provides various links by hooks
|
||||
*/
|
||||
class WPML_API_Hook_Links implements IWPML_Action {
|
||||
|
||||
const POST_TRANSLATION_SETTINGS_PRIORITY = 10;
|
||||
const LINK_TO_TRANSLATION_PRIORITY = 9;
|
||||
|
||||
/** @var WPML_Post_Status_Display_Factory */
|
||||
private $post_status_display_factory;
|
||||
|
||||
public function __construct(
|
||||
WPML_Post_Status_Display_Factory $post_status_display_factory
|
||||
) {
|
||||
$this->post_status_display_factory = $post_status_display_factory;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_filter(
|
||||
'wpml_get_post_translation_settings_link',
|
||||
array(
|
||||
$this,
|
||||
'get_post_translation_settings_link',
|
||||
),
|
||||
self::POST_TRANSLATION_SETTINGS_PRIORITY,
|
||||
1
|
||||
);
|
||||
|
||||
add_filter(
|
||||
'wpml_get_link_to_edit_translation',
|
||||
array(
|
||||
$this,
|
||||
'get_link_to_edit_translation',
|
||||
),
|
||||
self::LINK_TO_TRANSLATION_PRIORITY,
|
||||
3
|
||||
);
|
||||
}
|
||||
|
||||
public function get_post_translation_settings_link( $link ) {
|
||||
return admin_url( 'admin.php?page=' . WPML_PLUGIN_FOLDER . '/menu/translation-options.php#icl_custom_posts_sync_options' );
|
||||
}
|
||||
|
||||
public function get_link_to_edit_translation( $link, $post_id, $lang ) {
|
||||
$status_display = $this->post_status_display_factory->create();
|
||||
$status_data = $status_display->get_status_data( $post_id, $lang );
|
||||
|
||||
$status_link = $status_data[1];
|
||||
$trid = $status_data[2];
|
||||
$css_class = $status_data[3];
|
||||
|
||||
return apply_filters( 'wpml_link_to_translation', $status_link, $post_id, $lang, $trid, $css_class );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<?php
|
||||
|
||||
class WPML_API_Hook_Permalink implements IWPML_Action {
|
||||
|
||||
/** @var WPML_URL_Converter $url_converter */
|
||||
private $url_converter;
|
||||
|
||||
/** @var IWPML_Resolve_Object_Url $absolute_resolver */
|
||||
private $absolute_resolver;
|
||||
|
||||
public function __construct( WPML_URL_Converter $url_converter, IWPML_Resolve_Object_Url $absolute_resolver ) {
|
||||
$this->url_converter = $url_converter;
|
||||
$this->absolute_resolver = $absolute_resolver;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_filter( 'wpml_permalink', array( $this, 'wpml_permalink_filter' ), 10, 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $url
|
||||
* @param null|string $lang
|
||||
* @param bool $absolute_url If `true`, WPML will try to resolve the object behind the URL
|
||||
* and try to find the matching translation's URL.
|
||||
* WARNING: This is a heavy process which could lead to performance hit.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function wpml_permalink_filter( $url, $lang = null, $absolute_url = false ) {
|
||||
if ( $absolute_url ) {
|
||||
$new_url = $this->absolute_resolver->resolve_object_url( $url, $lang );
|
||||
|
||||
if ( $new_url ) {
|
||||
$url = $new_url;
|
||||
}
|
||||
} else {
|
||||
$url = $this->url_converter->convert_url( $url, $lang );
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
class WPML_API_Hook_Sync_Custom_Fields implements IWPML_Action {
|
||||
|
||||
/** @var WPML_Sync_Custom_Fields $sync_custom_fields */
|
||||
private $sync_custom_fields;
|
||||
|
||||
public function __construct( WPML_Sync_Custom_Fields $sync_custom_fields ) {
|
||||
$this->sync_custom_fields = $sync_custom_fields;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'wpml_sync_custom_field', array( $this, 'sync_custom_field' ), 10, 2 );
|
||||
add_action( 'wpml_sync_all_custom_fields', array( $this, 'sync_all_custom_fields' ), 10, 1 );
|
||||
}
|
||||
|
||||
public function sync_custom_field( $post_id, $custom_field_name ) {
|
||||
$this->sync_custom_fields->sync_to_translations( $post_id, $custom_field_name );
|
||||
}
|
||||
|
||||
public function sync_all_custom_fields( $post_id ) {
|
||||
$this->sync_custom_fields->sync_all_custom_fields( $post_id );
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,60 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author OnTheGo Systems
|
||||
*/
|
||||
class WPML_API_Hook_Translation_Element implements IWPML_Action {
|
||||
private $flags_factory;
|
||||
private $sitepress;
|
||||
private $translation_element_factory;
|
||||
|
||||
/**
|
||||
* WPML_API_Hook_Post constructor.
|
||||
*
|
||||
* @param SitePress $sitepress
|
||||
* @param WPML_Translation_Element_Factory $translation_element_factory
|
||||
* @param WPML_Flags_Factory $flags_factory
|
||||
*/
|
||||
public function __construct(
|
||||
SitePress $sitepress,
|
||||
WPML_Translation_Element_Factory $translation_element_factory,
|
||||
WPML_Flags_Factory $flags_factory
|
||||
) {
|
||||
$this->sitepress = $sitepress;
|
||||
$this->translation_element_factory = $translation_element_factory;
|
||||
$this->flags_factory = $flags_factory;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
/**
|
||||
* Use this filter to obtain the language flag URL of a given post
|
||||
*
|
||||
* @param string $default
|
||||
* @param int $element_id
|
||||
* @param string $element_type any of `WPML_Translation_Element_Factory::ELEMENT_TYPE_POST`, `WPML_Translation_Element_Factory::ELEMENT_TYPE_TERM`, `WPML_Translation_Element_Factory::ELEMENT_TYPE_MENU`
|
||||
*/
|
||||
add_filter( 'wpml_post_language_flag_url', array( $this, 'get_post_language_flag_url' ), 10, 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $default
|
||||
* @param int $element_id
|
||||
* @param string $element_type any of `WPML_Translation_Element_Factory::ELEMENT_TYPE_POST`, `WPML_Translation_Element_Factory::ELEMENT_TYPE_TERM`, `WPML_Translation_Element_Factory::ELEMENT_TYPE_MENU`
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_post_language_flag_url(
|
||||
$default,
|
||||
$element_id,
|
||||
$element_type = WPML_Translation_Element_Factory::ELEMENT_TYPE_POST
|
||||
) {
|
||||
if ( ! $element_id ) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$wpml_post = $this->translation_element_factory->create( $element_id, $element_type );
|
||||
$flag = $this->flags_factory->create();
|
||||
|
||||
return $flag->get_flag_url( $wpml_post->get_language_code() );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,47 @@
|
||||
<?php
|
||||
|
||||
class WPML_API_Hook_Translation_Mode implements IWPML_Action {
|
||||
|
||||
const OPTION_KEY = 'custom_posts_sync_option';
|
||||
|
||||
/** Allowed modes */
|
||||
const DO_NOT_TRANSLATE = 'do_not_translate';
|
||||
const TRANSLATE = 'translate';
|
||||
const DISPLAY_AS_TRANSLATED = 'display_as_translated';
|
||||
|
||||
/** @var WPML_Settings_Helper $settings */
|
||||
private $settings;
|
||||
|
||||
public function __construct( WPML_Settings_Helper $settings ) {
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
if ( is_admin() ) {
|
||||
add_action( 'wpml_set_translation_mode_for_post_type', array( $this, 'set_mode_for_post_type' ), 10, 2 );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $post_type
|
||||
* @param string $translation_mode any of
|
||||
* `WPML_API_Hook_Translation_Mode::DO_NOT_TRANSLATE`,
|
||||
* `WPML_API_Hook_Translation_Mode::TRANSLATE`,
|
||||
* `WPML_API_Hook_Translation_Mode::DISPLAY_AS_TRANSLATED`
|
||||
*/
|
||||
public function set_mode_for_post_type( $post_type, $translation_mode ) {
|
||||
switch ( $translation_mode ) {
|
||||
case self::DO_NOT_TRANSLATE:
|
||||
$this->settings->set_post_type_not_translatable( $post_type );
|
||||
break;
|
||||
|
||||
case self::TRANSLATE:
|
||||
$this->settings->set_post_type_translatable( $post_type );
|
||||
break;
|
||||
|
||||
case self::DISPLAY_AS_TRANSLATED:
|
||||
$this->settings->set_post_type_display_as_translated( $post_type );
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
class WPML_API_Hooks_Factory implements IWPML_Backend_Action_Loader, IWPML_Frontend_Action_Loader {
|
||||
|
||||
public function create() {
|
||||
global $wpdb, $sitepress, $wpml_post_translations, $wpml_url_converter;
|
||||
|
||||
$hooks = array();
|
||||
|
||||
$hooks[] = new WPML_API_Hook_Sync_Custom_Fields(
|
||||
new WPML_Sync_Custom_Fields(
|
||||
new WPML_Translation_Element_Factory( $sitepress ),
|
||||
$sitepress->get_custom_fields_translation_settings( WPML_COPY_CUSTOM_FIELD )
|
||||
)
|
||||
);
|
||||
|
||||
$hooks[] = new WPML_API_Hook_Links( new WPML_Post_Status_Display_Factory( $sitepress ) );
|
||||
|
||||
$hooks[] = new WPML_API_Hook_Translation_Element(
|
||||
$sitepress,
|
||||
new WPML_Translation_Element_Factory( $sitepress ),
|
||||
new WPML_Flags_Factory( $wpdb )
|
||||
);
|
||||
|
||||
$hooks[] = new WPML_API_Hook_Translation_Mode( new WPML_Settings_Helper( $wpml_post_translations, $sitepress ) );
|
||||
|
||||
$hooks[] = new WPML_API_Hook_Copy_Post_To_Language( new WPML_Post_Duplication( $wpdb, $sitepress ) );
|
||||
|
||||
$url_resolver_factory = new WPML_Resolve_Object_Url_Helper_Factory();
|
||||
$absolute_resolver = $url_resolver_factory->create( WPML_Resolve_Object_Url_Helper_Factory::ABSOLUTE_URL_RESOLVER );
|
||||
$hooks[] = new WPML_API_Hook_Permalink( $wpml_url_converter, $absolute_resolver );
|
||||
|
||||
return $hooks;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,28 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TM_API_Hook_Links
|
||||
*
|
||||
* This class provides various links by hooks
|
||||
*/
|
||||
class WPML_TM_API_Hook_Links implements IWPML_Action {
|
||||
|
||||
public function add_hooks() {
|
||||
// TODO: Use WPML_API_Hook_Links::POST_TRANSLATION_SETTINGS_PRIORITY + 1 instead of the hardcoded 11.
|
||||
// It's done this way right now so there's no potential for an error if TM is updated before Core for
|
||||
// the minor 3.9.1 release
|
||||
add_filter(
|
||||
'wpml_get_post_translation_settings_link',
|
||||
array(
|
||||
$this,
|
||||
'get_post_translation_settings_link',
|
||||
),
|
||||
11,
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
public function get_post_translation_settings_link( $link ) {
|
||||
return admin_url( 'admin.php?page=' . WPML_TM_FOLDER . WPML_Translation_Management::PAGE_SLUG_SETTINGS . '&sm=mcsetup#icl_custom_posts_sync_options' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,12 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_API_Hooks_Factory implements IWPML_Backend_Action_Loader, IWPML_Frontend_Action_Loader {
|
||||
|
||||
public function create() {
|
||||
$hooks = array();
|
||||
|
||||
$hooks[] = new WPML_TM_API_Hook_Links();
|
||||
|
||||
return $hooks;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\Rest;
|
||||
|
||||
use \WP_REST_Request;
|
||||
|
||||
class Adaptor extends \WPML_REST_Base {
|
||||
|
||||
/** @var ITarget $target */
|
||||
private $target;
|
||||
|
||||
public function set_target( ITarget $target ) {
|
||||
$this->target = $target;
|
||||
$this->namespace = $target->get_namespace();
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
$routes = $this->target->get_routes();
|
||||
foreach ( $routes as $route ) {
|
||||
$this->register_route( $route['route'], $route['args'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WP_REST_Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_allowed_capabilities( WP_REST_Request $request ) {
|
||||
return $this->target->get_allowed_capabilities( $request );
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\Rest;
|
||||
|
||||
use IWPML_Action;
|
||||
|
||||
abstract class Base implements ITarget, IWPML_Action {
|
||||
|
||||
/** @var Adaptor */
|
||||
private $adaptor;
|
||||
|
||||
public function __construct( Adaptor $adaptor ) {
|
||||
$this->adaptor = $adaptor;
|
||||
$adaptor->set_target( $this );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
abstract public function get_namespace();
|
||||
|
||||
public function add_hooks() {
|
||||
$this->adaptor->add_hooks();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getStringType() {
|
||||
return [
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => 'WPML_REST_Arguments_Sanitation::string',
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function getIntType() {
|
||||
return [
|
||||
'type' => 'int',
|
||||
'validate_callback' => 'WPML_REST_Arguments_Validation::integer',
|
||||
'sanitize_callback' => 'WPML_REST_Arguments_Sanitation::integer',
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\TM\REST;
|
||||
|
||||
abstract class Base extends \WPML\Rest\Base {
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_namespace() {
|
||||
return 'wpml/tm/v1';
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\REST\XMLConfig\Custom;
|
||||
|
||||
use WP_REST_Request;
|
||||
|
||||
class Actions extends \WPML_REST_Base {
|
||||
/** @var array<string> */
|
||||
private $capabilities = [ 'manage_options' ];
|
||||
|
||||
/**
|
||||
* @var \WPML_Custom_XML
|
||||
*/
|
||||
private $custom_xml;
|
||||
/**
|
||||
* @var \WPML_XML_Config_Validate
|
||||
*/
|
||||
private $validate;
|
||||
|
||||
public function __construct( \WPML_Custom_XML $custom_xml, \WPML_XML_Config_Validate $validate ) {
|
||||
parent::__construct();
|
||||
$this->custom_xml = $custom_xml;
|
||||
$this->validate = $validate;
|
||||
}
|
||||
|
||||
|
||||
function add_hooks() {
|
||||
$this->register_routes();
|
||||
}
|
||||
|
||||
function register_routes() {
|
||||
parent::register_route(
|
||||
'/custom-xml-config',
|
||||
[
|
||||
'methods' => 'GET',
|
||||
'callback' => [ $this, 'read_content' ],
|
||||
]
|
||||
);
|
||||
parent::register_route(
|
||||
'/custom-xml-config',
|
||||
[
|
||||
'methods' => 'POST',
|
||||
'callback' => [ $this, 'update_content' ],
|
||||
]
|
||||
);
|
||||
parent::register_route(
|
||||
'/custom-xml-config/validate',
|
||||
[
|
||||
'methods' => 'POST',
|
||||
'callback' => [ $this, 'validate_content' ],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* REST
|
||||
*
|
||||
* @param \WP_REST_Request $request
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function update_content( WP_REST_Request $request ) {
|
||||
$content = $request->get_param( 'content' );
|
||||
|
||||
$this->custom_xml->set( $content, false );
|
||||
\WPML_Config::load_config_run();
|
||||
|
||||
return $this->custom_xml->get();
|
||||
}
|
||||
|
||||
/**
|
||||
* REST
|
||||
*
|
||||
* @param \WP_REST_Request $request
|
||||
*
|
||||
* @return \LibXMLError[]
|
||||
*/
|
||||
public function validate_content( WP_REST_Request $request ) {
|
||||
$content = $request->get_param( 'content' );
|
||||
|
||||
if ( ! $this->validate->from_string( $content ) ) {
|
||||
return $this->validate->get_errors();
|
||||
}
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
/**
|
||||
* REST
|
||||
*/
|
||||
public function read_content() {
|
||||
return $this->custom_xml->get();
|
||||
}
|
||||
|
||||
function get_allowed_capabilities( WP_REST_Request $request ) {
|
||||
return $this->capabilities;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\REST\XMLConfig\Custom;
|
||||
|
||||
|
||||
class Factory extends \WPML_REST_Factory_Loader {
|
||||
public function create() {
|
||||
return new Actions( new \WPML_Custom_XML(), new \WPML_XML_Config_Validate( \WPML_Config::PATH_TO_XSD ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\TM\REST;
|
||||
|
||||
use IWPML_Deferred_Action_Loader;
|
||||
use IWPML_REST_Action_Loader;
|
||||
use WPML\TM\ATE\REST\Retry;
|
||||
use WPML\TM\ATE\REST\Sync;
|
||||
use \WPML\TM\ATE\REST\FixJob;
|
||||
use WPML\TM\ATE\REST\Download;
|
||||
use WPML\TM\ATE\REST\PublicReceive;
|
||||
use function WPML\Container\make;
|
||||
|
||||
class FactoryLoader implements IWPML_REST_Action_Loader, IWPML_Deferred_Action_Loader {
|
||||
|
||||
const REST_API_INIT_ACTION = 'rest_api_init';
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_load_action() {
|
||||
return self::REST_API_INIT_ACTION;
|
||||
}
|
||||
|
||||
public function create() {
|
||||
return [
|
||||
Sync::class => make( Sync::class ),
|
||||
Download::class => make( Download::class ),
|
||||
Retry::class => make( Retry::class ),
|
||||
PublicReceive::class => make( PublicReceive::class ),
|
||||
FixJob::class => make( FixJob::class ),
|
||||
];
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,11 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\Rest;
|
||||
|
||||
interface ITarget {
|
||||
|
||||
function get_routes();
|
||||
function get_allowed_capabilities( \WP_REST_Request $request );
|
||||
function get_namespace();
|
||||
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
<?php
|
||||
namespace WPML\TM\ATE\Factories;
|
||||
|
||||
class Proxy extends \WPML_REST_Factory_Loader {
|
||||
/**
|
||||
* @return \WPML\TM\ATE\Proxy
|
||||
*/
|
||||
public function create() {
|
||||
$endpoints = new \WPML_TM_ATE_AMS_Endpoints();
|
||||
|
||||
return new \WPML\TM\ATE\Proxy( $endpoints );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,189 @@
|
||||
<?php
|
||||
|
||||
namespace WPML\TM\ATE;
|
||||
|
||||
class Proxy extends \WPML_REST_Base {
|
||||
/**
|
||||
* @var \WPML_TM_ATE_AMS_Endpoints
|
||||
*/
|
||||
private $endpoints;
|
||||
|
||||
public function __construct( \WPML_TM_ATE_AMS_Endpoints $endpoints ) {
|
||||
parent::__construct( 'wpml/ate/v1' );
|
||||
|
||||
$this->endpoints = $endpoints;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
$this->register_routes();
|
||||
}
|
||||
|
||||
public function register_routes() {
|
||||
parent::register_route(
|
||||
'/ate/proxy',
|
||||
array(
|
||||
'methods' => \WP_REST_Server::ALLMETHODS,
|
||||
'callback' => [ $this, 'proxy' ],
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WP_REST_Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_args( \WP_REST_Request $request ) {
|
||||
$request_params = $this->get_request_params( $request );
|
||||
|
||||
$url = $request_params['url'];
|
||||
$headers = $request_params['headers'];
|
||||
$query = $request_params['query'];
|
||||
$content_type = $request_params['content_type'];
|
||||
|
||||
if ( $content_type ) {
|
||||
if ( ! $headers ) {
|
||||
$headers = [];
|
||||
}
|
||||
$headers[] = 'Content-Type: ' . $content_type;
|
||||
}
|
||||
|
||||
$args = [
|
||||
'method' => $request_params['method'],
|
||||
'headers' => $headers,
|
||||
];
|
||||
|
||||
$body = $request_params['body'];
|
||||
if ( $body ) {
|
||||
$args['body'] = $body;
|
||||
}
|
||||
|
||||
return [ $url, $query, $args, $content_type ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WP_REST_Request $request
|
||||
*
|
||||
* @return true|\WP_Error
|
||||
*/
|
||||
private function validate_request( \WP_REST_Request $request ) {
|
||||
if ( ! $this->get_request_params( $request ) ) {
|
||||
return new \WP_Error( 'endpoint_without_parameters', 'Endpoint called with no parameters.', [ 'status' => 400 ] );
|
||||
}
|
||||
|
||||
list( $url, , $args ) = $this->get_args( $request );
|
||||
|
||||
$has_all_required_parameters = $url && $args['method'] && $args['headers'];
|
||||
if ( ! $has_all_required_parameters ) {
|
||||
return new \WP_Error( 'missing_required_parameters', 'Required parameters missing.', [ 'status' => 400 ] );
|
||||
}
|
||||
|
||||
if ( \strtolower( $request->get_method() ) !== \strtolower( $args['method'] ) ) {
|
||||
return new \WP_Error( 'invalid_method', 'Invalid method.', [ 'status' => 400 ] );
|
||||
}
|
||||
|
||||
$ateBaseUrl = $this->endpoints->get_base_url( \WPML_TM_ATE_AMS_Endpoints::SERVICE_ATE );
|
||||
$amsBaseUrl = $this->endpoints->get_base_url( \WPML_TM_ATE_AMS_Endpoints::SERVICE_AMS );
|
||||
|
||||
if ( \strpos( \strtolower( $url ), $ateBaseUrl ) !== 0 && \strpos( \strtolower( $url ), $amsBaseUrl ) !== 0 ) {
|
||||
return new \WP_Error( 'invalid_url', 'Invalid URL.', [ 'status' => 400 ] );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WP_REST_Request $request
|
||||
*/
|
||||
public function proxy( \WP_REST_Request $request ) {
|
||||
list( $url, $params, $args, $content_type ) = $this->get_args( $request );
|
||||
|
||||
$status_code = 200;
|
||||
$status_message = 'OK';
|
||||
|
||||
$validation = $this->validate_request( $request );
|
||||
if ( \is_wp_error( $validation ) ) {
|
||||
$status_code = $validation->get_error_data()['status'];
|
||||
$status_message = $validation->get_error_message();
|
||||
$response_body = '';
|
||||
} else {
|
||||
|
||||
if ( \is_array( $params ) ) {
|
||||
$params = \http_build_query( $params );
|
||||
}
|
||||
|
||||
$endpoint = \http_build_url( $url, [ 'query' => $params ] );
|
||||
|
||||
$response = \wp_remote_request( $endpoint, $args );
|
||||
|
||||
$response_body = \wp_remote_retrieve_body( $response );
|
||||
}
|
||||
|
||||
$protocol = ( isset( $_SERVER['SERVER_PROTOCOL'] ) ? $_SERVER['SERVER_PROTOCOL'] : 'HTTP/1.0' );
|
||||
if ( 200 === $status_code ) {
|
||||
header( "{$protocol} {$status_code} {$status_message}" );
|
||||
} else {
|
||||
header( "Status: ${status_code} ${status_message}" );
|
||||
}
|
||||
header( "Content-Type: {$content_type}" );
|
||||
|
||||
// phpcs:disable WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
echo $response_body;
|
||||
// phpcs:enable WordPress.Security.EscapeOutput.OutputNotEscaped
|
||||
|
||||
$this->break_the_default_response_flow();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WP_REST_Request $request
|
||||
*
|
||||
* @return string[]|string
|
||||
*/
|
||||
public function get_allowed_capabilities( \WP_REST_Request $request ) {
|
||||
return [ \WPML_Manage_Translations_Role::CAPABILITY, 'manage_options' ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WP_REST_Request $request
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_request_params( \WP_REST_Request $request ) {
|
||||
$params = [
|
||||
'url' => null,
|
||||
'method' => null,
|
||||
'query' => null,
|
||||
'headers' => null,
|
||||
'body' => null,
|
||||
'content_type' => 'application/json',
|
||||
];
|
||||
|
||||
if ( $request->get_params() ) {
|
||||
$params = \array_merge( $params, $request->get_params() );
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
private function break_the_default_response_flow() {
|
||||
$shortcut = function () {
|
||||
return function () {
|
||||
die();
|
||||
};
|
||||
|
||||
};
|
||||
$die_handlers = [
|
||||
'wp_die_ajax_handler',
|
||||
'wp_die_json_handler',
|
||||
'wp_die_jsonp_handler',
|
||||
'wp_die_xmlrpc_handler',
|
||||
'wp_die_xml_handler',
|
||||
'wp_die_handler',
|
||||
];
|
||||
foreach ( $die_handlers as $die_handler ) {
|
||||
\add_filter( $die_handler, $shortcut, 10 );
|
||||
}
|
||||
|
||||
\wp_die();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,77 @@
|
||||
<?php
|
||||
|
||||
use WPML\API\Sanitize;
|
||||
|
||||
/**
|
||||
* @author OnTheGo Systems
|
||||
*
|
||||
* The following method can be used as REST arguments sanitation callback
|
||||
*/
|
||||
class WPML_REST_Arguments_Sanitation {
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static function boolean( $value ) {
|
||||
/**
|
||||
* `FILTER_VALIDATE_BOOLEAN` returns `NULL` if not valid, but in all other cases, it sanitizes the value
|
||||
*/
|
||||
return filter_var( $value, FILTER_VALIDATE_BOOLEAN );
|
||||
}
|
||||
|
||||
/**
|
||||
*@param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static function integer( $value ) {
|
||||
return (int) self::float( $value );
|
||||
}
|
||||
|
||||
/**
|
||||
*@param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static function float( $value ) {
|
||||
return (float) filter_var( $value, FILTER_SANITIZE_NUMBER_FLOAT, FILTER_FLAG_ALLOW_FRACTION );
|
||||
}
|
||||
|
||||
/**
|
||||
*@param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static function string( $value ) {
|
||||
return Sanitize::string( $value );
|
||||
}
|
||||
|
||||
/**
|
||||
*@param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static function url( $value ) {
|
||||
return filter_var( $value, FILTER_SANITIZE_URL );
|
||||
}
|
||||
|
||||
/**
|
||||
*@param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static function email( $value ) {
|
||||
return filter_var( $value, FILTER_SANITIZE_EMAIL );
|
||||
}
|
||||
|
||||
/**
|
||||
*@param mixed $value
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
static function array_of_integers( $value ) {
|
||||
return array_map( 'intval', $value );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,78 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author OnTheGo Systems
|
||||
*
|
||||
* The following method can be used as REST arguments validation callback
|
||||
*/
|
||||
class WPML_REST_Arguments_Validation {
|
||||
|
||||
/**
|
||||
*@param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static function boolean( $value ) {
|
||||
return null !== filter_var( $value, FILTER_VALIDATE_BOOLEAN, FILTER_NULL_ON_FAILURE );
|
||||
}
|
||||
|
||||
/**
|
||||
*@param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static function integer( $value ) {
|
||||
return false !== filter_var( $value, FILTER_VALIDATE_INT );
|
||||
}
|
||||
|
||||
/**
|
||||
*@param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static function float( $value ) {
|
||||
return false !== filter_var( $value, FILTER_VALIDATE_FLOAT );
|
||||
}
|
||||
|
||||
/**
|
||||
*@param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static function url( $value ) {
|
||||
return false !== filter_var( $value, FILTER_VALIDATE_URL );
|
||||
}
|
||||
|
||||
/**
|
||||
*@param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static function email( $value ) {
|
||||
return false !== filter_var( $value, FILTER_VALIDATE_EMAIL );
|
||||
}
|
||||
|
||||
/**
|
||||
*@param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static function is_array( $value ) {
|
||||
return is_array( $value );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param mixed $value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
static function date( $value ) {
|
||||
try {
|
||||
$d = new DateTime( $value );
|
||||
|
||||
return $d && $d->format( 'Y-m-d' ) == $value;
|
||||
} catch ( Exception $e ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,104 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_REST_Base
|
||||
*
|
||||
* @author OnTheGo Systems
|
||||
*/
|
||||
abstract class WPML_REST_Base {
|
||||
const CAPABILITY_EXTERNAL = 'external';
|
||||
|
||||
const REST_NAMESPACE = 'wpml/v1';
|
||||
/**
|
||||
* @var null
|
||||
*/
|
||||
protected $namespace;
|
||||
|
||||
/**
|
||||
* WPML_REST_Base constructor.
|
||||
*
|
||||
* @param null $namespace Defaults to `\WPML_REST_Base::REST_NAMESPACE`.
|
||||
*/
|
||||
public function __construct( $namespace = null ) {
|
||||
if ( ! $namespace ) {
|
||||
$namespace = self::REST_NAMESPACE;
|
||||
}
|
||||
$this->namespace = $namespace;
|
||||
}
|
||||
|
||||
abstract public function add_hooks();
|
||||
|
||||
public function validate_permission( WP_REST_Request $request ) {
|
||||
$user_can = $this->user_has_matching_capabilities( $request );
|
||||
|
||||
if ( ! $user_can ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$nonce = $this->get_nonce( $request );
|
||||
|
||||
return $user_can && wp_verify_nonce( $nonce, 'wp_rest' );
|
||||
}
|
||||
|
||||
abstract public function get_allowed_capabilities( WP_REST_Request $request );
|
||||
|
||||
/**
|
||||
* @param string $route
|
||||
* @param array $args
|
||||
*/
|
||||
protected function register_route( $route, array $args ) {
|
||||
$args = $this->ensure_permission( $args );
|
||||
|
||||
register_rest_route( $this->namespace, $route, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function ensure_permission( array $args ) {
|
||||
if ( ! array_key_exists( 'permission_callback', $args ) || ! $args['permission_callback'] ) {
|
||||
$args['permission_callback'] = array( $this, 'validate_permission' );
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WP_REST_Request $request
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function user_has_matching_capabilities( WP_REST_Request $request ) {
|
||||
$capabilities = $this->get_allowed_capabilities( $request );
|
||||
|
||||
$user_can = false;
|
||||
if ( self::CAPABILITY_EXTERNAL === $capabilities ) {
|
||||
$user_can = true;
|
||||
} elseif ( is_string( $capabilities ) ) {
|
||||
$user_can = current_user_can( $capabilities );
|
||||
} elseif ( is_array( $capabilities ) ) {
|
||||
foreach ( $capabilities as $capability ) {
|
||||
$user_can = $user_can || current_user_can( $capability );
|
||||
}
|
||||
}
|
||||
|
||||
return $user_can;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WP_REST_Request $request
|
||||
*
|
||||
* @return mixed|string|null
|
||||
*/
|
||||
private function get_nonce( WP_REST_Request $request ) {
|
||||
$nonce = $request->get_header( 'x_wp_nonce' );
|
||||
if ( ! $nonce ) {
|
||||
$nonce = $request->get_param( '_wpnonce' );
|
||||
}
|
||||
|
||||
return $nonce;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author OnTheGo Systems
|
||||
*/
|
||||
class WPML_REST_Extend_Args_Factory implements IWPML_REST_Action_Loader {
|
||||
/**
|
||||
* @return IWPML_Action|IWPML_Action[]|null
|
||||
*/
|
||||
public function create() {
|
||||
global $sitepress;
|
||||
|
||||
return new WPML_REST_Extend_Args( $sitepress );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,96 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author OnTheGo Systems
|
||||
*/
|
||||
class WPML_REST_Extend_Args implements IWPML_Action {
|
||||
|
||||
const REST_LANGUAGE_ARGUMENT = 'wpml_language';
|
||||
|
||||
/** @var \SitePress $sitepress */
|
||||
private $sitepress;
|
||||
|
||||
/** @var string $current_language_backup */
|
||||
private $current_language_backup;
|
||||
|
||||
public function __construct( SitePress $sitepress ) {
|
||||
$this->sitepress = $sitepress;
|
||||
}
|
||||
|
||||
function add_hooks() {
|
||||
add_filter( 'rest_endpoints', array( $this, 'rest_endpoints' ) );
|
||||
add_filter( 'rest_request_before_callbacks', array( $this, 'rest_request_before_callbacks' ), 10, 3 );
|
||||
add_filter( 'rest_request_after_callbacks', array( $this, 'rest_request_after_callbacks' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the `wpml_language` argument (optional) to all REST calls with arguments.
|
||||
*
|
||||
* @param array $endpoints
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function rest_endpoints( array $endpoints ) {
|
||||
$valid_language_codes = $this->get_active_language_codes();
|
||||
|
||||
foreach ( $endpoints as $route => &$endpoint ) {
|
||||
foreach ( $endpoint as $key => &$data ) {
|
||||
if ( is_numeric( $key ) ) {
|
||||
$data['args'][ self::REST_LANGUAGE_ARGUMENT ] = array(
|
||||
'type' => 'string',
|
||||
'description' => "WPML's language code",
|
||||
'required' => false,
|
||||
'enum' => $valid_language_codes,
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $endpoints;
|
||||
}
|
||||
|
||||
/**
|
||||
* If `wpml_language` is provided, backups the current language, then switch to the provided one.
|
||||
*
|
||||
* @param \WP_REST_Response|array|mixed $response
|
||||
* @param \WP_REST_Server|array|mixed $rest_server
|
||||
* @param \WP_REST_Request $request
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function rest_request_before_callbacks( $response, $rest_server, $request ) {
|
||||
$this->current_language_backup = null;
|
||||
$current_language = $this->sitepress->get_current_language();
|
||||
$rest_language = $request->get_param( self::REST_LANGUAGE_ARGUMENT );
|
||||
|
||||
if ( $rest_language && $rest_language !== $current_language ) {
|
||||
$this->current_language_backup = $current_language;
|
||||
$this->sitepress->switch_lang( $rest_language );
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Restore the backup language, if set.
|
||||
*
|
||||
* @param \WP_REST_Response|array|mixed $response
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function rest_request_after_callbacks( $response ) {
|
||||
if ( $this->current_language_backup ) {
|
||||
$this->sitepress->switch_lang( $this->current_language_backup );
|
||||
}
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_active_language_codes() {
|
||||
return array_keys( $this->sitepress->get_active_languages() );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,15 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author OnTheGo Systems
|
||||
*/
|
||||
abstract class WPML_REST_Factory_Loader implements IWPML_REST_Action_Loader, IWPML_Deferred_Action_Loader {
|
||||
const REST_API_INIT_ACTION = 'rest_api_init';
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_load_action() {
|
||||
return self::REST_API_INIT_ACTION;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,50 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author OnTheGo Systems
|
||||
*/
|
||||
class WPML_Rest {
|
||||
private $http;
|
||||
|
||||
/**
|
||||
* WPML_Rest constructor.
|
||||
*
|
||||
* @param WP_Http $http
|
||||
*/
|
||||
public function __construct( WP_Http $http ) {
|
||||
$this->http = $http;
|
||||
}
|
||||
|
||||
public function is_available() {
|
||||
return function_exists( 'rest_get_server' );
|
||||
}
|
||||
|
||||
public function is_rest_request() {
|
||||
return defined( 'REST_REQUEST' ) && REST_REQUEST;
|
||||
}
|
||||
|
||||
public function has_registered_routes() {
|
||||
return (bool) rest_get_server()->get_routes();
|
||||
}
|
||||
|
||||
public function has_discovered_routes() {
|
||||
return (bool) $this->get_discovered_routes();
|
||||
}
|
||||
|
||||
private function get_discovered_routes() {
|
||||
$url = $this->get_discovery_url();
|
||||
$response = $this->http->get( $url );
|
||||
$body = json_decode( $response['body'], true );
|
||||
|
||||
return array_key_exists( 'routes', $body ) ? $body['routes'] : array();
|
||||
}
|
||||
|
||||
public function get_discovery_url() {
|
||||
$url_prefix = 'wp-json';
|
||||
if ( function_exists( 'rest_get_url_prefix' ) ) {
|
||||
$url_prefix = rest_get_url_prefix();
|
||||
}
|
||||
|
||||
return untrailingslashit( trailingslashit( get_site_url() ) . $url_prefix );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_REST_Apply_TP_Translation_Factory extends WPML_REST_Factory_Loader {
|
||||
/**
|
||||
* @return WPML_TM_REST_Apply_TP_Translation
|
||||
*/
|
||||
public function create() {
|
||||
global $wpdb;
|
||||
|
||||
return new WPML_TM_REST_Apply_TP_Translation(
|
||||
new WPML_TP_Apply_Translations(
|
||||
wpml_tm_get_jobs_repository(),
|
||||
new WPML_TP_Apply_Single_Job(
|
||||
wpml_tm_get_tp_translations_repository(),
|
||||
new WPML_TP_Apply_Translation_Strategies( $wpdb )
|
||||
),
|
||||
wpml_tm_get_tp_sync_jobs()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_REST_Apply_TP_Translation extends WPML_REST_Base {
|
||||
/** @var WPML_TP_Apply_Translations */
|
||||
private $apply_translations;
|
||||
|
||||
public function __construct( WPML_TP_Apply_Translations $apply_translations ) {
|
||||
parent::__construct( 'wpml/tm/v1' );
|
||||
|
||||
$this->apply_translations = $apply_translations;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
$this->register_routes();
|
||||
}
|
||||
|
||||
public function register_routes() {
|
||||
parent::register_route(
|
||||
'/tp/apply-translations',
|
||||
array(
|
||||
'methods' => WP_REST_Server::CREATABLE,
|
||||
'callback' => array( $this, 'apply_translations' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WP_Error|int|array
|
||||
*/
|
||||
public function apply_translations( WP_REST_Request $request ) {
|
||||
try {
|
||||
$params = $request->get_json_params();
|
||||
|
||||
if ( $params ) {
|
||||
if ( ! isset( $params['original_element_id'] ) ) {
|
||||
$params = array_filter( $params, array( $this, 'validate_job' ) );
|
||||
if ( ! $params ) {
|
||||
return array();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $this->apply_translations->apply( $params )->map( array( $this, 'map_jobs_to_array' ) );
|
||||
} catch ( Exception $e ) {
|
||||
return new WP_Error( 400, $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
public function get_allowed_capabilities( WP_REST_Request $request ) {
|
||||
return array( WPML_Manage_Translations_Role::CAPABILITY, WPML_Translator_Role::CAPABILITY );
|
||||
}
|
||||
|
||||
public function map_jobs_to_array( WPML_TM_Job_Entity $job ) {
|
||||
return [
|
||||
'id' => $job->get_id(),
|
||||
'type' => $job->get_type(),
|
||||
'status' => $job->get_status(),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $job
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function validate_job( array $job ) {
|
||||
return isset( $job['id'], $job['type'] ) && \WPML_TM_Job_Entity::is_type_valid( $job['type'] );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_REST_Batch_Sync_Factory extends WPML_REST_Factory_Loader {
|
||||
/**
|
||||
* @return WPML_TM_REST_Batch_Sync
|
||||
*/
|
||||
public function create() {
|
||||
return new WPML_TM_REST_Batch_Sync(
|
||||
new WPML_TP_Batch_Sync_API(
|
||||
wpml_tm_get_tp_api_client(),
|
||||
wpml_tm_get_tp_project(),
|
||||
new WPML_TM_Log()
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_REST_Batch_Sync extends WPML_REST_Base {
|
||||
/** @var WPML_TP_Batch_Sync_API */
|
||||
private $batch_sync_api;
|
||||
|
||||
public function __construct( WPML_TP_Batch_Sync_API $batch_sync_api ) {
|
||||
parent::__construct( 'wpml/tm/v1' );
|
||||
$this->batch_sync_api = $batch_sync_api;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
$this->register_routes();
|
||||
}
|
||||
|
||||
public function register_routes() {
|
||||
parent::register_route(
|
||||
'/tp/batches/sync',
|
||||
array(
|
||||
'methods' => WP_REST_Server::CREATABLE,
|
||||
'callback' => array( $this, 'init' ),
|
||||
'args' => array(
|
||||
'batchId' => array(
|
||||
'required' => true,
|
||||
'validate_callback' => array( $this, 'validate_batch_ids' ),
|
||||
'sanitize_callback' => array( $this, 'sanitize_batch_ids' ),
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
parent::register_route(
|
||||
'/tp/batches/status',
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'check_progress' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
public function init( WP_REST_Request $request ) {
|
||||
try {
|
||||
return $this->batch_sync_api->init_synchronization( $request->get_param( 'batchId' ) );
|
||||
} catch ( Exception $e ) {
|
||||
return new WP_Error( 500, $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
public function check_progress() {
|
||||
try {
|
||||
return $this->batch_sync_api->check_progress();
|
||||
} catch ( Exception $e ) {
|
||||
return new WP_Error( 500, $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public function get_allowed_capabilities( WP_REST_Request $request ) {
|
||||
return array( WPML_Manage_Translations_Role::CAPABILITY, WPML_Translator_Role::CAPABILITY );
|
||||
}
|
||||
|
||||
public function validate_batch_ids( $batches ) {
|
||||
return is_array( $batches );
|
||||
}
|
||||
|
||||
public function sanitize_batch_ids( $batches ) {
|
||||
return array_map( 'intval', $batches );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Rest_Download_File {
|
||||
|
||||
public function send( $file_name, $content, $content_type = 'application/x-xliff+xml' ) {
|
||||
add_filter( 'rest_pre_echo_response', array( $this, 'force_wp_rest_server_download' ) );
|
||||
|
||||
header( 'Content-Description: File Transfer' );
|
||||
header( 'Content-Type: ' . $content_type );
|
||||
header( 'Content-Disposition: attachment; filename="' . $file_name . '"' );
|
||||
header( 'Content-Transfer-Encoding: binary' );
|
||||
header( 'Expires: 0' );
|
||||
header( 'Cache-Control: must-revalidate, post-check=0, pre-check=0' );
|
||||
header( 'Pragma: public' );
|
||||
header( 'Content-Length: ' . strlen( $content ) );
|
||||
|
||||
return $content;
|
||||
}
|
||||
|
||||
public function force_wp_rest_server_download( $content ) {
|
||||
echo $content;
|
||||
exit;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,30 @@
|
||||
<?php
|
||||
|
||||
use WPML\TM\Jobs\Utils\ElementLinkFactory;
|
||||
|
||||
class WPML_TM_REST_Jobs_Factory extends WPML_REST_Factory_Loader {
|
||||
/**
|
||||
* @return WPML_TM_REST_Jobs
|
||||
*/
|
||||
public function create() {
|
||||
global $sitepress, $wpdb;
|
||||
|
||||
return new WPML_TM_REST_Jobs(
|
||||
wpml_tm_get_jobs_repository( true, false, true ),
|
||||
new WPML_TM_Rest_Jobs_Criteria_Parser(),
|
||||
new WPML_TM_Rest_Jobs_View_Model(
|
||||
WPML_TM_Rest_Jobs_Translation_Service::create(),
|
||||
new WPML_TM_Rest_Jobs_Element_Info(
|
||||
new WPML_TM_Rest_Jobs_Package_Helper_Factory()
|
||||
),
|
||||
new WPML_TM_Rest_Jobs_Language_Names( $sitepress ),
|
||||
new WPML_TM_Rest_Job_Translator_Name(),
|
||||
new WPML_TM_Rest_Job_Progress(),
|
||||
ElementLinkFactory::create()
|
||||
),
|
||||
new WPML_TP_Sync_Update_Job( $wpdb, $sitepress ),
|
||||
new WPML_TM_Last_Picked_Up( $sitepress )
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,335 @@
|
||||
<?php
|
||||
/**
|
||||
* WPML_TM_REST_Jobs class file.
|
||||
*
|
||||
* @package wpml-translation-management
|
||||
*/
|
||||
|
||||
use WPML\FP\Obj;
|
||||
use WPML\FP\Fns;
|
||||
use WPML\FP\Maybe;
|
||||
use WPML\LIB\WP\User;
|
||||
use WPML\TM\ATE\Review\Cancel;
|
||||
use function WPML\FP\pipe;
|
||||
use function WPML\FP\partial;
|
||||
use function WPML\FP\invoke;
|
||||
use function WPML\FP\curryN;
|
||||
|
||||
/**
|
||||
* Class WPML_TM_REST_Jobs
|
||||
*/
|
||||
class WPML_TM_REST_Jobs extends WPML_REST_Base {
|
||||
const CAPABILITY = 'translate';
|
||||
|
||||
/**
|
||||
* Jobs repository
|
||||
*
|
||||
* @var WPML_TM_Jobs_Repository
|
||||
*/
|
||||
private $jobs_repository;
|
||||
|
||||
/**
|
||||
* Rest jobs criteria parser
|
||||
*
|
||||
* @var WPML_TM_Rest_Jobs_Criteria_Parser
|
||||
*/
|
||||
private $criteria_parser;
|
||||
|
||||
/**
|
||||
* View model
|
||||
*
|
||||
* @var WPML_TM_Rest_Jobs_View_Model
|
||||
*/
|
||||
private $view_model;
|
||||
|
||||
/**
|
||||
* Update jobs synchronisation
|
||||
*
|
||||
* @var WPML_TP_Sync_Update_Job
|
||||
*/
|
||||
private $update_jobs;
|
||||
|
||||
/**
|
||||
* Last picked up jobs
|
||||
*
|
||||
* @var WPML_TM_Last_Picked_Up $wpml_tm_last_picked_up
|
||||
*/
|
||||
private $wpml_tm_last_picked_up;
|
||||
|
||||
/**
|
||||
* WPML_TM_REST_Jobs constructor.
|
||||
*
|
||||
* @param WPML_TM_Jobs_Repository $jobs_repository Jobs repository.
|
||||
* @param WPML_TM_Rest_Jobs_Criteria_Parser $criteria_parser Rest jobs criteria parser.
|
||||
* @param WPML_TM_Rest_Jobs_View_Model $view_model View model.
|
||||
* @param WPML_TP_Sync_Update_Job $update_jobs Update jobs synchronisation.
|
||||
* @param WPML_TM_Last_Picked_Up $wpml_tm_last_picked_up Last picked up jobs.
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_TM_Jobs_Repository $jobs_repository,
|
||||
WPML_TM_Rest_Jobs_Criteria_Parser $criteria_parser,
|
||||
WPML_TM_Rest_Jobs_View_Model $view_model,
|
||||
WPML_TP_Sync_Update_Job $update_jobs,
|
||||
WPML_TM_Last_Picked_Up $wpml_tm_last_picked_up
|
||||
) {
|
||||
parent::__construct( 'wpml/tm/v1' );
|
||||
|
||||
$this->jobs_repository = $jobs_repository;
|
||||
$this->criteria_parser = $criteria_parser;
|
||||
$this->view_model = $view_model;
|
||||
$this->update_jobs = $update_jobs;
|
||||
$this->wpml_tm_last_picked_up = $wpml_tm_last_picked_up;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Add hooks
|
||||
*/
|
||||
public function add_hooks() {
|
||||
$this->register_routes();
|
||||
}
|
||||
|
||||
/**
|
||||
* Register routes
|
||||
*/
|
||||
public function register_routes() {
|
||||
parent::register_route(
|
||||
'/jobs',
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_jobs' ),
|
||||
'args' => array(
|
||||
'local_job_ids' => array(
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => array( 'WPML_REST_Arguments_Sanitation', 'string' ),
|
||||
),
|
||||
'scope' => array(
|
||||
'type' => 'string',
|
||||
'validate_callback' => array( 'WPML_TM_Jobs_Search_Params', 'is_valid_scope' ),
|
||||
'sanitize_callback' => array( 'WPML_REST_Arguments_Sanitation', 'string' ),
|
||||
),
|
||||
'id' => array(
|
||||
'type' => 'integer',
|
||||
'sanitize_callback' => array( 'WPML_REST_Arguments_Sanitation', 'integer' ),
|
||||
),
|
||||
'title' => array(
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => array( 'WPML_REST_Arguments_Sanitation', 'string' ),
|
||||
),
|
||||
'source_language' => array(
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => array( 'WPML_REST_Arguments_Sanitation', 'string' ),
|
||||
),
|
||||
'target_language' => array(
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => array( 'WPML_REST_Arguments_Sanitation', 'string' ),
|
||||
),
|
||||
'status' => array(
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => array( 'WPML_REST_Arguments_Sanitation', 'string' ),
|
||||
),
|
||||
'needs_update' => array(
|
||||
'type' => 'string',
|
||||
'validate_callback' => array( 'WPML_TM_Jobs_Needs_Update_Param', 'is_valid' ),
|
||||
),
|
||||
'limit' => array(
|
||||
'type' => 'integer',
|
||||
'validate_callback' => array( 'WPML_REST_Arguments_Validation', 'integer' ),
|
||||
),
|
||||
'offset' => array(
|
||||
'type' => 'integer',
|
||||
'validate_callback' => array( 'WPML_REST_Arguments_Validation', 'integer' ),
|
||||
),
|
||||
'sorting' => array(
|
||||
'validate_callback' => array( $this, 'validate_sorting' ),
|
||||
),
|
||||
'translated_by' => array(
|
||||
'type' => 'string',
|
||||
'sanitize_callback' => array( 'WPML_REST_Arguments_Sanitation', 'string' ),
|
||||
),
|
||||
'sent_from' => array(
|
||||
'type' => 'string',
|
||||
'validate_callback' => array( 'WPML_REST_Arguments_Validation', 'date' ),
|
||||
),
|
||||
'sent_to' => array(
|
||||
'type' => 'string',
|
||||
'validate_callback' => array( 'WPML_REST_Arguments_Validation', 'date' ),
|
||||
),
|
||||
'deadline_from' => array(
|
||||
'type' => 'string',
|
||||
'validate_callback' => array( 'WPML_REST_Arguments_Validation', 'date' ),
|
||||
),
|
||||
'deadline_to' => array(
|
||||
'type' => 'string',
|
||||
'validate_callback' => array( 'WPML_REST_Arguments_Validation', 'date' ),
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
parent::register_route(
|
||||
'/jobs/assign',
|
||||
array(
|
||||
'methods' => 'POST',
|
||||
'callback' => array( $this, 'assign_job' ),
|
||||
'args' => array(
|
||||
'jobId' => array(
|
||||
'required' => true,
|
||||
'validate_callback' => array( 'WPML_REST_Arguments_Validation', 'integer' ),
|
||||
'sanitize_callback' => array( 'WPML_REST_Arguments_Sanitation', 'integer' ),
|
||||
),
|
||||
'type' => array(
|
||||
'required' => false,
|
||||
'validate_callback' => [ WPML_TM_Job_Entity::class, 'is_type_valid' ],
|
||||
),
|
||||
'translatorId' => array(
|
||||
'required' => true,
|
||||
'validate_callback' => array( 'WPML_REST_Arguments_Validation', 'integer' ),
|
||||
'sanitize_callback' => array( 'WPML_REST_Arguments_Sanitation', 'integer' ),
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
parent::register_route(
|
||||
'/jobs/cancel',
|
||||
array(
|
||||
'methods' => 'POST',
|
||||
'callback' => array( $this, 'cancel_jobs' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get jobs
|
||||
*
|
||||
* @param WP_REST_Request $request REST request.
|
||||
*
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
public function get_jobs( WP_REST_Request $request ) {
|
||||
try {
|
||||
$criteria = $this->criteria_parser->build_criteria( $request );
|
||||
|
||||
$model = $this->view_model->build(
|
||||
$this->jobs_repository->get( $criteria ),
|
||||
$this->jobs_repository->get_count( $criteria )
|
||||
);
|
||||
|
||||
$model['last_picked_up_date'] = $this->wpml_tm_last_picked_up->get();
|
||||
|
||||
return $model;
|
||||
} catch ( Exception $e ) {
|
||||
return new WP_Error( 500, $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Assign job.
|
||||
*
|
||||
* @param WP_REST_Request $request REST request.
|
||||
*
|
||||
* @return array
|
||||
* @throws \InvalidArgumentException Exception on error.
|
||||
*/
|
||||
public function assign_job( WP_REST_Request $request ) {
|
||||
/**
|
||||
* It can be job_id from icl_translate_job or id from icl_string_translations
|
||||
*
|
||||
* @var int $job_id
|
||||
*/
|
||||
$job_id = $request->get_param( 'jobId' );
|
||||
$job_type = $request->get_param( 'type' ) ? $request->get_param( 'type' ) : WPML_TM_Job_Entity::POST_TYPE;
|
||||
|
||||
$assignJob = curryN( 4, 'wpml_tm_assign_translation_job');
|
||||
|
||||
return Maybe::of( $request->get_param( 'translatorId' ) )
|
||||
->filter( User::get() )
|
||||
->map( $assignJob( $job_id, Fns::__, 'local', $job_type ) )
|
||||
->map( Obj::objOf( 'assigned' ) )
|
||||
->getOrElse( null );
|
||||
}
|
||||
|
||||
/**
|
||||
* Cancel job
|
||||
*
|
||||
* @param WP_REST_Request $request REST request.
|
||||
*
|
||||
* @return array|WP_Error
|
||||
*/
|
||||
public function cancel_jobs( WP_REST_Request $request ) {
|
||||
try {
|
||||
// $validateParameter :: [id, type] -> bool
|
||||
$validateParameter = pipe( Obj::prop( 'type' ), [ \WPML_TM_Job_Entity::class, 'is_type_valid' ] );
|
||||
|
||||
// $getJob :: [id, type] -> \WPML_TM_Job_Entity
|
||||
$getJob = Fns::converge( [ $this->jobs_repository, 'get_job' ], [ Obj::prop( 'id' ), Obj::prop( 'type' ) ] );
|
||||
|
||||
// $jobEntityToArray :: \WPML_TM_Job_Entity -> [id, type]
|
||||
$jobEntityToArray = function ( \WPML_TM_Job_Entity $job ) {
|
||||
return [
|
||||
'id' => $job->get_id(),
|
||||
'type' => $job->get_type(),
|
||||
];
|
||||
};
|
||||
|
||||
$jobs = \wpml_collect( $request->get_json_params() )
|
||||
->filter( $validateParameter )
|
||||
->map( $getJob )
|
||||
->filter()
|
||||
->map( Fns::tap( invoke( 'set_status' )->with( ICL_TM_NOT_TRANSLATED ) ) )
|
||||
->map( Fns::tap( [ $this->update_jobs, 'update_state' ] ) );
|
||||
|
||||
do_action( 'wpml_tm_jobs_cancelled', $jobs->toArray() );
|
||||
|
||||
return $jobs->map( $jobEntityToArray )->values()->toArray();
|
||||
} catch ( Exception $e ) {
|
||||
return new WP_Error( 500, $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get allowed capabilities
|
||||
*
|
||||
* @param WP_REST_Request $request REST request.
|
||||
*
|
||||
* @return array|string
|
||||
*/
|
||||
public function get_allowed_capabilities( WP_REST_Request $request ) {
|
||||
return array( WPML_Manage_Translations_Role::CAPABILITY, WPML_Translator_Role::CAPABILITY );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate sorting
|
||||
*
|
||||
* @param mixed $sorting Sorting parameters.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function validate_sorting( $sorting ) {
|
||||
if ( ! is_array( $sorting ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
foreach ( $sorting as $column => $asc_or_desc ) {
|
||||
new WPML_TM_Jobs_Sorting_Param( $column, $asc_or_desc );
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate job
|
||||
*
|
||||
* @param mixed $job Job.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function validate_job( $job ) {
|
||||
return is_array( $job ) && isset( $job['id'] ) && isset( $job['type'] ) && \WPML_TM_Job_Entity::is_type_valid( $job['type'] );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_REST_TP_XLIFF_Factory extends WPML_REST_Factory_Loader {
|
||||
|
||||
public function create() {
|
||||
return new WPML_TM_REST_TP_XLIFF(
|
||||
new WPML_TP_Translations_Repository(
|
||||
wpml_tm_get_tp_xliff_api(),
|
||||
wpml_tm_get_jobs_repository()
|
||||
),
|
||||
new WPML_TM_Rest_Download_File()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,100 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_REST_TP_XLIFF extends WPML_REST_Base {
|
||||
/** @var WPML_TP_Translations_Repository */
|
||||
private $translation_repository;
|
||||
|
||||
/** @var WPML_TM_Rest_Download_File */
|
||||
private $download_file;
|
||||
|
||||
public function __construct(
|
||||
WPML_TP_Translations_Repository $translation_repository,
|
||||
WPML_TM_Rest_Download_File $download_file
|
||||
) {
|
||||
parent::__construct( 'wpml/tm/v1' );
|
||||
|
||||
$this->translation_repository = $translation_repository;
|
||||
$this->download_file = $download_file;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
$this->register_routes();
|
||||
}
|
||||
|
||||
public function register_routes() {
|
||||
parent::register_route(
|
||||
'/tp/xliff/download/(?P<job_id>\d+)/(?P<job_type>\w+)',
|
||||
array(
|
||||
'methods' => WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_job_translations_from_tp' ),
|
||||
'args' => array(
|
||||
'job_id' => array(
|
||||
'required' => true,
|
||||
),
|
||||
'job_type' => array(
|
||||
'required' => true,
|
||||
'validate_callback' => array( $this, 'validate_job_type' ),
|
||||
),
|
||||
'json' => array(
|
||||
'type' => 'boolean',
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WP_REST_Request $request
|
||||
*
|
||||
* @return array|string|WP_Error
|
||||
*/
|
||||
public function get_job_translations_from_tp( WP_REST_Request $request ) {
|
||||
try {
|
||||
if ( $request->get_param( 'json' ) ) {
|
||||
return $this->translation_repository->get_job_translations(
|
||||
$request->get_param( 'job_id' ),
|
||||
$request->get_param( 'job_type' )
|
||||
)->to_array();
|
||||
} else {
|
||||
return $this->download_job_translation( $request );
|
||||
}
|
||||
} catch ( Exception $e ) {
|
||||
return new WP_Error( 400, $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WP_REST_Request $request
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function download_job_translation( WP_REST_Request $request ) {
|
||||
try {
|
||||
$content = $this->translation_repository->get_job_translations(
|
||||
$request->get_param( 'job_id' ),
|
||||
$request->get_param( 'job_type' ),
|
||||
false
|
||||
);
|
||||
} catch ( WPML_TP_API_Exception $e ) {
|
||||
return new WP_Error( 500, $e->getMessage() );
|
||||
}
|
||||
|
||||
$file_name = sprintf( 'job-%d.xliff', $request->get_param( 'job_id' ) );
|
||||
return $this->download_file->send( $file_name, $content );
|
||||
}
|
||||
|
||||
public function get_allowed_capabilities( WP_REST_Request $request ) {
|
||||
return array( WPML_Manage_Translations_Role::CAPABILITY, WPML_Translator_Role::CAPABILITY );
|
||||
}
|
||||
|
||||
public function validate_job_type( $value ) {
|
||||
return in_array(
|
||||
$value,
|
||||
array(
|
||||
WPML_TM_Job_Entity::POST_TYPE,
|
||||
WPML_TM_Job_Entity::STRING_TYPE,
|
||||
WPML_TM_Job_Entity::PACKAGE_TYPE,
|
||||
)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Rest_Job_Progress {
|
||||
/** @var wpdb */
|
||||
private $wpdb;
|
||||
|
||||
public function __construct() {
|
||||
global $wpdb;
|
||||
$this->wpdb = $wpdb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Job_Entity $job
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get( WPML_TM_Job_Entity $job ) {
|
||||
if ( $job->get_translation_service() !== 'local' ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( $job->get_status() !== ICL_TM_IN_PROGRESS ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
if ( $job->get_type() === WPML_TM_Job_Entity::STRING_TYPE ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$sql = "
|
||||
SELECT field_finished FROM {$this->wpdb->prefix}icl_translate translate
|
||||
INNER JOIN {$this->wpdb->prefix}icl_translate_job translate_job ON translate_job.job_id = translate.job_id
|
||||
INNER JOIN {$this->wpdb->prefix}icl_translation_status translation_status ON translation_status.rid = translate_job.rid
|
||||
WHERE translation_status.rid = %d AND translate.field_translate = 1 AND LENGTH(translate.field_data) > 0
|
||||
";
|
||||
$sql = $this->wpdb->prepare( $sql, $job->get_id() );
|
||||
|
||||
$elements = $this->wpdb->get_col( $sql );
|
||||
$translated = array_filter( $elements );
|
||||
|
||||
$percentage = (int) ( count( $translated ) / count( $elements ) * 100 );
|
||||
|
||||
return sprintf( _x( '%s completed', 'Translation jobs list', 'wpml-transation-manager' ), $percentage . '%' );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Rest_Job_Translator_Name {
|
||||
|
||||
public function get( $translator_id ) {
|
||||
$user = get_user_by( 'id', $translator_id );
|
||||
if ( $user instanceof WP_User ) {
|
||||
return $user->display_name;
|
||||
} else {
|
||||
return '';
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Rest_Jobs_Columns {
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function get_columns() {
|
||||
return array(
|
||||
'id' => __( 'ID', 'wpml-translation-management' ),
|
||||
'title' => __( 'Title', 'wpml-translation-management' ),
|
||||
'languages' => __( 'Languages', 'wpml-translation-management' ),
|
||||
'batch_name' => __( 'Batch name', 'wpml-translation-management' ),
|
||||
'translator' => __( 'Translated by', 'wpml-translation-management' ),
|
||||
'sent_date' => __( 'Sent on', 'wpml-translation-management' ),
|
||||
'deadline' => __( 'Deadline', 'wpml-translation-management' ),
|
||||
'status' => __( 'Status', 'wpml-translation-management' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function get_sortable() {
|
||||
return array(
|
||||
'id' => __( 'ID', 'wpml-translation-management' ),
|
||||
'title' => __( 'Title', 'wpml-translation-management' ),
|
||||
'batch_name' => __( 'Batch name', 'wpml-translation-management' ),
|
||||
'language' => __( 'Language', 'wpml-translation-management' ),
|
||||
'sent_date' => __( 'Sent on', 'wpml-translation-management' ),
|
||||
'deadline_date' => __( 'Deadline', 'wpml-translation-management' ),
|
||||
'status' => __( 'Status', 'wpml-translation-management' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,179 @@
|
||||
<?php
|
||||
|
||||
use WPML\FP\Cast;
|
||||
use WPML\FP\Fns;
|
||||
use WPML\FP\Lst;
|
||||
use WPML\FP\Relation;
|
||||
use WPML\LIB\WP\User;
|
||||
use WPML\TM\API\Translators;
|
||||
|
||||
class WPML_TM_Rest_Jobs_Criteria_Parser {
|
||||
/**
|
||||
* @param WP_REST_Request $request
|
||||
*
|
||||
* @return WPML_TM_Jobs_Search_Params
|
||||
*/
|
||||
public function build_criteria( WP_REST_Request $request ) {
|
||||
$params = new WPML_TM_Jobs_Search_Params();
|
||||
|
||||
$params = $this->set_scope( $params, $request );
|
||||
$params = $this->set_pagination( $params, $request );
|
||||
$params = $this->set_filters( $params, $request );
|
||||
$params = $this->set_sorting( $params, $request );
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Jobs_Search_Params $params
|
||||
* @param WP_REST_Request $request
|
||||
*
|
||||
* @return WPML_TM_Jobs_Search_Params
|
||||
*/
|
||||
private function set_scope( WPML_TM_Jobs_Search_Params $params, WP_REST_Request $request ) {
|
||||
$scope = $request->get_param( 'scope' );
|
||||
if ( WPML_TM_Jobs_Search_Params::is_valid_scope( $scope ) ) {
|
||||
$params->set_scope( $scope );
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Jobs_Search_Params $params
|
||||
* @param WP_REST_Request $request
|
||||
*
|
||||
* @return WPML_TM_Jobs_Search_Params
|
||||
*/
|
||||
private function set_pagination( WPML_TM_Jobs_Search_Params $params, WP_REST_Request $request ) {
|
||||
$limit = (int) $request->get_param( 'limit' );
|
||||
if ( $limit > 0 ) {
|
||||
$params->set_limit( $limit );
|
||||
|
||||
$offset = (int) $request->get_param( 'offset' );
|
||||
if ( $offset > 0 ) {
|
||||
$params->set_offset( $offset );
|
||||
}
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
private function set_filters( WPML_TM_Jobs_Search_Params $params, WP_REST_Request $request ) {
|
||||
foreach ( [ 'id', 'source_language', 'translated_by', 'element_type' ] as $key ) {
|
||||
$value = (string) $request->get_param( $key );
|
||||
if ( $value ) {
|
||||
$params->{'set_' . $key}( $value );
|
||||
}
|
||||
}
|
||||
|
||||
foreach ( [ 'local_job_ids', 'title', 'target_language', 'batch_name' ] as $key ) {
|
||||
$value = (string) $request->get_param( $key );
|
||||
if ( strlen( $value ) ) {
|
||||
$params->{'set_' . $key}( explode( ',', $value ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $request->get_param( 'status' ) !== null ) {
|
||||
$statuses = Fns::map( Cast::toInt(), explode( ',', $request->get_param( 'status' ) ) );
|
||||
|
||||
if ( $statuses === [ ICL_TM_NEEDS_REVIEW ] ) {
|
||||
$params->set_needs_review( true );
|
||||
} else {
|
||||
$params->set_status( Fns::reject( Relation::equals( ICL_TM_NEEDS_REVIEW ), $statuses ) );
|
||||
|
||||
if ( ! Lst::includes( ICL_TM_NEEDS_REVIEW, $statuses ) ) {
|
||||
$params->set_needs_review( false );
|
||||
}
|
||||
}
|
||||
}
|
||||
$params->set_exclude_cancelled();
|
||||
|
||||
if ( $request->get_param( 'needs_update' ) ) {
|
||||
$params->set_needs_update( new WPML_TM_Jobs_Needs_Update_Param( $request->get_param( 'needs_update' ) ) );
|
||||
}
|
||||
|
||||
$date_range_values = array( 'sent', 'deadline' );
|
||||
foreach ( $date_range_values as $date_range_value ) {
|
||||
$from = $request->get_param( $date_range_value . '_from' );
|
||||
$to = $request->get_param( $date_range_value . '_to' );
|
||||
|
||||
if ( $from || $to ) {
|
||||
$from = $from ? new DateTime( $from ) : $from;
|
||||
$to = $to ? new DateTime( $to ) : $to;
|
||||
|
||||
if ( $from && $to && $from > $to ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$params->{'set_' . $date_range_value}( new WPML_TM_Jobs_Date_Range( $from, $to ) );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $request->get_param( 'pageName' ) === \WPML_TM_Jobs_List_Script_Data::TRANSLATION_QUEUE_PAGE ) {
|
||||
global $wpdb;
|
||||
$where[] = $wpdb->prepare( '(translate_job.translator_id = %d OR translate_job.translator_id = 0 OR translate_job.translator_id IS NULL)', User::getCurrentId() );
|
||||
if ( ! $request->get_param( 'includeTranslationServiceJobs' ) ) {
|
||||
$where[] = 'translation_status.translation_service = "local"';
|
||||
}
|
||||
$where[] = "( automatic = 0 OR review_status = 'NEEDS_REVIEW' )";
|
||||
|
||||
$where[] = $this->buildLanguagePairsCriteria();
|
||||
|
||||
$params->set_custom_where_conditions( $where );
|
||||
}
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function buildLanguagePairsCriteria() {
|
||||
$translator = Translators::getCurrent();
|
||||
|
||||
$buildWhereForPair = function ( $targets, $source ) {
|
||||
return sprintf(
|
||||
'( translations.source_language_code = "%s" AND translations.language_code IN (%s) )',
|
||||
$source,
|
||||
wpml_prepare_in( $targets )
|
||||
);
|
||||
};
|
||||
|
||||
return '( ' . \wpml_collect( $translator->language_pairs )
|
||||
->map( $buildWhereForPair )
|
||||
->implode( ' OR ' ) . ' ) ';
|
||||
}
|
||||
|
||||
private function set_sorting( WPML_TM_Jobs_Search_Params $params, WP_REST_Request $request ) {
|
||||
$sorting = [];
|
||||
|
||||
$sortingParams = $request->get_param( 'sorting' );
|
||||
if ( $sortingParams ) {
|
||||
$sorting = $this->build_sorting_params( $sortingParams );
|
||||
}
|
||||
|
||||
if ( $request->get_param( 'pageName' ) === \WPML_TM_Jobs_List_Script_Data::TRANSLATION_QUEUE_PAGE ) {
|
||||
$sorting[] = new \WPML_TM_Jobs_Sorting_Param( "IF ((status = 10 AND (review_status = 'EDITING' OR review_status = 'NEEDS_REVIEW')) OR status = 1, 1,IF (status = 2, 2, IF (needs_update = 1, 3, 4)))", 'ASC' );
|
||||
$sorting[] = new \WPML_TM_Jobs_Sorting_Param( 'translator_id', 'DESC' );
|
||||
$sorting[] = new \WPML_TM_Jobs_Sorting_Param( 'translate_job_id', 'DESC' );
|
||||
}
|
||||
|
||||
$params->set_sorting( $sorting );
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $request_param
|
||||
*
|
||||
* @return WPML_TM_Jobs_Sorting_Param[]
|
||||
*/
|
||||
private function build_sorting_params( array $request_param ) {
|
||||
return \wpml_collect( $request_param )->map(
|
||||
function ( $direction, $column ) {
|
||||
return new WPML_TM_Jobs_Sorting_Param( $column, $direction );
|
||||
}
|
||||
)->toArray();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,165 @@
|
||||
<?php
|
||||
|
||||
use WPML\FP\Obj;
|
||||
|
||||
class WPML_TM_Rest_Jobs_Element_Info {
|
||||
/** @var WPML_TM_Rest_Jobs_Package_Helper_Factory */
|
||||
private $package_helper_factory;
|
||||
|
||||
/** @var array|null */
|
||||
private $post_types;
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Rest_Jobs_Package_Helper_Factory $package_helper_factory
|
||||
*/
|
||||
public function __construct( WPML_TM_Rest_Jobs_Package_Helper_Factory $package_helper_factory ) {
|
||||
$this->package_helper_factory = $package_helper_factory;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Job_Entity $job
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get( WPML_TM_Job_Entity $job ) {
|
||||
$type = $job->get_type();
|
||||
$id = $job->get_original_element_id();
|
||||
$result = [];
|
||||
|
||||
switch ( $type ) {
|
||||
case WPML_TM_Job_Entity::POST_TYPE:
|
||||
/** @var WPML_TM_Post_Job_Entity $job */
|
||||
$result = $this->get_for_post( $id, $job->get_element_id() );
|
||||
break;
|
||||
case WPML_TM_Job_Entity::STRING_TYPE:
|
||||
case WPML_TM_Job_Entity::STRING_BATCH:
|
||||
$result = $this->get_for_title( $job->get_title() );
|
||||
break;
|
||||
case WPML_TM_Job_Entity::PACKAGE_TYPE:
|
||||
$result = $this->get_for_package( $id );
|
||||
break;
|
||||
}
|
||||
|
||||
if ( empty( $result ) ) {
|
||||
$result = array(
|
||||
'name' => '',
|
||||
'url' => null,
|
||||
);
|
||||
do_action( 'wpml_tm_jobs_log', 'WPML_TM_Rest_Jobs_Element_Info::get', array( $id, $type ), 'Empty result' );
|
||||
}
|
||||
|
||||
$result['url'] = apply_filters( 'wpml_tm_job_list_element_url', $result['url'], $id, $type );
|
||||
|
||||
if ( $job instanceof WPML_TM_Post_Job_Entity ) {
|
||||
$result['type'] = $this->get_type_info( $job );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $originalPostId
|
||||
* @param int $translatedPostId
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_for_post( $originalPostId, $translatedPostId ) {
|
||||
$result = array();
|
||||
|
||||
$post = get_post( $originalPostId );
|
||||
if ( $post ) {
|
||||
$permalink = get_permalink( $post );
|
||||
|
||||
$result = [
|
||||
'name' => $post->post_title,
|
||||
'url' => $permalink,
|
||||
'status' => Obj::propOr( 'draft', 'post_status', get_post( $translatedPostId ) ),
|
||||
];
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_for_package( $id ) {
|
||||
$result = array();
|
||||
|
||||
$helper = $this->package_helper_factory->create();
|
||||
if ( ! $helper ) {
|
||||
return array(
|
||||
'name' => __( 'String package job', 'wpml-translation-management' ),
|
||||
'url' => null,
|
||||
);
|
||||
}
|
||||
|
||||
$package = $helper->get_translatable_item( null, $id );
|
||||
if ( $package ) {
|
||||
$result = array(
|
||||
'name' => $package->title,
|
||||
'url' => $package->edit_link,
|
||||
);
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $title
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_for_title( $title ) {
|
||||
return [
|
||||
'name' => $title,
|
||||
'url' => null,
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Post_Job_Entity $job
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_type_info( WPML_TM_Post_Job_Entity $job ) {
|
||||
$generalType = substr(
|
||||
$job->get_element_type(),
|
||||
0,
|
||||
strpos( $job->get_element_type(), '_' )
|
||||
);
|
||||
|
||||
switch ( $generalType ) {
|
||||
case 'post':
|
||||
case 'package':
|
||||
$specificType = substr( $job->get_element_type(), strlen( $generalType ) + 1 );
|
||||
$label = Obj::pathOr(
|
||||
$job->get_element_type(),
|
||||
[ $specificType, 'labels', 'singular_name' ],
|
||||
$this->get_post_types()
|
||||
);
|
||||
break;
|
||||
case 'st-batch':
|
||||
$label = __( 'Strings', 'wpml-translation-management' );
|
||||
break;
|
||||
default:
|
||||
$label = $job->get_element_type();
|
||||
}
|
||||
|
||||
return [
|
||||
'value' => $job->get_element_type(),
|
||||
'label' => $label,
|
||||
];
|
||||
}
|
||||
|
||||
private function get_post_types() {
|
||||
if ( $this->post_types === null ) {
|
||||
$this->post_types = \WPML\API\PostTypes::getTranslatableWithInfo();
|
||||
}
|
||||
|
||||
return $this->post_types;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,40 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Rest_Jobs_Language_Names {
|
||||
/** @var SitePress */
|
||||
private $sitepress;
|
||||
|
||||
/** @var array */
|
||||
private $active_languages;
|
||||
|
||||
/**
|
||||
* @param SitePress $sitepress
|
||||
*/
|
||||
public function __construct( SitePress $sitepress ) {
|
||||
$this->sitepress = $sitepress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $code
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get( $code ) {
|
||||
$languages = $this->get_active_languages();
|
||||
|
||||
return isset( $languages[ $code ] ) ? $languages[ $code ] : $code;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_active_languages() {
|
||||
if ( ! $this->active_languages ) {
|
||||
foreach ( $this->sitepress->get_active_languages() as $code => $data ) {
|
||||
$this->active_languages[ $code ] = $data['display_name'];
|
||||
}
|
||||
}
|
||||
|
||||
return $this->active_languages;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Rest_Jobs_Package_Helper_Factory {
|
||||
/** @var WPML_Package_Helper */
|
||||
private $package_helper = false;
|
||||
|
||||
/**
|
||||
* @return null|WPML_Package_Helper
|
||||
*/
|
||||
public function create() {
|
||||
if ( false === $this->package_helper ) {
|
||||
if ( defined( 'WPML_ST_VERSION' ) && class_exists( 'WPML_Package_Helper' ) ) {
|
||||
$this->package_helper = new WPML_Package_Helper();
|
||||
} else {
|
||||
$this->package_helper = null;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->package_helper;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,61 @@
|
||||
<?php
|
||||
|
||||
class WPML_TM_Rest_Jobs_Translation_Service {
|
||||
/** @var WPML_WP_Cache */
|
||||
private $cache;
|
||||
|
||||
/**
|
||||
* @param WPML_WP_Cache $cache
|
||||
*/
|
||||
public function __construct( WPML_WP_Cache $cache ) {
|
||||
$this->cache = $cache;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @param string|int $service_id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_name( $service_id ) {
|
||||
$name = '';
|
||||
if ( is_numeric( $service_id ) ) {
|
||||
$service = $this->get_translation_service( (int) $service_id );
|
||||
if ( $service ) {
|
||||
$name = $service->name;
|
||||
}
|
||||
} else {
|
||||
$name = __( 'Local', 'wpml-translation-management' );
|
||||
}
|
||||
|
||||
return $name;
|
||||
}
|
||||
|
||||
private function get_translation_service( $service_id ) {
|
||||
$key = 'service_' . $service_id;
|
||||
$found = false;
|
||||
$service = $this->cache->get( $key, $found );
|
||||
|
||||
if ( ! $found ) {
|
||||
$current_service = TranslationProxy::get_current_service();
|
||||
if ( $current_service && $current_service->id === $service_id ) {
|
||||
$service = $current_service;
|
||||
} else {
|
||||
$service = TranslationProxy_Service::get_service( $service_id );
|
||||
}
|
||||
|
||||
$this->cache->set( $key, $service );
|
||||
}
|
||||
|
||||
return $service;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_TM_Rest_Jobs_Translation_Service
|
||||
*/
|
||||
public static function create() {
|
||||
$cache = new WPML_WP_Cache( 'wpml-tm-services' );
|
||||
|
||||
return new WPML_TM_Rest_Jobs_Translation_Service( $cache );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,173 @@
|
||||
<?php
|
||||
|
||||
use WPML\Element\API\PostTranslations;
|
||||
use WPML\FP\Fns;
|
||||
use WPML\FP\Lst;
|
||||
use WPML\FP\Obj;
|
||||
use WPML\TM\API\Jobs;
|
||||
use WPML\TM\ATE\Review\PreviewLink;
|
||||
use WPML\TM\ATE\Review\ReviewStatus;
|
||||
use WPML\TM\Jobs\Utils\ElementLink;
|
||||
|
||||
class WPML_TM_Rest_Jobs_View_Model {
|
||||
/** @var WPML_TM_Rest_Jobs_Translation_Service */
|
||||
private $translation_service;
|
||||
|
||||
/** @var WPML_TM_Rest_Jobs_Element_Info */
|
||||
private $element_info;
|
||||
|
||||
/** @var WPML_TM_Rest_Jobs_Language_Names */
|
||||
private $language_names;
|
||||
|
||||
/** @var WPML_TM_Rest_Job_Translator_Name */
|
||||
private $translator_name;
|
||||
|
||||
/** @var WPML_TM_Rest_Job_Progress */
|
||||
private $progress;
|
||||
|
||||
/** @var ElementLink $element_link */
|
||||
private $element_link;
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Rest_Jobs_Translation_Service $translation_service
|
||||
* @param WPML_TM_Rest_Jobs_Element_Info $element_info
|
||||
* @param WPML_TM_Rest_Jobs_Language_Names $language_names
|
||||
* @param WPML_TM_Rest_Job_Translator_Name $translator_name
|
||||
* @param WPML_TM_Rest_Job_Progress $progress
|
||||
* @param ElementLink $element_link
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_TM_Rest_Jobs_Translation_Service $translation_service,
|
||||
WPML_TM_Rest_Jobs_Element_Info $element_info,
|
||||
WPML_TM_Rest_Jobs_Language_Names $language_names,
|
||||
WPML_TM_Rest_Job_Translator_Name $translator_name,
|
||||
WPML_TM_Rest_Job_Progress $progress,
|
||||
ElementLink $element_link
|
||||
) {
|
||||
$this->translation_service = $translation_service;
|
||||
$this->element_info = $element_info;
|
||||
$this->language_names = $language_names;
|
||||
$this->translator_name = $translator_name;
|
||||
$this->progress = $progress;
|
||||
$this->element_link = $element_link;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Jobs_Collection $jobs
|
||||
* @param int $total_jobs_count
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function build( WPML_TM_Jobs_Collection $jobs, $total_jobs_count ) {
|
||||
$result = [ 'jobs' => [] ];
|
||||
|
||||
foreach ( $jobs as $job ) {
|
||||
$result['jobs'][] = $this->map_job( $job );
|
||||
}
|
||||
|
||||
$result['total'] = $total_jobs_count;
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Job_Entity $job
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function map_job( WPML_TM_Job_Entity $job ) {
|
||||
$extra_data = [];
|
||||
$viewUrl = '';
|
||||
|
||||
if ( $job instanceof WPML_TM_Post_Job_Entity ) {
|
||||
$extra_data['icl_translate_job_id'] = $job->get_translate_job_id();
|
||||
$extra_data['editor_job_id'] = $job->get_editor_job_id();
|
||||
|
||||
$viewUrl = $this->getViewUrl( $job );
|
||||
}
|
||||
|
||||
return [
|
||||
'id' => $job->get_rid(),
|
||||
'type' => $job->get_type(),
|
||||
'tp_id' => $job->get_tp_id(),
|
||||
'status' => $job->get_status(),
|
||||
'needs_update' => $job->does_need_update(),
|
||||
'review_status' => $job->get_review_status(),
|
||||
'language_codes' => [
|
||||
'source' => $job->get_source_language(),
|
||||
'target' => $job->get_target_language(),
|
||||
],
|
||||
'languages' => [
|
||||
'source' => $this->language_names->get( $job->get_source_language() ),
|
||||
'target' => $this->language_names->get( $job->get_target_language() ),
|
||||
],
|
||||
'translation_service_id' => $job->get_translation_service(),
|
||||
'translation_service' => $this->translation_service->get_name( $job->get_translation_service() ),
|
||||
'sent_date' => $job->get_sent_date()->format( 'Y-m-d' ),
|
||||
'deadline' => $job->get_deadline() ? $job->get_deadline()->format( 'Y-m-d' ) : '',
|
||||
'ts_status' => (string) $job->get_ts_status(),
|
||||
'element' => $this->element_info->get( $job ),
|
||||
'translator_name' => $job->get_translator_id() ? $this->translator_name->get( $job->get_translator_id() ) : '',
|
||||
'translator_id' => $job->get_translator_id() ? (int) $job->get_translator_id() : '',
|
||||
'is_ate_job' => $job->is_ate_job(),
|
||||
'automatic' => $job->is_automatic(),
|
||||
'progress' => $this->progress->get( $job ),
|
||||
'batch' => [
|
||||
'id' => $job->get_batch()->get_id(),
|
||||
'name' => $job->get_batch()->get_name(),
|
||||
'tp_id' => $job->get_batch()->get_tp_id(),
|
||||
],
|
||||
'extra_data' => $extra_data,
|
||||
'edit_url' => $this->get_edit_url( $job ),
|
||||
'view_url' => $viewUrl,
|
||||
'view_original_url' => $this->element_link->getOriginal( $job ),
|
||||
];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Job_Entity $job
|
||||
*
|
||||
* @return mixed|string|void
|
||||
*/
|
||||
private function get_edit_url( $job ) {
|
||||
$edit_url = '';
|
||||
if ( $job->get_original_element_id() ) {
|
||||
|
||||
$jobId = $job instanceof WPML_TM_Post_Job_Entity ? $job->get_translate_job_id() : $job->get_rid();
|
||||
|
||||
$translation_queue_page = admin_url( 'admin.php?page='
|
||||
. WPML_TM_FOLDER
|
||||
. '/menu/translations-queue.php&job_id='
|
||||
. $jobId );
|
||||
$edit_url = apply_filters( 'icl_job_edit_url', $translation_queue_page, $jobId );
|
||||
}
|
||||
|
||||
return $edit_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Post_Job_Entity $job
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getViewUrl( WPML_TM_Post_Job_Entity $job ) {
|
||||
$needsReview = Lst::includes( $job->get_review_status(), [
|
||||
ReviewStatus::NEEDS_REVIEW,
|
||||
ReviewStatus::EDITING
|
||||
] );
|
||||
|
||||
return $needsReview ? $this->getReviewUrl( $job ) : $this->element_link->getTranslation( $job );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TM_Post_Job_Entity $job
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function getReviewUrl( WPML_TM_Post_Job_Entity $job ) {
|
||||
$translation = PostTranslations::getInLanguage( $job->get_original_element_id(), $job->get_target_language() );
|
||||
$returnUrl = admin_url( 'admin.php?page=' . WPML_TM_FOLDER . '/menu/translations-queue.php' );
|
||||
|
||||
return PreviewLink::getWithSpecifiedReturnUrl( $returnUrl, $translation->element_id, $job->get_translate_job_id() );
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user