first commit
This commit is contained in:
@@ -0,0 +1,135 @@
|
||||
<?php
|
||||
|
||||
use WPML\API\Sanitize;
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Bulk_Actions
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Bulk_Actions {
|
||||
|
||||
/** @var WPML_TF_Data_Object_Storage $feedback_storage */
|
||||
private $feedback_storage;
|
||||
|
||||
/** @var WPML_WP_API $wp_api */
|
||||
private $wp_api;
|
||||
|
||||
/** @var WPML_TF_Backend_Notices $backend_notices */
|
||||
private $backend_notices;
|
||||
|
||||
/**
|
||||
* WPML_TF_Feedback_List_Bulk_Action_Hooks constructor.
|
||||
*
|
||||
* @param WPML_TF_Data_Object_Storage $feedback_storage
|
||||
* @param WPML_WP_API $wp_api
|
||||
* @param WPML_TF_Backend_Notices $backend_notices
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_TF_Data_Object_Storage $feedback_storage,
|
||||
WPML_WP_API $wp_api,
|
||||
WPML_TF_Backend_Notices $backend_notices
|
||||
) {
|
||||
$this->feedback_storage = $feedback_storage;
|
||||
$this->wp_api = $wp_api;
|
||||
$this->backend_notices = $backend_notices;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method bulk_action_callback
|
||||
*/
|
||||
public function process() {
|
||||
|
||||
if ( $this->is_valid_request() && current_user_can( 'manage_options' ) ) {
|
||||
$feedback_ids = array_map( 'intval', $_GET['feedback_ids'] );
|
||||
$bulk_action = Sanitize::stringProp( 'bulk_action', $_GET );
|
||||
|
||||
$updated_feedback_ids = $feedback_ids;
|
||||
|
||||
switch ( $bulk_action ) {
|
||||
case 'trash':
|
||||
$this->delete( $feedback_ids );
|
||||
break;
|
||||
|
||||
case 'untrash':
|
||||
$this->untrash( $feedback_ids );
|
||||
break;
|
||||
|
||||
case 'delete':
|
||||
$this->delete( $feedback_ids, true );
|
||||
break;
|
||||
|
||||
default:
|
||||
$updated_feedback_ids = $this->change_status( $feedback_ids, $bulk_action );
|
||||
break;
|
||||
}
|
||||
|
||||
$this->backend_notices->add_bulk_updated_notice( $updated_feedback_ids, $bulk_action );
|
||||
$this->redirect();
|
||||
} else {
|
||||
$this->backend_notices->remove_bulk_updated_notice_after_display();
|
||||
}
|
||||
}
|
||||
|
||||
private function change_status( array $feedback_ids, $new_status ) {
|
||||
$updated_feedback_ids = array();
|
||||
|
||||
foreach ( $feedback_ids as $feedback_id ) {
|
||||
$feedback = $this->feedback_storage->get( $feedback_id );
|
||||
|
||||
if ( $feedback ) {
|
||||
/** @var WPML_TF_Feedback $feedback */
|
||||
$feedback->set_status( $new_status );
|
||||
$updated_feedback_ids[] = $this->feedback_storage->persist( $feedback );
|
||||
}
|
||||
}
|
||||
|
||||
return $updated_feedback_ids;
|
||||
}
|
||||
|
||||
private function delete( array $feedback_ids, $force_delete = false ) {
|
||||
foreach ( $feedback_ids as $feedback_id ) {
|
||||
$this->feedback_storage->delete( $feedback_id, $force_delete );
|
||||
}
|
||||
}
|
||||
|
||||
private function untrash( array $feedback_ids ) {
|
||||
foreach ( $feedback_ids as $feedback_id ) {
|
||||
$this->feedback_storage->untrash( $feedback_id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function is_valid_request() {
|
||||
$is_valid = false;
|
||||
|
||||
if ( isset( $_GET['bulk_action'], $_GET['bulk_action2'] ) ) {
|
||||
if ( '-1' === $_GET['bulk_action'] ) {
|
||||
$_GET['bulk_action'] = $_GET['bulk_action2'];
|
||||
}
|
||||
|
||||
if ( isset( $_GET['nonce'], $_GET['feedback_ids'] ) ) {
|
||||
$is_valid = $this->is_valid_action( $_GET['bulk_action'] )
|
||||
&& wp_verify_nonce( $_GET['nonce'], WPML_TF_Backend_Hooks::PAGE_HOOK );
|
||||
}
|
||||
}
|
||||
|
||||
return $is_valid;
|
||||
}
|
||||
|
||||
private function is_valid_action( $action ) {
|
||||
return in_array( $action, array( 'pending', 'fixed', 'trash', 'untrash', 'delete' ), true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirect after processing the bulk action
|
||||
*/
|
||||
private function redirect() {
|
||||
$args_to_remove = array( 'feedback_ids', 'bulk_action', 'bulk_action2' );
|
||||
$url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
|
||||
$url = remove_query_arg( $args_to_remove, $url );
|
||||
$this->wp_api->wp_safe_redirect( $url );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_TP_Ratings_Synchronize
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_TP_Ratings_Synchronize {
|
||||
|
||||
const MAX_RATINGS_TO_SYNCHRONIZE = 5;
|
||||
const PENDING_SYNC_RATING_IDS_OPTION = 'wpml_tf_pending_sync_rating_ids';
|
||||
const MAX_ATTEMPTS_TO_SYNC = 3;
|
||||
|
||||
/** @var WPML_TF_Data_Object_Storage $feedback_storage */
|
||||
private $feedback_storage;
|
||||
|
||||
/** @var WPML_TP_API_TF_Ratings $tp_ratings */
|
||||
private $tp_ratings;
|
||||
|
||||
/** @var array $pending_ids */
|
||||
private $pending_ids;
|
||||
|
||||
/**
|
||||
* WPML_TF_TP_Ratings_Synchronize constructor.
|
||||
*
|
||||
* @param WPML_TF_Data_Object_Storage $feedback_storage
|
||||
* @param WPML_TP_API_TF_Ratings $tp_ratings
|
||||
*/
|
||||
public function __construct( WPML_TF_Data_Object_Storage $feedback_storage, WPML_TP_API_TF_Ratings $tp_ratings ) {
|
||||
$this->feedback_storage = $feedback_storage;
|
||||
$this->tp_ratings = $tp_ratings;
|
||||
}
|
||||
|
||||
/** @param bool $clear_all_pending_ratings */
|
||||
public function run( $clear_all_pending_ratings = false ) {
|
||||
$this->pending_ids = get_option( self::PENDING_SYNC_RATING_IDS_OPTION, array() );
|
||||
|
||||
$filter_args = array(
|
||||
'pending_tp_ratings' => $clear_all_pending_ratings ? -1 : self::MAX_RATINGS_TO_SYNCHRONIZE,
|
||||
);
|
||||
|
||||
$feedback_filter = new WPML_TF_Feedback_Collection_Filter( $filter_args );
|
||||
/** @var WPML_TF_Feedback_Collection $feedback_collection */
|
||||
$feedback_collection = $this->feedback_storage->get_collection( $feedback_filter );
|
||||
$time_threshold = 5 * MINUTE_IN_SECONDS;
|
||||
|
||||
foreach ( $feedback_collection as $feedback ) {
|
||||
/** @var WPML_TF_Feedback $feedback */
|
||||
$time_since_creation = time() - strtotime( $feedback->get_date_created() );
|
||||
|
||||
if ( ! $clear_all_pending_ratings && $time_since_creation < $time_threshold ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$tp_rating_id = $this->tp_ratings->send( $feedback );
|
||||
|
||||
if ( $tp_rating_id || $clear_all_pending_ratings ) {
|
||||
$this->set_tp_rating_id( $feedback, $tp_rating_id );
|
||||
} else {
|
||||
$this->handle_pending_rating_sync( $feedback );
|
||||
}
|
||||
}
|
||||
|
||||
if ( $this->pending_ids ) {
|
||||
update_option( self::PENDING_SYNC_RATING_IDS_OPTION, $this->pending_ids, false );
|
||||
} else {
|
||||
delete_option( self::PENDING_SYNC_RATING_IDS_OPTION );
|
||||
}
|
||||
}
|
||||
|
||||
private function set_tp_rating_id( WPML_TF_Feedback $feedback, $tp_rating_id ) {
|
||||
$feedback->get_tp_responses()->set_rating_id( (int) $tp_rating_id );
|
||||
$this->feedback_storage->persist( $feedback );
|
||||
}
|
||||
|
||||
private function handle_pending_rating_sync( WPML_TF_Feedback $feedback ) {
|
||||
$this->increment_attempts( $feedback->get_id() );
|
||||
|
||||
if ( $this->exceeds_max_attempts( $feedback->get_id() ) ) {
|
||||
$this->set_tp_rating_id( $feedback, 0 );
|
||||
unset( $this->pending_ids[ $feedback->get_id() ] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function exceeds_max_attempts( $id ) {
|
||||
return isset( $this->pending_ids[ $id ] ) && $this->pending_ids[ $id ] >= self::MAX_ATTEMPTS_TO_SYNC;
|
||||
}
|
||||
|
||||
/** @param int $id */
|
||||
private function increment_attempts( $id ) {
|
||||
if ( ! isset( $this->pending_ids[ $id ] ) ) {
|
||||
$this->pending_ids[ $id ] = 1;
|
||||
} else {
|
||||
$this->pending_ids[ $id ]++;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_WP_Cron_Events
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_WP_Cron_Events implements IWPML_Action {
|
||||
|
||||
const SYNCHRONIZE_RATINGS_EVENT = 'wpml_tf_synchronize_ratings_event';
|
||||
|
||||
/** @var WPML_TF_Settings_Read $settings_read */
|
||||
private $settings_read;
|
||||
|
||||
/** @var WPML_TF_Settings $settings */
|
||||
private $settings;
|
||||
|
||||
/** @var WPML_TF_TP_Ratings_Synchronize_Factory $ratings_synchronize_factory */
|
||||
private $ratings_synchronize_factory;
|
||||
|
||||
/**
|
||||
* WPML_TF_WP_Cron_Events constructor.
|
||||
*
|
||||
* @param WPML_TF_Settings_Read $settings_read
|
||||
* @param WPML_TF_TP_Ratings_Synchronize_Factory $ratings_synchronize_factory
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_TF_Settings_Read $settings_read,
|
||||
WPML_TF_TP_Ratings_Synchronize_Factory $ratings_synchronize_factory
|
||||
) {
|
||||
$this->settings_read = $settings_read;
|
||||
$this->ratings_synchronize_factory = $ratings_synchronize_factory;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'init', array( $this, 'init_action' ) );
|
||||
add_action( self::SYNCHRONIZE_RATINGS_EVENT, array( $this, 'synchronize_ratings' ) );
|
||||
}
|
||||
|
||||
public function init_action() {
|
||||
if ( $this->get_settings()->is_enabled() ) {
|
||||
$this->add_synchronize_ratings_event();
|
||||
} else {
|
||||
$this->remove_synchronize_ratings_event();
|
||||
}
|
||||
}
|
||||
|
||||
private function add_synchronize_ratings_event() {
|
||||
if ( ! wp_next_scheduled( self::SYNCHRONIZE_RATINGS_EVENT ) ) {
|
||||
wp_schedule_event( time(), 'twicedaily', self::SYNCHRONIZE_RATINGS_EVENT );
|
||||
}
|
||||
}
|
||||
|
||||
private function remove_synchronize_ratings_event() {
|
||||
$timestamp = wp_next_scheduled( self::SYNCHRONIZE_RATINGS_EVENT );
|
||||
wp_unschedule_event( $timestamp, self::SYNCHRONIZE_RATINGS_EVENT );
|
||||
}
|
||||
|
||||
public function synchronize_ratings() {
|
||||
$ratings_synchronize = $this->ratings_synchronize_factory->create();
|
||||
$ratings_synchronize->run();
|
||||
}
|
||||
|
||||
/** @return WPML_TF_Settings */
|
||||
private function get_settings() {
|
||||
if ( ! $this->settings ) {
|
||||
$this->settings = $this->settings_read->get( 'WPML_TF_Settings' );
|
||||
}
|
||||
|
||||
return $this->settings;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_AJAX_Exception
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_AJAX_Exception extends Exception {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Feedback_Update_Exception
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Feedback_Update_Exception extends Exception {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_AJAX_Feedback_Edit_Hooks_Factory
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_AJAX_Feedback_Edit_Hooks_Factory extends WPML_AJAX_Base_Factory implements IWPML_Backend_Action_Loader {
|
||||
|
||||
const AJAX_ACTION = 'wpml-tf-backend-feedback-edit';
|
||||
|
||||
public function create() {
|
||||
$hooks = null;
|
||||
|
||||
if ( $this->is_valid_action( self::AJAX_ACTION ) ) {
|
||||
$feedback_storage = new WPML_TF_Data_Object_Storage( new WPML_TF_Feedback_Post_Convert() );
|
||||
$message_storage = new WPML_TF_Data_Object_Storage( new WPML_TF_Message_Post_Convert() );
|
||||
|
||||
$feedback_query = new WPML_TF_Feedback_Query(
|
||||
$feedback_storage,
|
||||
$message_storage,
|
||||
new WPML_TF_Collection_Filter_Factory()
|
||||
);
|
||||
|
||||
$feedback_edit = new WPML_TF_Feedback_Edit(
|
||||
$feedback_query,
|
||||
$feedback_storage,
|
||||
$message_storage,
|
||||
class_exists( 'WPML_TP_Client_Factory' ) ? new WPML_TP_Client_Factory() : null
|
||||
);
|
||||
|
||||
$template_loader = new WPML_Twig_Template_Loader(
|
||||
array( WPML_PLUGIN_PATH . WPML_TF_Backend_Feedback_Row_View::TEMPLATE_FOLDER )
|
||||
);
|
||||
$row_view = new WPML_TF_Backend_Feedback_Row_View( $template_loader->get_template() );
|
||||
|
||||
$hooks = new WPML_TF_Backend_AJAX_Feedback_Edit_Hooks(
|
||||
$feedback_edit,
|
||||
$row_view,
|
||||
$_POST
|
||||
);
|
||||
}
|
||||
|
||||
return $hooks;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Hooks_Factory
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Hooks_Factory implements IWPML_Backend_Action_Loader {
|
||||
|
||||
/**
|
||||
* @return WPML_TF_Backend_Hooks
|
||||
*/
|
||||
public function create() {
|
||||
/** @var wpdb $wpdb */
|
||||
global $wpdb;
|
||||
|
||||
return new WPML_TF_Backend_Hooks(
|
||||
new WPML_TF_Backend_Bulk_Actions_Factory(),
|
||||
new WPML_TF_Backend_Feedback_List_View_Factory(),
|
||||
new WPML_TF_Backend_Styles(),
|
||||
new WPML_TF_Backend_Scripts(),
|
||||
$wpdb
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Options_AJAX_Hooks_Factory
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Options_AJAX_Hooks_Factory extends WPML_AJAX_Base_Factory implements IWPML_Backend_Action_Loader {
|
||||
|
||||
const AJAX_ACTION = 'wpml-tf-backend-options';
|
||||
|
||||
/**
|
||||
* @return IWPML_Action|null
|
||||
*/
|
||||
public function create() {
|
||||
global $sitepress;
|
||||
|
||||
$hooks = null;
|
||||
|
||||
if ( $this->is_valid_action( self::AJAX_ACTION ) ) {
|
||||
$settings_read = new WPML_TF_Settings_Read();
|
||||
/** @var WPML_TF_Settings $tf_settings */
|
||||
$tf_settings = $settings_read->get( 'WPML_TF_Settings' );
|
||||
|
||||
$hooks = new WPML_TF_Backend_Options_AJAX_Hooks(
|
||||
$tf_settings,
|
||||
new WPML_TF_Settings_Write(),
|
||||
new WPML_TF_Promote_Notices( $sitepress ),
|
||||
$_POST
|
||||
);
|
||||
}
|
||||
|
||||
return $hooks;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Options_Hooks_Factory
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Options_Hooks_Factory extends WPML_Current_Screen_Loader_Factory {
|
||||
|
||||
/** @return string */
|
||||
protected function get_screen_regex() {
|
||||
return '#' . WPML_PLUGIN_FOLDER . '/menu/languages#';
|
||||
}
|
||||
|
||||
/** @return null|WPML_TF_Backend_Options_Hooks */
|
||||
protected function create_hooks() {
|
||||
/** @var SitePress $sitepress */
|
||||
global $sitepress;
|
||||
|
||||
if ( $sitepress->is_setup_complete() ) {
|
||||
$template_loader = new WPML_Twig_Template_Loader(
|
||||
array( WPML_PLUGIN_PATH . WPML_TF_Backend_Options_View::TEMPLATE_FOLDER )
|
||||
);
|
||||
|
||||
$settings_read = new WPML_TF_Settings_Read();
|
||||
/** @var WPML_TF_Settings $tf_settings */
|
||||
$tf_settings = $settings_read->get( 'WPML_TF_Settings' );
|
||||
|
||||
$options_view = new WPML_TF_Backend_Options_View(
|
||||
$template_loader->get_template(),
|
||||
$tf_settings,
|
||||
$sitepress
|
||||
);
|
||||
|
||||
$translation_service = new WPML_TF_Translation_Service(
|
||||
class_exists( 'WPML_TP_Client_Factory' ) ? new WPML_TP_Client_Factory() : null
|
||||
);
|
||||
|
||||
return new WPML_TF_Backend_Options_Hooks(
|
||||
$options_view,
|
||||
new WPML_TF_Backend_Options_Scripts(),
|
||||
new WPML_TF_Backend_Options_Styles(),
|
||||
$translation_service
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Post_List_Hooks_Factory
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Post_List_Hooks_Factory extends WPML_Current_Screen_Loader_Factory {
|
||||
|
||||
/** @return string */
|
||||
protected function get_screen_regex() {
|
||||
return '/^edit$/';
|
||||
}
|
||||
|
||||
/** @return WPML_TF_Backend_Post_List_Hooks */
|
||||
protected function create_hooks() {
|
||||
global $wpdb, $sitepress;
|
||||
|
||||
$post_rating_metrics = new WPML_TF_Post_Rating_Metrics( $wpdb );
|
||||
$document_information = new WPML_TF_Document_Information( $sitepress );
|
||||
$backend_styles = new WPML_TF_Backend_Styles();
|
||||
|
||||
return new WPML_TF_Backend_Post_List_Hooks( $post_rating_metrics, $document_information, $backend_styles );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Promote_Hooks_Factory
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Promote_Hooks_Factory implements IWPML_Backend_Action_Loader, IWPML_Deferred_Action_Loader {
|
||||
|
||||
/** @return string */
|
||||
public function get_load_action() {
|
||||
return 'wpml_after_tm_loaded';
|
||||
}
|
||||
|
||||
public function create() {
|
||||
/** @var SitePress $sitepress */
|
||||
global $sitepress;
|
||||
|
||||
$hooks = null;
|
||||
|
||||
$settings_read = new WPML_TF_Settings_Read();
|
||||
/** @var WPML_TF_Settings $tf_settings */
|
||||
$tf_settings = $settings_read->get( 'WPML_TF_Settings' );
|
||||
|
||||
if ( ! $tf_settings->is_enabled() ) {
|
||||
$setup_complete = $sitepress->is_setup_complete();
|
||||
|
||||
$translation_service = new WPML_TF_Translation_Service(
|
||||
class_exists( 'WPML_TP_Client_Factory' ) ? new WPML_TP_Client_Factory() : null
|
||||
);
|
||||
|
||||
$hooks = new WPML_TF_Backend_Promote_Hooks(
|
||||
new WPML_TF_Promote_Notices( $sitepress ),
|
||||
$setup_complete,
|
||||
$translation_service
|
||||
);
|
||||
}
|
||||
|
||||
return $hooks;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Common_Hooks_Factory
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Common_Hooks_Factory implements IWPML_Backend_Action_Loader, IWPML_Frontend_Action_Loader {
|
||||
|
||||
/**
|
||||
* @return WPML_TF_Common_Hooks
|
||||
*/
|
||||
public function create() {
|
||||
$feedback_storage = new WPML_TF_Data_Object_Storage( new WPML_TF_Feedback_Post_Convert() );
|
||||
|
||||
return new WPML_TF_Common_Hooks( $feedback_storage );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,32 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Frontend_AJAX_Hooks_Factory
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Frontend_AJAX_Hooks_Factory extends WPML_AJAX_Base_Factory {
|
||||
|
||||
const AJAX_ACTION = 'wpml-tf-frontend-feedback';
|
||||
|
||||
/**
|
||||
* @return IWPML_Action|null
|
||||
*/
|
||||
public function create() {
|
||||
/** @var SitePress $sitepress */
|
||||
/** @var wpdb $wpdb */
|
||||
global $sitepress, $wpdb;
|
||||
|
||||
if ( $this->is_valid_action( self::AJAX_ACTION ) ) {
|
||||
return new WPML_TF_Frontend_AJAX_Hooks(
|
||||
new WPML_TF_Data_Object_Storage( new WPML_TF_Feedback_Post_Convert() ),
|
||||
new WPML_TF_Document_Information( $sitepress ),
|
||||
new WPML_TF_Post_Rating_Metrics( $wpdb ),
|
||||
class_exists( 'WPML_TP_Client_Factory' ) ? new WPML_TP_Client_Factory() : null,
|
||||
$_POST
|
||||
);
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,102 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Frontend_Hooks_Factory
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Frontend_Hooks_Factory implements IWPML_Frontend_Action_Loader, IWPML_Deferred_Action_Loader {
|
||||
|
||||
/** @var WPML_Queried_Object $queried_object */
|
||||
private $queried_object;
|
||||
|
||||
/** @var WPML_TF_Frontend_Display_Requirements $display_requirements */
|
||||
private $display_requirements;
|
||||
|
||||
/**
|
||||
* WPML_TF_Frontend_Hooks_Factory constructor.
|
||||
*
|
||||
* @param WPML_Queried_Object $queried_object
|
||||
* @param WPML_TF_Frontend_Display_Requirements $display_requirements
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_Queried_Object $queried_object = null,
|
||||
WPML_TF_Frontend_Display_Requirements $display_requirements = null
|
||||
) {
|
||||
$this->queried_object = $queried_object;
|
||||
$this->display_requirements = $display_requirements;
|
||||
}
|
||||
|
||||
/**
|
||||
* The frontend hooks must be loaded when the request has been parsed (in "wp")
|
||||
* to avoid unnecessary instantiation if the current page is not a translation
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_load_action() {
|
||||
return 'wp';
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|WPML_TF_Frontend_Hooks
|
||||
*/
|
||||
public function create() {
|
||||
global $sitepress;
|
||||
|
||||
$hooks = null;
|
||||
|
||||
if ( $this->get_display_requirements()->verify() ) {
|
||||
$template_loader = new WPML_Twig_Template_Loader(
|
||||
array( WPML_PLUGIN_PATH . WPML_TF_Frontend_Feedback_View::TEMPLATE_FOLDER )
|
||||
);
|
||||
|
||||
$template_service = $template_loader->get_template();
|
||||
|
||||
$settings_reader = new WPML_TF_Settings_Read();
|
||||
/** @var WPML_TF_Settings $settings */
|
||||
$settings = $settings_reader->get( 'WPML_TF_Settings' );
|
||||
|
||||
$frontend_feedback_form = new WPML_TF_Frontend_Feedback_View(
|
||||
$template_service,
|
||||
$sitepress,
|
||||
$this->get_queried_object(),
|
||||
$settings
|
||||
);
|
||||
|
||||
$hooks = new WPML_TF_Frontend_Hooks(
|
||||
$frontend_feedback_form,
|
||||
new WPML_TF_Frontend_Scripts(),
|
||||
new WPML_TF_Frontend_Styles()
|
||||
);
|
||||
}
|
||||
|
||||
return $hooks;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_Queried_Object
|
||||
*/
|
||||
private function get_queried_object() {
|
||||
global $sitepress;
|
||||
|
||||
if ( ! $this->queried_object ) {
|
||||
$this->queried_object = new WPML_Queried_Object( $sitepress );
|
||||
}
|
||||
|
||||
return $this->queried_object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_TF_Frontend_Display_Requirements
|
||||
*/
|
||||
private function get_display_requirements() {
|
||||
if ( ! $this->display_requirements ) {
|
||||
$settings_read = new WPML_TF_Settings_Read();
|
||||
$settings = $settings_read->get( 'WPML_TF_Settings' );
|
||||
/** @var WPML_TF_Settings $settings */
|
||||
$this->display_requirements = new WPML_TF_Frontend_Display_Requirements( $this->get_queried_object(), $settings );
|
||||
}
|
||||
|
||||
return $this->display_requirements;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Translation_Queue_Hooks_Factory
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Translation_Queue_Hooks_Factory extends WPML_Current_Screen_Loader_Factory {
|
||||
|
||||
/** @return string */
|
||||
protected function get_screen_regex() {
|
||||
return '/translations-queue/';
|
||||
}
|
||||
|
||||
/** @return WPML_TF_Translation_Queue_Hooks */
|
||||
protected function create_hooks() {
|
||||
$feedback_storage = new WPML_TF_Data_Object_Storage( new WPML_TF_Feedback_Post_Convert() );
|
||||
return new WPML_TF_Translation_Queue_Hooks( $feedback_storage );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Translation_Service_Change_Hooks_Factory
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Translation_Service_Change_Hooks_Factory implements IWPML_Backend_Action_Loader {
|
||||
|
||||
/** @return WPML_TF_Translation_Service_Change_Hooks */
|
||||
public function create() {
|
||||
return new WPML_TF_Translation_Service_Change_Hooks(
|
||||
new WPML_TF_Settings_Read(),
|
||||
new WPML_TF_Settings_Write(),
|
||||
new WPML_TF_TP_Ratings_Synchronize_Factory()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Common_Hooks_Factory
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_WP_Cron_Events_Factory implements IWPML_Backend_Action_Loader, IWPML_Frontend_Action_Loader {
|
||||
|
||||
/** @return WPML_TF_WP_Cron_Events */
|
||||
public function create() {
|
||||
return new WPML_TF_WP_Cron_Events(
|
||||
new WPML_TF_Settings_Read(),
|
||||
new WPML_TF_TP_Ratings_Synchronize_Factory()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,17 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_XML_RPC_Hooks_Factory
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_XML_RPC_Hooks_Factory implements IWPML_Frontend_Action_Loader {
|
||||
|
||||
/** @return WPML_TF_XML_RPC_Hooks */
|
||||
public function create() {
|
||||
return new WPML_TF_XML_RPC_Hooks(
|
||||
new WPML_TF_XML_RPC_Feedback_Update_Factory(),
|
||||
new WPML_WP_API()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TM_TF_AJAX_Feedback_List_Hooks_Factory
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TM_TF_AJAX_Feedback_List_Hooks_Factory implements IWPML_AJAX_Action_Loader {
|
||||
|
||||
/** @return WPML_TM_TF_Feedback_List_Hooks */
|
||||
public function create() {
|
||||
return new WPML_TM_TF_Feedback_List_Hooks();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TM_TF_Feedback_List_Hooks_Factory
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TM_TF_Feedback_List_Hooks_Factory extends WPML_Current_Screen_Loader_Factory {
|
||||
|
||||
/** @return string */
|
||||
public function get_screen_regex() {
|
||||
return '/wpml-translation-feedback-list/';
|
||||
}
|
||||
|
||||
/** @return WPML_TM_TF_Feedback_List_Hooks */
|
||||
public function create_hooks() {
|
||||
return new WPML_TM_TF_Feedback_List_Hooks();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Bulk_Actions_Factory
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Bulk_Actions_Factory {
|
||||
|
||||
/**
|
||||
* @return WPML_TF_Backend_Bulk_Actions
|
||||
*/
|
||||
public function create() {
|
||||
return new WPML_TF_Backend_Bulk_Actions(
|
||||
new WPML_TF_Data_Object_Storage( new WPML_TF_Feedback_Post_Convert() ),
|
||||
new WPML_WP_API(),
|
||||
new WPML_TF_Backend_Notices()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,33 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Feedback_List_View_Factory
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Feedback_List_View_Factory {
|
||||
|
||||
public function create() {
|
||||
/** @var SitePress $sitepress*/
|
||||
global $sitepress;
|
||||
|
||||
$template_loader = new WPML_Twig_Template_Loader(
|
||||
array( WPML_PLUGIN_PATH . WPML_TF_Backend_Feedback_List_View::TEMPLATE_FOLDER )
|
||||
);
|
||||
|
||||
$feedback_query = new WPML_TF_Feedback_Query(
|
||||
new WPML_TF_Data_Object_Storage( new WPML_TF_Feedback_Post_Convert() ),
|
||||
new WPML_TF_Data_Object_Storage( new WPML_TF_Message_Post_Convert() ),
|
||||
new WPML_TF_Collection_Filter_Factory()
|
||||
);
|
||||
|
||||
return new WPML_TF_Backend_Feedback_List_View(
|
||||
$template_loader->get_template(),
|
||||
$feedback_query,
|
||||
new WPML_Admin_Pagination(),
|
||||
new WPML_Admin_Table_Sort(),
|
||||
new WPML_TF_Feedback_Page_Filter( $sitepress, $feedback_query )
|
||||
);
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_TP_Ratings_Synchronize
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_TP_Ratings_Synchronize_Factory {
|
||||
|
||||
/**
|
||||
* @return WPML_TF_TP_Ratings_Synchronize
|
||||
*/
|
||||
public function create() {
|
||||
$tp_client_factory = new WPML_TP_Client_Factory();
|
||||
$tp_client = $tp_client_factory->create();
|
||||
|
||||
return new WPML_TF_TP_Ratings_Synchronize(
|
||||
new WPML_TF_Data_Object_Storage( new WPML_TF_Feedback_Post_Convert() ),
|
||||
$tp_client->ratings()
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,22 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_XML_RPC_Feedback_Update_Factory
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_XML_RPC_Feedback_Update_Factory {
|
||||
|
||||
/** @return WPML_TF_XML_RPC_Feedback_Update */
|
||||
public function create() {
|
||||
global $sitepress;
|
||||
|
||||
$translation_service = $sitepress->get_setting( 'translation_service' );
|
||||
$translation_projects = $sitepress->get_setting( 'icl_translation_projects' );
|
||||
$tp_project = new WPML_TP_Project( $translation_service, $translation_projects );
|
||||
|
||||
$feedback_storage = new WPML_TF_Data_Object_Storage( new WPML_TF_Feedback_Post_Convert() );
|
||||
|
||||
return new WPML_TF_XML_RPC_Feedback_Update( $feedback_storage, $tp_project );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_AJAX_Feedback_Edit_Hooks
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_AJAX_Feedback_Edit_Hooks implements IWPML_Action {
|
||||
|
||||
/** @var WPML_TF_Feedback_Edit $feedback_edit */
|
||||
private $feedback_edit;
|
||||
|
||||
/** @var WPML_TF_Backend_Feedback_Row_View $row_view */
|
||||
private $row_view;
|
||||
|
||||
/** @var array $post_data */
|
||||
private $post_data;
|
||||
|
||||
/**
|
||||
* WPML_TF_Backend_AJAX_Feedback_Edit_Hooks constructor.
|
||||
*
|
||||
* @param WPML_TF_Feedback_Edit $feedback_edit
|
||||
* @param WPML_TF_Backend_Feedback_Row_View $row_view
|
||||
* @param array $post_data
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_TF_Feedback_Edit $feedback_edit,
|
||||
WPML_TF_Backend_Feedback_Row_View $row_view,
|
||||
array $post_data
|
||||
) {
|
||||
$this->feedback_edit = $feedback_edit;
|
||||
$this->row_view = $row_view;
|
||||
$this->post_data = $post_data;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action(
|
||||
'wp_ajax_' . WPML_TF_Backend_AJAX_Feedback_Edit_Hooks_Factory::AJAX_ACTION,
|
||||
array( $this, 'edit_feedback_callback' )
|
||||
);
|
||||
}
|
||||
|
||||
public function edit_feedback_callback() {
|
||||
try {
|
||||
$this->check_post_data_key( 'feedback_id' );
|
||||
$feedback_id = filter_var( $this->post_data['feedback_id'], FILTER_SANITIZE_NUMBER_INT );
|
||||
$feedback = $this->feedback_edit->update( $feedback_id, $this->post_data );
|
||||
|
||||
if ( ! $feedback ) {
|
||||
throw new WPML_TF_AJAX_Exception( esc_html__( 'Failed to update the feedback.', 'sitepress' ) );
|
||||
}
|
||||
|
||||
$response = array(
|
||||
'summary_row' => $this->row_view->render_summary_row( $feedback ),
|
||||
'details_row' => $this->row_view->render_details_row( $feedback ),
|
||||
);
|
||||
|
||||
wp_send_json_success( $response );
|
||||
|
||||
} catch ( WPML_TF_AJAX_Exception $e ) {
|
||||
wp_send_json_error( $e->getMessage() );
|
||||
} catch ( WPML_TF_Feedback_Update_Exception $e ) {
|
||||
wp_send_json_error( $e->getMessage() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $key
|
||||
*
|
||||
* @throws WPML_TF_AJAX_Exception
|
||||
*/
|
||||
private function check_post_data_key( $key ) {
|
||||
if ( ! isset( $this->post_data[ $key ] ) ) {
|
||||
$message = sprintf(
|
||||
esc_html__( 'Missing key "%s".', 'sitepress' ),
|
||||
$key
|
||||
);
|
||||
|
||||
throw new WPML_TF_AJAX_Exception( $message );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,141 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Hooks
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Hooks implements IWPML_Action {
|
||||
|
||||
const PAGE_HOOK = 'wpml-translation-feedback-list';
|
||||
|
||||
/** @var WPML_TF_Backend_Bulk_Actions_Factory */
|
||||
private $bulk_actions_factory;
|
||||
|
||||
/** @var WPML_TF_Backend_Feedback_List_View_Factory feedback_list_view_factory */
|
||||
private $feedback_list_view_factory;
|
||||
|
||||
/** @var WPML_TF_Backend_Styles $backend_styles */
|
||||
private $backend_styles;
|
||||
|
||||
/** @var WPML_TF_Backend_Scripts */
|
||||
private $backend_scripts;
|
||||
|
||||
/** @var wpdb $wpdb */
|
||||
private $wpdb;
|
||||
|
||||
/**
|
||||
* WPML_TF_Backend_Hooks constructor.
|
||||
*
|
||||
* @param WPML_TF_Backend_Bulk_Actions_Factory $bulk_actions_factory
|
||||
* @param WPML_TF_Backend_Feedback_List_View_Factory $feedback_list_view_factory
|
||||
* @param WPML_TF_Backend_Styles $backend_styles
|
||||
* @param WPML_TF_Backend_Scripts $backend_scripts
|
||||
* @param wpdb $wpdb
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_TF_Backend_Bulk_Actions_Factory $bulk_actions_factory,
|
||||
WPML_TF_Backend_Feedback_List_View_Factory $feedback_list_view_factory,
|
||||
WPML_TF_Backend_Styles $backend_styles,
|
||||
WPML_TF_Backend_Scripts $backend_scripts,
|
||||
wpdb $wpdb
|
||||
) {
|
||||
$this->bulk_actions_factory = $bulk_actions_factory;
|
||||
$this->feedback_list_view_factory = $feedback_list_view_factory;
|
||||
$this->backend_styles = $backend_styles;
|
||||
$this->backend_scripts = $backend_scripts;
|
||||
$this->wpdb = $wpdb;
|
||||
}
|
||||
|
||||
/**
|
||||
* method add_hooks
|
||||
*/
|
||||
public function add_hooks() {
|
||||
add_action( 'wpml_admin_menu_configure', array( $this, 'add_translation_feedback_list_menu' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts_action' ) );
|
||||
add_action( 'current_screen', array( $this, 'bulk_actions_callback' ) );
|
||||
add_filter( 'posts_where', array( $this, 'maybe_exclude_rating_only_status' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Define translation feedback list menu and callback
|
||||
*
|
||||
* @param string $menu_id
|
||||
*/
|
||||
public function add_translation_feedback_list_menu( $menu_id ) {
|
||||
if ( 'WPML' !== $menu_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( current_user_can( 'manage_options' ) ) {
|
||||
$menu = array();
|
||||
$menu['order'] = 1200;
|
||||
$menu['page_title'] = __( 'Translation Feedback', 'sitepress' );
|
||||
$menu['menu_title'] = __( 'Translation Feedback', 'sitepress' );
|
||||
$menu['capability'] = 'manage_options';
|
||||
$menu['menu_slug'] = self::PAGE_HOOK;
|
||||
$menu['function'] = array( $this, 'translation_feedback_list_display' );
|
||||
|
||||
do_action( 'wpml_admin_menu_register_item', $menu );
|
||||
|
||||
} else {
|
||||
add_menu_page(
|
||||
__( 'Translation Feedback', 'sitepress' ),
|
||||
__( 'Translation Feedback', 'sitepress' ),
|
||||
'read',
|
||||
self::PAGE_HOOK,
|
||||
array( $this, 'translation_feedback_list_display' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Callback to display the feedback list page
|
||||
*/
|
||||
public function translation_feedback_list_display() {
|
||||
$view = $this->feedback_list_view_factory->create();
|
||||
echo $view->render_page();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $hook
|
||||
*/
|
||||
public function admin_enqueue_scripts_action( $hook ) {
|
||||
if ( $this->is_page_hook( $hook ) ) {
|
||||
$this->backend_styles->enqueue();
|
||||
$this->backend_scripts->enqueue();
|
||||
}
|
||||
}
|
||||
|
||||
public function bulk_actions_callback( $current_screen ) {
|
||||
$hook = isset( $current_screen->id ) ? $current_screen->id : null;
|
||||
|
||||
if ( $this->is_page_hook( $hook ) ) {
|
||||
$bulk_actions = $this->bulk_actions_factory->create();
|
||||
$bulk_actions->process();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $hook
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_page_hook( $hook ) {
|
||||
return strpos( $hook, self::PAGE_HOOK ) !== false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $where
|
||||
* @param WP_Query $query
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function maybe_exclude_rating_only_status( $where, $query ) {
|
||||
if ( isset( $query->query_vars['exclude_tf_rating_only'] ) && $query->query_vars['exclude_tf_rating_only'] ) {
|
||||
$where .= " AND {$this->wpdb->posts}.post_status <> 'rating_only'";
|
||||
}
|
||||
|
||||
return $where;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,94 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Options_AJAX_Hooks
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Options_AJAX_Hooks implements IWPML_Action {
|
||||
|
||||
/** @var WPML_TF_Settings $settings */
|
||||
private $settings;
|
||||
|
||||
/** @var WPML_TF_Settings_Write $settings_write */
|
||||
private $settings_write;
|
||||
|
||||
/** @var WPML_TF_Promote_Notices $promote_notices */
|
||||
private $promote_notices;
|
||||
|
||||
/** @var array $post_data */
|
||||
private $post_data;
|
||||
|
||||
/**
|
||||
* WPML_TF_Frontend_AJAX_Hooks constructor.
|
||||
*
|
||||
* @param WPML_TF_Settings $settings
|
||||
* @param WPML_TF_Settings_Write $settings_write
|
||||
* @param WPML_TF_Promote_Notices $promote_notices
|
||||
* @param array $post_data
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_TF_Settings $settings,
|
||||
WPML_TF_Settings_Write $settings_write,
|
||||
WPML_TF_Promote_Notices $promote_notices,
|
||||
array $post_data
|
||||
) {
|
||||
$this->settings = $settings;
|
||||
$this->settings_write = $settings_write;
|
||||
$this->promote_notices = $promote_notices;
|
||||
$this->post_data = $post_data;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action( 'wp_ajax_' . WPML_TF_Backend_Options_AJAX_Hooks_Factory::AJAX_ACTION, array( $this, 'save_settings_callback' ) );
|
||||
}
|
||||
|
||||
public function save_settings_callback() {
|
||||
$new_settings = array();
|
||||
|
||||
if ( isset( $this->post_data['settings'] ) ) {
|
||||
parse_str( $this->post_data['settings'], $new_settings );
|
||||
}
|
||||
|
||||
if ( isset( $new_settings['enabled'] ) ) {
|
||||
$this->settings->set_enabled( true );
|
||||
$this->promote_notices->remove();
|
||||
} else {
|
||||
$this->settings->set_enabled( false );
|
||||
}
|
||||
|
||||
if ( isset( $new_settings['button_mode'] ) ) {
|
||||
$this->settings->set_button_mode( $new_settings['button_mode'] );
|
||||
}
|
||||
|
||||
if ( isset( $new_settings['icon_style'] ) ) {
|
||||
$this->settings->set_icon_style( $new_settings['icon_style'] );
|
||||
}
|
||||
|
||||
if ( isset( $new_settings['languages_to'] ) ) {
|
||||
$this->settings->set_languages_to( $new_settings['languages_to'] );
|
||||
} else {
|
||||
$this->settings->set_languages_to( array() );
|
||||
}
|
||||
|
||||
if ( isset( $new_settings['display_mode'] ) ) {
|
||||
$this->settings->set_display_mode( $new_settings['display_mode'] );
|
||||
}
|
||||
|
||||
if ( isset( $new_settings['expiration_mode'] ) ) {
|
||||
$this->settings->set_expiration_mode( $new_settings['expiration_mode'] );
|
||||
}
|
||||
|
||||
if ( isset( $new_settings['expiration_delay_quantity'] ) ) {
|
||||
$this->settings->set_expiration_delay_quantity( $new_settings['expiration_delay_quantity'] );
|
||||
}
|
||||
|
||||
if ( isset( $new_settings['expiration_delay_unit'] ) ) {
|
||||
$this->settings->set_expiration_delay_unit( $new_settings['expiration_delay_unit'] );
|
||||
}
|
||||
|
||||
$this->settings_write->save( $this->settings );
|
||||
|
||||
wp_send_json_success( __( 'Settings saved', 'sitepress' ) );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,82 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Options_Hooks
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Options_Hooks implements IWPML_Action {
|
||||
|
||||
const WPML_LOVE_ID = '#lang-sec-10';
|
||||
|
||||
/** @var WPML_TF_Backend_Options_View $options_view */
|
||||
private $options_view;
|
||||
|
||||
/** @var WPML_TF_Backend_Options_Scripts $scripts */
|
||||
private $scripts;
|
||||
|
||||
/** @var WPML_TF_Backend_Options_Styles $styles */
|
||||
private $styles;
|
||||
|
||||
/** @var WPML_TF_Translation_Service $translation_service */
|
||||
private $translation_service;
|
||||
|
||||
/**
|
||||
* WPML_TF_Backend_Options_Hooks constructor.
|
||||
*
|
||||
* @param WPML_TF_Backend_Options_View $options_view
|
||||
* @param WPML_TF_Backend_Options_Scripts $scripts
|
||||
* @param WPML_TF_Backend_Options_Styles $styles
|
||||
* @param WPML_TF_Translation_Service $translation_service
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_TF_Backend_Options_View $options_view,
|
||||
WPML_TF_Backend_Options_Scripts $scripts,
|
||||
WPML_TF_Backend_Options_Styles $styles,
|
||||
WPML_TF_Translation_Service $translation_service
|
||||
) {
|
||||
$this->options_view = $options_view;
|
||||
$this->scripts = $scripts;
|
||||
$this->styles = $styles;
|
||||
$this->translation_service = $translation_service;
|
||||
}
|
||||
|
||||
/**
|
||||
* Method add_hooks
|
||||
*/
|
||||
public function add_hooks() {
|
||||
if ( $this->translation_service->allows_translation_feedback() ) {
|
||||
add_action( 'wpml_after_settings', array( $this, 'display_options_ui' ) );
|
||||
add_filter( 'wpml_admin_languages_navigation_items', array( $this, 'insert_navigation_item' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts_action' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Method to render the options UI
|
||||
*/
|
||||
public function display_options_ui() {
|
||||
echo $this->options_view->render();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $items
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function insert_navigation_item( $items ) {
|
||||
$insert_key_index = array_search( self::WPML_LOVE_ID, array_keys( $items ) );
|
||||
$insert_position = false === $insert_key_index ? count( $items ) : $insert_key_index + 1;
|
||||
|
||||
return array_merge(
|
||||
array_slice( $items, 0, $insert_position ),
|
||||
array( '#wpml-translation-feedback-options' => esc_html__( 'Translation Feedback', 'sitepress' ) ),
|
||||
array_slice( $items, $insert_position )
|
||||
);
|
||||
}
|
||||
|
||||
public function enqueue_scripts_action() {
|
||||
$this->scripts->enqueue();
|
||||
$this->styles->enqueue();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,116 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Post_List_Hooks
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Post_List_Hooks implements IWPML_Action {
|
||||
|
||||
const RATING_COLUMN_ID = 'translation_rating';
|
||||
|
||||
/** @var WPML_TF_Post_Rating_Metrics $post_rating_metrics*/
|
||||
private $post_rating_metrics;
|
||||
|
||||
/** @var WPML_TF_Document_Information $document_information */
|
||||
private $document_information;
|
||||
|
||||
/** @var WPML_TF_Backend_Styles $styles */
|
||||
private $styles;
|
||||
|
||||
public function __construct(
|
||||
WPML_TF_Post_Rating_Metrics $post_rating_metrics,
|
||||
WPML_TF_Document_Information $document_information,
|
||||
WPML_TF_Backend_Styles $styles
|
||||
) {
|
||||
$this->post_rating_metrics = $post_rating_metrics;
|
||||
$this->document_information = $document_information;
|
||||
$this->styles = $styles;
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
private function get_post_types() {
|
||||
return array(
|
||||
'edit-post' => 'posts',
|
||||
'edit-page' => 'pages',
|
||||
);
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
foreach ( $this->get_post_types() as $screen_id => $post_type ) {
|
||||
add_filter( 'manage_' . $post_type . '_columns' , array( $this, 'add_rating_column_header' ) );
|
||||
add_action( 'manage_' . $post_type . '_custom_column', array( $this, 'add_rating_column_content' ), 10, 2 );
|
||||
add_filter( 'manage_' . $screen_id .'_sortable_columns', array( $this, 'add_rating_sortable_column' ) );
|
||||
}
|
||||
|
||||
add_action( 'pre_get_posts', array( $this, 'order_posts_by_rating' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'admin_enqueue_scripts_action' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $columns
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_rating_column_header( array $columns ) {
|
||||
$key_to_insert_before = 'date';
|
||||
$column_name = __( 'Translation rating', 'sitepress' );
|
||||
|
||||
if ( array_key_exists( $key_to_insert_before, $columns ) ) {
|
||||
$insert_position = array_search( $key_to_insert_before, array_keys( $columns ) );
|
||||
$columns_before = array_slice( $columns, 0, $insert_position, true );
|
||||
$columns_to_insert = array( self::RATING_COLUMN_ID => $column_name );
|
||||
$columns_after = array_slice( $columns, $insert_position, null, true );
|
||||
$columns = array_merge( $columns_before, $columns_to_insert, $columns_after );
|
||||
} else {
|
||||
$columns[ self::RATING_COLUMN_ID ] = $column_name;
|
||||
}
|
||||
|
||||
return $columns;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $column_name
|
||||
* @param int $post_id
|
||||
*/
|
||||
public function add_rating_column_content( $column_name, $post_id ) {
|
||||
if ( self::RATING_COLUMN_ID !== $column_name ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$post_type = get_post_type( $post_id );
|
||||
$this->document_information->init( $post_id, 'post_' . $post_type );
|
||||
|
||||
if ( $this->document_information->get_source_language() ) {
|
||||
echo $this->post_rating_metrics->get_display( $post_id );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $columns
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_rating_sortable_column( array $columns ) {
|
||||
$columns[ self::RATING_COLUMN_ID ] = self::RATING_COLUMN_ID;
|
||||
return $columns;
|
||||
}
|
||||
|
||||
public function order_posts_by_rating( WP_Query $query ) {
|
||||
$orderby = $query->get( 'orderby');
|
||||
|
||||
if( self::RATING_COLUMN_ID === $orderby ) {
|
||||
$query->set( 'meta_key', WPML_TF_Post_Rating_Metrics::AVERAGE_KEY );
|
||||
$query->set( 'orderby', 'meta_value_num' );
|
||||
$query->set( 'meta_type', 'NUMERIC' );
|
||||
}
|
||||
}
|
||||
|
||||
public function admin_enqueue_scripts_action() {
|
||||
$current_screen = get_current_screen();
|
||||
|
||||
if ( isset( $current_screen->id ) && array_key_exists( $current_screen->id, $this->get_post_types() ) ) {
|
||||
$this->styles->enqueue();
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
use WPML\FP\Obj;
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Promote_Hooks
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Promote_Hooks implements IWPML_Action {
|
||||
/** @var WPML_TF_Promote_Notices $promote_notices */
|
||||
private $promote_notices;
|
||||
|
||||
/** @var WPML_TF_Translation_Service $translation_service */
|
||||
private $translation_service;
|
||||
|
||||
/** @var bool $is_setup_complete */
|
||||
private $is_setup_complete;
|
||||
|
||||
/**
|
||||
* WPML_TF_Backend_Promote_Hooks constructor.
|
||||
*
|
||||
* @param WPML_TF_Promote_Notices $promote_notices
|
||||
* @param bool $is_setup_complete
|
||||
* @param WPML_TF_Translation_Service $translation_service
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_TF_Promote_Notices $promote_notices,
|
||||
$is_setup_complete,
|
||||
WPML_TF_Translation_Service $translation_service
|
||||
) {
|
||||
$this->promote_notices = $promote_notices;
|
||||
$this->is_setup_complete = $is_setup_complete;
|
||||
$this->translation_service = $translation_service;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
if ( $this->translation_service->allows_translation_feedback() ) {
|
||||
if ( $this->is_setup_complete && get_option( WPML_Installation::WPML_START_VERSION_KEY ) ) {
|
||||
add_action(
|
||||
'wpml_pro_translation_completed',
|
||||
[ $this, 'add_notice_for_manager_on_job_completed' ],
|
||||
10, 3
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $new_post_id
|
||||
* @param array $fields
|
||||
* @param stdClass $job
|
||||
*/
|
||||
public function add_notice_for_manager_on_job_completed( $new_post_id, $fields, $job ) {
|
||||
if ( Obj::prop( 'translation_service', $job ) !== 'local' ) {
|
||||
$this->promote_notices->show_notice_for_new_site( (int) $job->manager_id );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Common_Hooks
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Common_Hooks implements IWPML_Action {
|
||||
|
||||
/** @var WPML_TF_Data_Object_Storage $feedback_storage */
|
||||
private $feedback_storage;
|
||||
|
||||
public function __construct( WPML_TF_Data_Object_Storage $feedback_storage ) {
|
||||
$this->feedback_storage = $feedback_storage;
|
||||
}
|
||||
|
||||
/**
|
||||
* method init
|
||||
*/
|
||||
public function add_hooks() {
|
||||
add_action( 'init', array( $this, 'init_action' ) );
|
||||
add_action( 'deleted_post', array( $this, 'cleanup_post_feedback_data' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* method init_action
|
||||
*/
|
||||
public function init_action() {
|
||||
register_post_type( WPML_TF_Feedback_Post_Convert::POST_TYPE );
|
||||
register_post_type( WPML_TF_Message_Post_Convert::POST_TYPE );
|
||||
}
|
||||
|
||||
/** @param int $post_id */
|
||||
public function cleanup_post_feedback_data( $post_id ) {
|
||||
if ( WPML_TF_Feedback_Post_Convert::POST_TYPE === get_post_type( $post_id ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$args = array(
|
||||
'post_id' => $post_id,
|
||||
);
|
||||
|
||||
$collection_filter = new WPML_TF_Feedback_Collection_Filter( $args );
|
||||
$feedback_collection = $this->feedback_storage->get_collection( $collection_filter );
|
||||
|
||||
foreach ( $feedback_collection as $feedback ) {
|
||||
$this->feedback_storage->delete( $feedback->get_id(), true );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,154 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Frontend_AJAX_Hooks
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Frontend_AJAX_Hooks implements IWPML_Action {
|
||||
|
||||
/** @var WPML_TF_Data_Object_Storage $feedback_storage */
|
||||
private $feedback_storage;
|
||||
|
||||
/** @var WPML_TF_Document_Information $document_information */
|
||||
private $document_information;
|
||||
|
||||
/** @var WPML_TF_Post_Rating_Metrics $post_rating_metrics */
|
||||
private $post_rating_metrics;
|
||||
|
||||
/** @var WPML_TP_Client_Factory $tp_client_factory */
|
||||
private $tp_client_factory;
|
||||
|
||||
/** @var WPML_TP_Client $tp_client */
|
||||
private $tp_client;
|
||||
|
||||
private $post_data;
|
||||
|
||||
/**
|
||||
* WPML_TF_Frontend_AJAX_Hooks constructor.
|
||||
*
|
||||
* @param WPML_TF_Data_Object_Storage $feedback_storage
|
||||
* @param WPML_TF_Document_Information $document_information
|
||||
* @param WPML_TF_Post_Rating_Metrics $post_rating_metrics
|
||||
* @param WPML_TP_Client_Factory|null $tp_client_factory
|
||||
* @param mixed[]|null $post_data
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_TF_Data_Object_Storage $feedback_storage,
|
||||
WPML_TF_Document_Information $document_information,
|
||||
WPML_TF_Post_Rating_Metrics $post_rating_metrics,
|
||||
WPML_TP_Client_Factory $tp_client_factory = null,
|
||||
array $post_data = null
|
||||
) {
|
||||
$this->feedback_storage = $feedback_storage;
|
||||
$this->document_information = $document_information;
|
||||
$this->post_rating_metrics = $post_rating_metrics;
|
||||
$this->tp_client_factory = $tp_client_factory;
|
||||
$this->post_data = $post_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* method init
|
||||
*/
|
||||
public function add_hooks() {
|
||||
add_action( 'wp_ajax_nopriv_' . WPML_TF_Frontend_AJAX_Hooks_Factory::AJAX_ACTION, array( $this, 'save_feedback_callback' ) );
|
||||
add_action( 'wp_ajax_' . WPML_TF_Frontend_AJAX_Hooks_Factory::AJAX_ACTION, array( $this, 'save_feedback_callback' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Method callback
|
||||
*/
|
||||
public function save_feedback_callback() {
|
||||
$feedback = null;
|
||||
|
||||
if ( isset( $this->post_data['feedback_id'] ) ) {
|
||||
$feedback = $this->update_feedback( $this->post_data['feedback_id'] );
|
||||
} elseif ( isset( $this->post_data['rating'], $this->post_data['document_id'], $this->post_data['document_type'] ) ) {
|
||||
$feedback = $this->create_feedback();
|
||||
}
|
||||
|
||||
if ( $feedback ) {
|
||||
$feedback_id = $this->feedback_storage->persist( $feedback );
|
||||
$this->post_rating_metrics->refresh( $feedback->get_document_id() );
|
||||
wp_send_json_success( array( 'feedback_id' => $feedback_id ) );
|
||||
} else {
|
||||
wp_send_json_error( esc_html__( 'Invalid request!', 'sitepress' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $feedback_id
|
||||
*
|
||||
* @return WPML_TF_Feedback|null|false
|
||||
*/
|
||||
private function update_feedback( $feedback_id ) {
|
||||
$feedback = $this->feedback_storage->get( $feedback_id );
|
||||
|
||||
if ( ! $feedback ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @var WPML_TF_Feedback $feedback */
|
||||
if ( isset( $this->post_data['content'] ) ) {
|
||||
$feedback->set_content( $this->post_data['content'] );
|
||||
}
|
||||
|
||||
if ( isset( $this->post_data['rating'] ) ) {
|
||||
$feedback->set_rating( $this->post_data['rating'] );
|
||||
}
|
||||
|
||||
$feedback->set_status( $this->get_filtered_status() );
|
||||
|
||||
return $feedback;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_TF_Feedback
|
||||
*/
|
||||
private function create_feedback() {
|
||||
$this->document_information->init( $this->post_data['document_id'], $this->post_data['document_type'] );
|
||||
|
||||
$args = array(
|
||||
'rating' => $this->post_data['rating'],
|
||||
'status' => $this->get_filtered_status(),
|
||||
'document_id' => $this->post_data['document_id'],
|
||||
'document_type' => $this->post_data['document_type'],
|
||||
'language_from' => $this->document_information->get_source_language(),
|
||||
'language_to' => $this->document_information->get_language(),
|
||||
'job_id' => $this->document_information->get_job_id(),
|
||||
);
|
||||
|
||||
if ( $this->document_information->is_local_translation( $args['job_id'] ) ) {
|
||||
$args['tp_rating_id'] = 0;
|
||||
} elseif ( $this->get_tp_client() ) {
|
||||
$active_service = $this->get_tp_client()->services()->get_active();
|
||||
|
||||
if ( isset( $active_service->feedback_forward_method ) ) {
|
||||
$args['feedback_forward_method'] = $active_service->feedback_forward_method;
|
||||
}
|
||||
}
|
||||
|
||||
return new WPML_TF_Feedback( $args );
|
||||
}
|
||||
|
||||
/** @return string */
|
||||
private function get_filtered_status() {
|
||||
$rating = isset( $this->post_data['rating'] ) ? $this->post_data['rating'] : null;
|
||||
$status = 'pending';
|
||||
|
||||
if ( 3 < (int) $rating || empty( $this->post_data['content'] ) ) {
|
||||
$status = 'rating_only';
|
||||
}
|
||||
|
||||
return $status;
|
||||
}
|
||||
|
||||
/** @return null|WPML_TP_Client */
|
||||
private function get_tp_client() {
|
||||
if ( $this->tp_client_factory && ! $this->tp_client ) {
|
||||
$this->tp_client = $this->tp_client_factory->create();
|
||||
}
|
||||
|
||||
return $this->tp_client;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,65 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Frontend_Hooks
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Frontend_Hooks implements IWPML_Action {
|
||||
|
||||
/** @var WPML_TF_Frontend_Feedback_View $feedback_view */
|
||||
private $feedback_view;
|
||||
|
||||
/** @var WPML_TF_Frontend_Scripts $scripts */
|
||||
private $scripts;
|
||||
|
||||
/** @var WPML_TF_Frontend_Styles $styles */
|
||||
private $styles;
|
||||
|
||||
/**
|
||||
* WPML_TF_Frontend_Hooks constructor.
|
||||
*
|
||||
* @param WPML_TF_Frontend_Feedback_View $feedback_view
|
||||
* @param WPML_TF_Frontend_Scripts $scripts
|
||||
* @param WPML_TF_Frontend_Styles $styles
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_TF_Frontend_Feedback_View $feedback_view,
|
||||
WPML_TF_Frontend_Scripts $scripts,
|
||||
WPML_TF_Frontend_Styles $styles
|
||||
) {
|
||||
$this->feedback_view = $feedback_view;
|
||||
$this->scripts = $scripts;
|
||||
$this->styles = $styles;
|
||||
}
|
||||
|
||||
/**
|
||||
* method init
|
||||
*/
|
||||
public function add_hooks() {
|
||||
add_action( 'wp_enqueue_scripts', array( $this, 'enqueue_scripts_action' ) );
|
||||
add_action( 'wp_footer', array( $this, 'render_feedback_form' ) );
|
||||
add_action( 'wpml_tf_feedback_open_link', array( $this, 'render_custom_form_open_link' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* method enqueue_scripts_action
|
||||
*/
|
||||
public function enqueue_scripts_action() {
|
||||
$this->scripts->enqueue();
|
||||
$this->styles->enqueue();
|
||||
}
|
||||
|
||||
/**
|
||||
* method render_feedback_form
|
||||
*/
|
||||
public function render_feedback_form() {
|
||||
echo $this->feedback_view->render_open_button();
|
||||
echo $this->feedback_view->render_form();
|
||||
}
|
||||
|
||||
/** @param string|array $args */
|
||||
public function render_custom_form_open_link( $args ) {
|
||||
echo $this->feedback_view->render_custom_open_link( $args );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,49 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Translation_Queue_Hooks
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Translation_Queue_Hooks implements IWPML_Action {
|
||||
|
||||
/** @var WPML_TF_Data_Object_Storage $feedback_storage */
|
||||
private $feedback_storage;
|
||||
|
||||
public function __construct( WPML_TF_Data_Object_Storage $feedback_storage ) {
|
||||
$this->feedback_storage = $feedback_storage;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_filter( 'wpml_tm_allowed_translators_for_job', array( $this, 'add_reviewer_to_allowed_translators' ), 10, 2 );
|
||||
}
|
||||
|
||||
public function add_reviewer_to_allowed_translators(
|
||||
array $allowed_translators,
|
||||
WPML_Translation_Job $translation_job
|
||||
) {
|
||||
$current_user_id = get_current_user_id();
|
||||
|
||||
if ( $translation_job->get_translator_id() !== $current_user_id ) {
|
||||
|
||||
$filter_args = array(
|
||||
'reviewer_id' => $current_user_id,
|
||||
);
|
||||
|
||||
$collection_filter = new WPML_TF_Feedback_Collection_Filter( $filter_args );
|
||||
$feedback_collection = $this->feedback_storage->get_collection( $collection_filter );
|
||||
|
||||
foreach ( $feedback_collection as $feedback ) {
|
||||
/** @var WPML_TF_Feedback $feedback */
|
||||
if ( $feedback->get_job_id() === (int) $translation_job->get_id()
|
||||
&& 'fixed' !== $feedback->get_status()
|
||||
) {
|
||||
$allowed_translators[] = $current_user_id;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return $allowed_translators;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Translation_Service_Change_Hooks
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Translation_Service_Change_Hooks implements IWPML_Action {
|
||||
|
||||
/** @var WPML_TF_Settings_Read $settings_read */
|
||||
private $settings_read;
|
||||
|
||||
/** @var WPML_TF_Settings_Write $settings_write */
|
||||
private $settings_write;
|
||||
|
||||
/** @var WPML_TF_TP_Ratings_Synchronize_Factory $tp_ratings_synchronize_factory */
|
||||
private $tp_ratings_synchronize_factory;
|
||||
|
||||
public function __construct(
|
||||
WPML_TF_Settings_Read $settings_read,
|
||||
WPML_TF_Settings_Write $settings_write,
|
||||
WPML_TF_TP_Ratings_Synchronize_Factory $tp_ratings_synchronize_factory
|
||||
) {
|
||||
$this->settings_read = $settings_read;
|
||||
$this->settings_write = $settings_write;
|
||||
$this->tp_ratings_synchronize_factory = $tp_ratings_synchronize_factory;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
add_action(
|
||||
'wpml_tm_before_set_translation_service',
|
||||
array( $this, 'before_set_translation_service_callback' )
|
||||
);
|
||||
}
|
||||
|
||||
public function before_set_translation_service_callback( stdClass $service ) {
|
||||
$this->cleanup_pending_ratings_queue();
|
||||
$this->disable_tf_if_not_allowed_by_ts( $service );
|
||||
}
|
||||
|
||||
private function cleanup_pending_ratings_queue() {
|
||||
$tp_ratings_sync = $this->tp_ratings_synchronize_factory->create();
|
||||
$tp_ratings_sync->run( true );
|
||||
}
|
||||
|
||||
private function disable_tf_if_not_allowed_by_ts( stdClass $service ) {
|
||||
if ( isset( $service->translation_feedback ) && ! $service->translation_feedback ) {
|
||||
/** @var WPML_TF_Settings $settings */
|
||||
$settings = $this->settings_read->get( 'WPML_TF_Settings' );
|
||||
$settings->set_enabled( false );
|
||||
$this->settings_write->save( $settings );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,45 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_XML_RPC_Hooks
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_XML_RPC_Hooks implements IWPML_Action {
|
||||
|
||||
/** @var WPML_TF_XML_RPC_Feedback_Update_Factory $xml_rpc_feedback_update_factory */
|
||||
private $xml_rpc_feedback_update_factory;
|
||||
|
||||
/** @var WPML_WP_API $wp_api */
|
||||
private $wp_api;
|
||||
|
||||
public function __construct(
|
||||
WPML_TF_XML_RPC_Feedback_Update_Factory $xml_rpc_feedback_update_factory,
|
||||
WPML_WP_API $wp_api
|
||||
) {
|
||||
$this->xml_rpc_feedback_update_factory = $xml_rpc_feedback_update_factory;
|
||||
$this->wp_api = $wp_api;
|
||||
}
|
||||
|
||||
public function add_hooks() {
|
||||
if ( $this->wp_api->constant( 'XMLRPC_REQUEST' ) ) {
|
||||
add_filter( 'xmlrpc_methods', array( $this, 'add_tf_xmlrpc_methods' ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $methods
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function add_tf_xmlrpc_methods( $methods ) {
|
||||
$methods['translationproxy.update_feedback_status'] = array( $this, 'update_feedback_status' );
|
||||
return $methods;
|
||||
}
|
||||
|
||||
/** @param array $args */
|
||||
public function update_feedback_status( array $args ) {
|
||||
$xml_rpc_feedback_update = $this->xml_rpc_feedback_update_factory->create();
|
||||
$xml_rpc_feedback_update->set_status( $args );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TM_TF_Feedback_List_Hooks
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TM_TF_Feedback_List_Hooks implements IWPML_Action {
|
||||
|
||||
public function add_hooks() {
|
||||
add_filter( 'wpml_use_tm_editor', array( $this, 'maybe_force_to_use_translation_editor' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int|bool $use_translation_editor
|
||||
*
|
||||
* @return int|bool
|
||||
*/
|
||||
public function maybe_force_to_use_translation_editor( $use_translation_editor ) {
|
||||
if ( ! current_user_can( 'edit_others_posts' ) ) {
|
||||
$use_translation_editor = true;
|
||||
}
|
||||
|
||||
return $use_translation_editor;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,183 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Feedback_Collection_Filter
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Feedback_Collection_Filter implements IWPML_TF_Collection_Filter {
|
||||
|
||||
/** @var bool $exclude_rating_only */
|
||||
private $exclude_rating_only;
|
||||
|
||||
/** @var array $language_pairs */
|
||||
private $language_pairs;
|
||||
|
||||
/** @var int $pending_tp_ratings */
|
||||
private $pending_tp_ratings;
|
||||
|
||||
/** @var int tp_feedback_id */
|
||||
private $tp_feedback_id;
|
||||
|
||||
/** @var int $post_id */
|
||||
private $post_id;
|
||||
|
||||
/** @var int $reviewer_id */
|
||||
private $reviewer_id;
|
||||
|
||||
/**
|
||||
* WPML_TF_Feedback_Collection_Filter constructor.
|
||||
*
|
||||
* @param array $args
|
||||
*/
|
||||
public function __construct( array $args ) {
|
||||
if ( isset( $args['exclude_rating_only'] ) ) {
|
||||
$this->exclude_rating_only = $args['exclude_rating_only'];
|
||||
}
|
||||
|
||||
if ( isset( $args['language_pairs'] ) ) {
|
||||
$this->language_pairs = $args['language_pairs'];
|
||||
}
|
||||
|
||||
if ( isset( $args['pending_tp_ratings'] ) ) {
|
||||
$this->pending_tp_ratings = (int) $args['pending_tp_ratings'];
|
||||
}
|
||||
|
||||
if ( isset( $args['tp_feedback_id'] ) ) {
|
||||
$this->tp_feedback_id = (int) $args['tp_feedback_id'];
|
||||
}
|
||||
|
||||
if ( isset( $args['post_id'] ) ) {
|
||||
$this->post_id = (int) $args['post_id'];
|
||||
}
|
||||
|
||||
if ( isset( $args['reviewer_id'] ) ) {
|
||||
$this->reviewer_id = (int) $args['reviewer_id'];
|
||||
}
|
||||
}
|
||||
|
||||
/** @return null|bool */
|
||||
private function get_exclude_rating_only() {
|
||||
return $this->exclude_rating_only;
|
||||
}
|
||||
|
||||
/** @return null|array */
|
||||
private function get_language_pairs() {
|
||||
return $this->language_pairs;
|
||||
}
|
||||
|
||||
/** @return null|int */
|
||||
private function get_pending_tp_ratings() {
|
||||
return $this->pending_tp_ratings;
|
||||
}
|
||||
|
||||
/** @return null|int */
|
||||
private function get_tp_feedback_id() {
|
||||
return $this->tp_feedback_id;
|
||||
}
|
||||
|
||||
/** @return null|int */
|
||||
private function get_reviewer_id() {
|
||||
return $this->reviewer_id;
|
||||
}
|
||||
|
||||
/** @return null|int */
|
||||
private function get_post_id() {
|
||||
return $this->post_id;
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
public function get_posts_args() {
|
||||
$args = array(
|
||||
'posts_per_page' => -1,
|
||||
'post_type' => WPML_TF_Feedback_Post_Convert::POST_TYPE,
|
||||
'suppress_filters' => false,
|
||||
'post_status' => array( 'any', 'trash' ),
|
||||
);
|
||||
|
||||
if ( $this->get_exclude_rating_only() ) {
|
||||
$args['exclude_tf_rating_only'] = true;
|
||||
}
|
||||
|
||||
if ( is_array( $this->get_language_pairs() ) ) {
|
||||
|
||||
$meta_query = array(
|
||||
'relation' => 'OR',
|
||||
);
|
||||
|
||||
foreach ( $this->get_language_pairs() as $from => $targets ) {
|
||||
|
||||
foreach ( $targets as $to => $value ) {
|
||||
|
||||
$meta_query[] = array(
|
||||
'relation' => 'AND',
|
||||
array(
|
||||
'key' => WPML_TF_Data_Object_Storage::META_PREFIX . 'language_from',
|
||||
'value' => $from,
|
||||
'compare' => '=',
|
||||
),
|
||||
array(
|
||||
'key' => WPML_TF_Data_Object_Storage::META_PREFIX . 'language_to',
|
||||
'value' => $to,
|
||||
'compare' => '=',
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
$args['meta_query'] = $meta_query;
|
||||
|
||||
} elseif ( $this->get_pending_tp_ratings() ) {
|
||||
$args['posts_per_page'] = $this->get_pending_tp_ratings();
|
||||
$args['orderby'] = 'ID';
|
||||
$args['order'] = 'ASC';
|
||||
$args['meta_query'] = array(
|
||||
array(
|
||||
'key' => WPML_TF_Data_Object_Storage::META_PREFIX . 'tp_rating_id',
|
||||
'value' => '',
|
||||
'compare' => '=',
|
||||
'type' => 'CHAR',
|
||||
),
|
||||
);
|
||||
} elseif ( $this->get_tp_feedback_id() ) {
|
||||
$args['posts_per_page'] = 1;
|
||||
$args['meta_query'] = array(
|
||||
array(
|
||||
'key' => WPML_TF_Data_Object_Storage::META_PREFIX . 'tp_feedback_id',
|
||||
'value' => $this->get_tp_feedback_id(),
|
||||
'compare' => '=',
|
||||
),
|
||||
);
|
||||
|
||||
} elseif ( $this->get_post_id() ) {
|
||||
$args['meta_query'] = array(
|
||||
'relation' => 'AND',
|
||||
array(
|
||||
'key' => WPML_TF_Data_Object_Storage::META_PREFIX . 'document_id',
|
||||
'value' => $this->get_post_id(),
|
||||
'compare' => '=',
|
||||
),
|
||||
array(
|
||||
'key' => WPML_TF_Data_Object_Storage::META_PREFIX . 'document_type',
|
||||
'value' => 'post_' . get_post_type( $this->get_post_id() ),
|
||||
'compare' => '=',
|
||||
),
|
||||
);
|
||||
} elseif ( $this->get_reviewer_id() ) {
|
||||
$args['meta_query'] = array(
|
||||
array(
|
||||
'key' => WPML_TF_Data_Object_Storage::META_PREFIX . 'reviewer_id',
|
||||
'value' => $this->get_reviewer_id(),
|
||||
'compare' => '=',
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/** @return WPML_TF_Feedback_Collection */
|
||||
public function get_new_collection() {
|
||||
return new WPML_TF_Feedback_Collection();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,240 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Feedback_Collection
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Feedback_Collection extends WPML_TF_Collection {
|
||||
|
||||
private $order;
|
||||
private $filter_value;
|
||||
|
||||
/**
|
||||
* @param int $offset
|
||||
* @param int $length
|
||||
*/
|
||||
public function reduce_collection( $offset, $length ) {
|
||||
$this->collection = array_slice( $this->collection, $offset, $length, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property
|
||||
* @param string $order
|
||||
*/
|
||||
public function sort_collection( $property, $order ) {
|
||||
$this->order = $order;
|
||||
$method = 'compare_by_' . $property;
|
||||
|
||||
if ( method_exists( $this, $method ) ) {
|
||||
// Use @ to avoid warnings in unit tests => see bug https://bugs.php.net/bug.php?id=50688
|
||||
@uasort( $this->collection, array( $this, $method ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Feedback $a
|
||||
* @param WPML_TF_Feedback $b
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function compare_by_pending( WPML_TF_Feedback $a, WPML_TF_Feedback $b ) {
|
||||
if ( $a->is_pending() && ! $b->is_pending() ) {
|
||||
$compare = -1;
|
||||
} elseif ( ! $a->is_pending() && $b->is_pending() ) {
|
||||
$compare = 1;
|
||||
} else {
|
||||
$compare = $this->compare_by_id( $a, $b );
|
||||
}
|
||||
|
||||
return $compare;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Feedback $a
|
||||
* @param WPML_TF_Feedback $b
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function compare_by_feedback( WPML_TF_Feedback $a, WPML_TF_Feedback $b ) {
|
||||
if ( 'asc' === $this->order ) {
|
||||
$compare = strcasecmp( $a->get_content(), $b->get_content() );
|
||||
} else {
|
||||
$compare = strcasecmp( $b->get_content(), $a->get_content() );
|
||||
}
|
||||
|
||||
if ( 0 === $compare ) {
|
||||
$compare = $this->compare_by_id( $a, $b );
|
||||
}
|
||||
|
||||
return $compare;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Feedback $a
|
||||
* @param WPML_TF_Feedback $b
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function compare_by_rating( WPML_TF_Feedback $a, WPML_TF_Feedback $b ) {
|
||||
if ( 'asc' === $this->order ) {
|
||||
$compare = $a->get_rating() - $b->get_rating();
|
||||
} else {
|
||||
$compare = $b->get_rating() - $a->get_rating();
|
||||
}
|
||||
|
||||
if ( 0 === $compare ) {
|
||||
$compare = $this->compare_by_id( $a, $b );
|
||||
}
|
||||
|
||||
return $compare;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Feedback $a
|
||||
* @param WPML_TF_Feedback $b
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function compare_by_status( WPML_TF_Feedback $a, WPML_TF_Feedback $b ) {
|
||||
if ( 'asc' === $this->order ) {
|
||||
$compare = strcmp( $a->get_text_status(), $b->get_text_status() );
|
||||
} else {
|
||||
$compare = strcmp( $b->get_text_status(), $a->get_text_status() );
|
||||
}
|
||||
|
||||
if ( 0 === $compare ) {
|
||||
$compare = $this->compare_by_id( $a, $b );
|
||||
}
|
||||
|
||||
return $compare;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Feedback $a
|
||||
* @param WPML_TF_Feedback $b
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function compare_by_document_title( WPML_TF_Feedback $a, WPML_TF_Feedback $b ) {
|
||||
if ( 'asc' === $this->order ) {
|
||||
$compare = strcasecmp( $a->get_document_information()->get_title(), $b->get_document_information()->get_title() );
|
||||
} else {
|
||||
$compare = strcasecmp( $b->get_document_information()->get_title(), $a->get_document_information()->get_title() );
|
||||
}
|
||||
|
||||
if ( 0 === $compare ) {
|
||||
$compare = $this->compare_by_id( $a, $b );
|
||||
}
|
||||
|
||||
return $compare;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Feedback $a
|
||||
* @param WPML_TF_Feedback $b
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
private function compare_by_date( WPML_TF_Feedback $a, WPML_TF_Feedback $b ) {
|
||||
if ( 'asc' === $this->order ) {
|
||||
$compare = strtotime( $a->get_date_created() ) - strtotime( $b->get_date_created() );
|
||||
} else {
|
||||
$compare = strtotime( $b->get_date_created() ) - strtotime( $a->get_date_created() );
|
||||
}
|
||||
|
||||
if ( 0 === $compare ) {
|
||||
$compare = $this->compare_by_id( $a, $b );
|
||||
}
|
||||
|
||||
return $compare;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Feedback $a
|
||||
* @param WPML_TF_Feedback $b
|
||||
*
|
||||
* @return int
|
||||
*/
|
||||
private function compare_by_id( WPML_TF_Feedback $a, WPML_TF_Feedback $b ) {
|
||||
if ( 'asc' === $this->order ) {
|
||||
return $a->get_id() - $b->get_id();
|
||||
} else {
|
||||
return $b->get_id() - $a->get_id();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Message_Collection $message_collection
|
||||
*/
|
||||
public function link_messages_to_feedback( WPML_TF_Message_Collection $message_collection ) {
|
||||
foreach ( $message_collection as $message ) {
|
||||
if ( array_key_exists( $message->get_feedback_id(), $this->collection ) ) {
|
||||
$this->collection[ $message->get_feedback_id() ]->add_message( $message );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $property
|
||||
* @param string $value
|
||||
*/
|
||||
public function filter_by( $property, $value ) {
|
||||
$this->filter_value = $value;
|
||||
$method = 'filter_by_' . $property;
|
||||
|
||||
if ( method_exists( $this, $method ) ) {
|
||||
$this->collection = array_filter( $this->collection, array( $this, $method ) );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Feedback $feedback
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function filter_by_status( WPML_TF_Feedback $feedback ) {
|
||||
if ( $feedback->get_status() === $this->filter_value ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Feedback $feedback
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function filter_by_language( WPML_TF_Feedback $feedback ) {
|
||||
if ( $feedback->get_language_to() === $this->filter_value ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Feedback $feedback
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function filter_by_post_id( WPML_TF_Feedback $feedback ) {
|
||||
if ( 0 === strpos( $feedback->get_document_type(), 'post_' )
|
||||
&& $feedback->get_document_id() === (int) $this->filter_value
|
||||
) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
public function remove_trashed() {
|
||||
foreach ( $this->collection as $id => $feedback ) {
|
||||
/** @var WPML_TF_Feedback $feedback */
|
||||
if ( 'trash' === $feedback->get_status() ) {
|
||||
unset( $this->collection[ $id ] );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,25 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Feedback_Factory
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Feedback_Factory {
|
||||
|
||||
/**
|
||||
* @param array $feedback_data
|
||||
*
|
||||
* @return WPML_TF_Feedback
|
||||
*/
|
||||
public function create( array $feedback_data ) {
|
||||
global $sitepress;
|
||||
|
||||
$document_information = new WPML_TF_Backend_Document_Information(
|
||||
$sitepress,
|
||||
class_exists( 'WPML_TP_Client_Factory' ) ? new WPML_TP_Client_Factory() : null
|
||||
);
|
||||
|
||||
return new WPML_TF_Feedback( $feedback_data, $document_information );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,88 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Feedback_Post_Convert
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Feedback_Post_Convert extends WPML_TF_Data_Object_Post_Convert {
|
||||
|
||||
const POST_TYPE = 'wpml_tf_feedback';
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_post_fields() {
|
||||
return array(
|
||||
'id' => 'ID',
|
||||
'date_created' => 'post_date',
|
||||
'content' => 'post_content',
|
||||
'status' => 'post_status',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_meta_fields() {
|
||||
return array(
|
||||
'rating',
|
||||
'document_id',
|
||||
'document_type',
|
||||
'language_from',
|
||||
'language_to',
|
||||
'job_id',
|
||||
'reviewer_id',
|
||||
'tp_rating_id',
|
||||
'tp_feedback_id',
|
||||
'feedback_forward_method'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IWPML_TF_Data_Object $feedback
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function to_post_data( IWPML_TF_Data_Object $feedback ) {
|
||||
if( ! $feedback instanceof WPML_TF_Feedback ) {
|
||||
throw new Exception( 'The $feedback argument must be an instance of WPML_TF_Feedback' );
|
||||
}
|
||||
|
||||
/** @var WPML_TF_Feedback $feedback */
|
||||
$post = new stdClass();
|
||||
$post->ID = $feedback->get_id();
|
||||
$post->post_date = $feedback->get_date_created();
|
||||
$post->post_content = $feedback->get_content();
|
||||
$post->post_status = $feedback->get_status();
|
||||
$post->post_type = self::POST_TYPE;
|
||||
|
||||
return array(
|
||||
'post' => $post,
|
||||
'metadata' => array(
|
||||
'rating' => $feedback->get_rating(),
|
||||
'document_id' => $feedback->get_document_id(),
|
||||
'document_type' => $feedback->get_document_type(),
|
||||
'language_from' => $feedback->get_language_from(),
|
||||
'language_to' => $feedback->get_language_to(),
|
||||
'job_id' => $feedback->get_job_id(),
|
||||
'reviewer_id' => $feedback->get_reviewer()->get_id(),
|
||||
'tp_rating_id' => $feedback->get_tp_responses()->get_rating_id(),
|
||||
'tp_feedback_id' => $feedback->get_tp_responses()->get_feedback_id(),
|
||||
'feedback_forward_method' => $feedback->get_tp_responses()->get_feedback_forward_method(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $post_data
|
||||
*
|
||||
* @return WPML_TF_Feedback
|
||||
*/
|
||||
public function to_object( array $post_data ) {
|
||||
$feedback_data = $this->build_object_data_for_constructor( $post_data );
|
||||
$feedback_factory = new WPML_TF_Feedback_Factory();
|
||||
return $feedback_factory->create( $feedback_data );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,41 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Feedback_Reviewer {
|
||||
|
||||
/** @var int $id WP_User ID */
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* WPML_TF_Feedback_Reviewer constructor.
|
||||
*
|
||||
* @param int $id
|
||||
*/
|
||||
public function __construct( $id ) {
|
||||
$this->id = (int) $id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|null
|
||||
*/
|
||||
public function get_id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_reviewer_display_name() {
|
||||
$display_name = __( 'Unknown reviewer', 'sitepress' );
|
||||
|
||||
$reviewer = get_user_by( 'id', $this->get_id() );
|
||||
|
||||
if ( isset( $reviewer->display_name ) ) {
|
||||
$display_name = $reviewer->display_name;
|
||||
}
|
||||
|
||||
return $display_name;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,138 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Feedback_Status
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Feedback_Status {
|
||||
|
||||
/** @var string $status */
|
||||
private $status = 'pending';
|
||||
|
||||
/**
|
||||
* WPML_TF_Feedback_Status constructor.
|
||||
*
|
||||
* @param string $status
|
||||
*/
|
||||
public function __construct( $status = null ) {
|
||||
if ( $status ) {
|
||||
$this->set_value( $status );
|
||||
}
|
||||
}
|
||||
|
||||
/** @param string $status*/
|
||||
public function set_value( $status ) {
|
||||
$this->status = sanitize_text_field( $status );
|
||||
}
|
||||
|
||||
/** @return string */
|
||||
public function get_value() {
|
||||
return $this->status;
|
||||
}
|
||||
|
||||
/** @return null|string */
|
||||
public function get_display_text() {
|
||||
switch ( $this->get_value() ) {
|
||||
case 'pending':
|
||||
return __( 'New', 'sitepress' );
|
||||
|
||||
case 'sent_to_translator':
|
||||
if ( $this->is_admin_user() ) {
|
||||
return __( 'Sent to translator', 'sitepress' );
|
||||
}
|
||||
|
||||
return __( 'New', 'sitepress' );
|
||||
|
||||
case 'translator_replied':
|
||||
if ( $this->is_admin_user() ) {
|
||||
return __( 'Translator replied', 'sitepress' );
|
||||
}
|
||||
|
||||
return __( 'Replied', 'sitepress' );
|
||||
|
||||
case 'admin_replied':
|
||||
if ( $this->is_admin_user() ) {
|
||||
return __( 'Sent to translator', 'sitepress' );
|
||||
}
|
||||
|
||||
return __( 'Admin replied', 'sitepress' );
|
||||
|
||||
case 'sent_to_ts_api':
|
||||
case 'sent_to_ts_manual':
|
||||
return __( 'Sent to translation service', 'sitepress' );
|
||||
|
||||
case 'sent_to_ts_email':
|
||||
return __( 'E-mail sent to translation service', 'sitepress' );
|
||||
|
||||
case 'fixed':
|
||||
return __( 'Translation fixed', 'sitepress' );
|
||||
|
||||
case 'publish':
|
||||
return __( 'Approved', 'sitepress' );
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @return bool */
|
||||
private function is_admin_user() {
|
||||
return current_user_can( 'manage_options' );
|
||||
}
|
||||
|
||||
/**
|
||||
* This is used by the blue button on the feedback list
|
||||
*
|
||||
* @return array|null
|
||||
*/
|
||||
public function get_next_status() {
|
||||
if ( $this->is_admin_user() ) {
|
||||
switch ( $this->get_value() ) {
|
||||
case 'pending':
|
||||
case 'sent_to_translator':
|
||||
return array(
|
||||
'value' => 'sent_to_translator',
|
||||
'label' => __( 'Send to translator', 'sitepress' ),
|
||||
);
|
||||
|
||||
case 'translator_replied':
|
||||
return array(
|
||||
'value' => 'admin_replied',
|
||||
'label' => __( 'Reply to translator', 'sitepress' ),
|
||||
);
|
||||
|
||||
case 'admin_replied':
|
||||
return array(
|
||||
'value' => 'admin_replied',
|
||||
'label' => __( 'Send to translator', 'sitepress' ),
|
||||
);
|
||||
}
|
||||
} else {
|
||||
switch ( $this->get_value() ) {
|
||||
case 'sent_to_translator':
|
||||
case 'translator_replied':
|
||||
case 'admin_replied':
|
||||
return array(
|
||||
'value' => 'translator_replied',
|
||||
'label' => __( 'Reply to admin', 'sitepress' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/** @return bool */
|
||||
public function is_pending() {
|
||||
$pending_statuses = array( 'pending' );
|
||||
|
||||
if ( current_user_can( 'manage_options' ) ) {
|
||||
$pending_statuses[] = 'translator_replied';
|
||||
} else {
|
||||
$pending_statuses[] = 'admin_replied';
|
||||
$pending_statuses[] = 'sent_to_translator';
|
||||
}
|
||||
|
||||
return in_array( $this->status, $pending_statuses, true );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,297 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Feedback
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Feedback implements IWPML_TF_Data_Object {
|
||||
|
||||
/** @var int */
|
||||
private $id;
|
||||
|
||||
/** @var string */
|
||||
private $date_created;
|
||||
|
||||
/** @var WPML_TF_Feedback_Status */
|
||||
private $status;
|
||||
|
||||
/** @var int */
|
||||
private $rating;
|
||||
|
||||
/** @var string */
|
||||
private $content;
|
||||
|
||||
/** @var int */
|
||||
private $document_id;
|
||||
|
||||
/** @var string */
|
||||
private $document_type;
|
||||
|
||||
/** @var string */
|
||||
private $language_from;
|
||||
|
||||
/** @var string */
|
||||
private $language_to;
|
||||
|
||||
/** @var int|null */
|
||||
private $job_id;
|
||||
|
||||
/** @var WPML_TF_Feedback_Reviewer */
|
||||
private $reviewer;
|
||||
|
||||
/** @var WPML_TF_Collection $messages */
|
||||
private $messages;
|
||||
|
||||
/** @var WPML_TF_Backend_Document_Information $document_information */
|
||||
private $document_information;
|
||||
|
||||
/** @var WPML_TF_TP_Responses $tp_rating_responses */
|
||||
private $tp_responses;
|
||||
|
||||
/**
|
||||
* WPML_Translation_Feedback constructor.
|
||||
*
|
||||
* @param array $data
|
||||
* @param WPML_TF_Backend_Document_Information $document_information
|
||||
*/
|
||||
public function __construct(
|
||||
$data = array(),
|
||||
WPML_TF_Backend_Document_Information $document_information = null
|
||||
) {
|
||||
$this->id = array_key_exists( 'id', $data ) ? (int) $data['id'] : null;
|
||||
$this->date_created = array_key_exists( 'date_created', $data )
|
||||
? sanitize_text_field( $data['date_created'] ) : null;
|
||||
$this->rating = array_key_exists( 'rating', $data ) ? (int) $data['rating'] : null;
|
||||
$this->content = array_key_exists( 'content', $data )
|
||||
? sanitize_text_field( $data['content'] ) : '';
|
||||
$this->document_id = array_key_exists( 'document_id', $data ) ? (int) $data['document_id'] : null;
|
||||
$this->document_type = array_key_exists( 'document_type', $data )
|
||||
? sanitize_text_field( $data['document_type'] ) : null;
|
||||
$this->language_from = array_key_exists( 'language_from', $data )
|
||||
? sanitize_text_field( $data['language_from'] ) : null;
|
||||
$this->language_to = array_key_exists( 'language_to', $data )
|
||||
? sanitize_text_field( $data['language_to'] ) : null;
|
||||
$this->job_id = array_key_exists( 'job_id', $data ) ? (int) $data['job_id'] : null;
|
||||
$this->messages = array_key_exists( 'messages', $data ) && $data['messages'] instanceof WPML_TF_Collection
|
||||
? $data['messages'] : new WPML_TF_Message_Collection();
|
||||
|
||||
if ( array_key_exists( 'reviewer_id', $data ) ) {
|
||||
$this->set_reviewer( $data['reviewer_id'] );
|
||||
}
|
||||
|
||||
$this->status = array_key_exists( 'status', $data )
|
||||
? new WPML_TF_Feedback_Status( $data['status'] ) : new WPML_TF_Feedback_Status( 'pending' );
|
||||
|
||||
$this->set_tp_responses( new WPML_TF_TP_Responses( $data ) );
|
||||
|
||||
if ( $document_information ) {
|
||||
$this->set_document_information( $document_information );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|mixed|null
|
||||
*/
|
||||
public function get_id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|null
|
||||
*/
|
||||
public function get_feedback_id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WPML_TF_Message $message
|
||||
*/
|
||||
public function add_message( WPML_TF_Message $message ) {
|
||||
$this->messages->add( $message );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|null|string
|
||||
*/
|
||||
public function get_date_created() {
|
||||
return $this->date_created;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_status() {
|
||||
return $this->status->get_value();
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $status
|
||||
*/
|
||||
public function set_status( $status ) {
|
||||
$this->status->set_value( $status );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_rating() {
|
||||
return $this->rating;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $rating
|
||||
*/
|
||||
public function set_rating( $rating ) {
|
||||
$this->rating = (int) $rating;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|null|string
|
||||
*/
|
||||
public function get_content() {
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $content
|
||||
*/
|
||||
public function set_content( $content ) {
|
||||
$this->content = sanitize_text_field( $content );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|null
|
||||
*/
|
||||
public function get_document_id() {
|
||||
return $this->document_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
public function get_document_type() {
|
||||
return $this->document_type;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
public function get_language_from() {
|
||||
return $this->language_from;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
public function get_language_to() {
|
||||
return $this->language_to;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|null
|
||||
*/
|
||||
public function get_job_id() {
|
||||
return $this->job_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_TF_Feedback_Reviewer
|
||||
*/
|
||||
public function get_reviewer() {
|
||||
if ( ! isset( $this->reviewer ) ) {
|
||||
$this->set_reviewer( 0 );
|
||||
}
|
||||
|
||||
return $this->reviewer;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $reviewer_id
|
||||
*/
|
||||
public function set_reviewer( $reviewer_id ) {
|
||||
$this->reviewer = new WPML_TF_Feedback_Reviewer( $reviewer_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_TF_Collection
|
||||
*/
|
||||
public function get_messages() {
|
||||
return $this->messages;
|
||||
}
|
||||
|
||||
/** @param WPML_TF_TP_Responses $tp_responses */
|
||||
public function set_tp_responses( WPML_TF_TP_Responses $tp_responses ) {
|
||||
$this->tp_responses = $tp_responses;
|
||||
}
|
||||
|
||||
/** @return WPML_TF_TP_Responses */
|
||||
public function get_tp_responses() {
|
||||
return $this->tp_responses;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_text_status() {
|
||||
return $this->status->get_display_text();
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
public function get_next_status() {
|
||||
return $this->status->get_next_status();
|
||||
}
|
||||
|
||||
/** @return bool */
|
||||
public function is_pending() {
|
||||
return $this->status->is_pending();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_document_flag_url() {
|
||||
return $this->document_information->get_flag_url( $this->get_language_to() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_source_document_flag_url() {
|
||||
return $this->document_information->get_flag_url( $this->get_language_from() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_local_translation() {
|
||||
return $this->document_information->is_local_translation( $this->get_job_id() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_translator_name() {
|
||||
return $this->document_information->get_translator_name( $this->get_job_id() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_available_translators() {
|
||||
return $this->document_information->get_available_translators( $this->language_from, $this->language_to );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Backend_Document_Information $document_information
|
||||
*/
|
||||
public function set_document_information( WPML_TF_Backend_Document_Information $document_information ) {
|
||||
$this->document_information = $document_information;
|
||||
$this->document_information->init( $this->get_document_id(), $this->get_document_type() );
|
||||
}
|
||||
|
||||
/** @return WPML_TF_Backend_Document_Information */
|
||||
public function get_document_information() {
|
||||
return $this->document_information;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
use WPML\API\Sanitize;
|
||||
|
||||
/**
|
||||
* Class WPML_TF_TP_Responses
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_TP_Responses {
|
||||
|
||||
const FEEDBACK_FORWARD_MANUAL = 'manual';
|
||||
const FEEDBACK_FORWARD_EMAIL = 'email';
|
||||
const FEEDBACK_FORWARD_API = 'api';
|
||||
const FEEDBACK_TP_URL_ENDPOINT = '/feedbacks/{feedback_id}/external';
|
||||
|
||||
/**
|
||||
* @var string|int $tp_rating_id
|
||||
*
|
||||
* - empty string for rating never sent (or problems occurred during TP transmission)
|
||||
* - 0 for local jobs (which does not need to be sent)
|
||||
* - positive integer for ratings already sent
|
||||
*
|
||||
* This will allow to have a shorter DB query to select feedback to be sent
|
||||
*/
|
||||
private $rating_id = '';
|
||||
|
||||
/** @var null|int $feedback_id */
|
||||
private $feedback_id;
|
||||
|
||||
/** @var null|string $feedback_forward_method */
|
||||
private $feedback_forward_method;
|
||||
|
||||
public function __construct( array $args = array() ) {
|
||||
if( isset( $args['tp_rating_id'] ) ) {
|
||||
$this->set_rating_id( $args['tp_rating_id'] );
|
||||
}
|
||||
|
||||
if( isset( $args['tp_feedback_id'] ) ) {
|
||||
$this->set_feedback_id( $args['tp_feedback_id'] );
|
||||
}
|
||||
|
||||
if( isset( $args['feedback_forward_method'] ) ) {
|
||||
$this->set_feedback_forward_method( $args['feedback_forward_method'] );
|
||||
}
|
||||
}
|
||||
|
||||
/** @param string|int $rating_id */
|
||||
public function set_rating_id( $rating_id ) {
|
||||
if ( is_numeric( $rating_id ) ) {
|
||||
$rating_id = (int) $rating_id;
|
||||
}
|
||||
|
||||
$this->rating_id = $rating_id;
|
||||
}
|
||||
|
||||
/** @return string|int */
|
||||
public function get_rating_id() {
|
||||
return $this->rating_id;
|
||||
}
|
||||
|
||||
/** @param int $feedback_id */
|
||||
public function set_feedback_id( $feedback_id ) {
|
||||
$this->feedback_id = (int) $feedback_id;
|
||||
}
|
||||
|
||||
/** @return null|int */
|
||||
public function get_feedback_id() {
|
||||
return $this->feedback_id;
|
||||
}
|
||||
|
||||
/** @param string $method */
|
||||
public function set_feedback_forward_method( $method ) {
|
||||
$this->feedback_forward_method = Sanitize::string( $method );
|
||||
}
|
||||
|
||||
/** @return null|string */
|
||||
public function get_feedback_forward_method() {
|
||||
return $this->feedback_forward_method;
|
||||
}
|
||||
|
||||
/** @return bool */
|
||||
public function is_manual_feedback() {
|
||||
return self::FEEDBACK_FORWARD_MANUAL === $this->feedback_forward_method;
|
||||
}
|
||||
|
||||
/** @return bool */
|
||||
public function is_email_feedback() {
|
||||
return self::FEEDBACK_FORWARD_EMAIL === $this->feedback_forward_method;
|
||||
}
|
||||
|
||||
/** @return bool */
|
||||
public function is_api_feedback() {
|
||||
return self::FEEDBACK_FORWARD_API === $this->feedback_forward_method;
|
||||
}
|
||||
|
||||
/** @return null|string */
|
||||
public function get_feedback_tp_url() {
|
||||
$url = null;
|
||||
|
||||
if ( $this->is_api_feedback() && defined( 'OTG_TRANSLATION_PROXY_URL' ) ) {
|
||||
$url = OTG_TRANSLATION_PROXY_URL . self::FEEDBACK_TP_URL_ENDPOINT;
|
||||
$url = preg_replace( '/{feedback_id}/', $this->get_feedback_id(), $url );
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
public function get_strings() {
|
||||
return array(
|
||||
'display_for_manual' => __( '%1s cannot receive feedback about the translation automatically. Please log-in to %1s website and report these issues manually.', 'sitepress' ),
|
||||
'display_for_email' => __( 'An email has been sent to %s to report the issue. Please check your email for a feedback from their part.', 'sitepress' ),
|
||||
'display_for_api' => __( 'Issue tracking in %s', 'sitepress' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,19 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Interface IWPML_TF_Collection_Filter
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
interface IWPML_TF_Collection_Filter {
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_posts_args();
|
||||
|
||||
/**
|
||||
* @return WPML_TF_Collection
|
||||
*/
|
||||
public function get_new_collection();
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Interface IWPML_TF_Data_Object
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
interface IWPML_TF_Data_Object {
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_id();
|
||||
|
||||
/**
|
||||
* @return int|null
|
||||
*/
|
||||
public function get_feedback_id();
|
||||
|
||||
/**
|
||||
* @param \WPML_TF_Message $message
|
||||
*/
|
||||
public function add_message( WPML_TF_Message $message );
|
||||
}
|
||||
@@ -0,0 +1,74 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Message_Collection_Filter
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Message_Collection_Filter implements IWPML_TF_Collection_Filter {
|
||||
|
||||
/** @var int $feedback_id */
|
||||
private $feedback_id;
|
||||
|
||||
/** @var array|null */
|
||||
private $feedback_ids;
|
||||
|
||||
/**
|
||||
* WPML_TF_Feedback_Collection_Filter constructor.
|
||||
*
|
||||
* @param array $args
|
||||
*/
|
||||
public function __construct( array $args = array() ) {
|
||||
if ( isset( $args['feedback_id'] ) ) {
|
||||
$this->feedback_id = (int) $args['feedback_id'];
|
||||
}
|
||||
|
||||
if ( isset( $args['feedback_ids'] ) && is_array( $args['feedback_ids'] ) ) {
|
||||
$this->feedback_ids = $args['feedback_ids'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|null
|
||||
*/
|
||||
private function get_feedback_id() {
|
||||
return $this->feedback_id;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* @return array|null
|
||||
*/
|
||||
private function get_feedback_ids() {
|
||||
return $this->feedback_ids;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_posts_args() {
|
||||
$posts_args = array(
|
||||
'posts_per_page' => -1,
|
||||
'post_type' => WPML_TF_Message_Post_Convert::POST_TYPE,
|
||||
'suppress_filters' => false,
|
||||
'post_status' => 'any',
|
||||
);
|
||||
|
||||
if ( $this->get_feedback_id() ) {
|
||||
$posts_args['post_parent'] = $this->get_feedback_id();
|
||||
}
|
||||
|
||||
if ( $this->get_feedback_ids() ) {
|
||||
$posts_args['post_parent__in'] = $this->get_feedback_ids();
|
||||
}
|
||||
|
||||
return $posts_args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_TF_Message_Collection
|
||||
*/
|
||||
public function get_new_collection() {
|
||||
return new WPML_TF_Message_Collection();
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,10 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Message_Collection
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Message_Collection extends WPML_TF_Collection {
|
||||
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Message_Post_Convert
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Message_Post_Convert extends WPML_TF_Data_Object_Post_Convert {
|
||||
|
||||
const POST_TYPE = 'wpml_tf_message';
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_post_fields() {
|
||||
return array(
|
||||
'id' => 'ID',
|
||||
'date_created' => 'post_date',
|
||||
'content' => 'post_content',
|
||||
'feedback_id' => 'post_parent',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_meta_fields() {
|
||||
return array(
|
||||
'author_id',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IWPML_TF_Data_Object $message
|
||||
*
|
||||
* @return array
|
||||
* @throws Exception
|
||||
*/
|
||||
public function to_post_data( IWPML_TF_Data_Object $message ) {
|
||||
if( ! $message instanceof WPML_TF_Message ) {
|
||||
throw new Exception( 'The $message argument must be an instance of WPML_TF_Message' );
|
||||
}
|
||||
|
||||
/** @var WPML_TF_Message $message */
|
||||
$post = new stdClass();
|
||||
$post->ID = $message->get_id();
|
||||
$post->post_date = $message->get_date_created();
|
||||
$post->post_content = $message->get_content();
|
||||
$post->post_parent = $message->get_feedback_id();
|
||||
$post->post_type = self::POST_TYPE;
|
||||
|
||||
return array(
|
||||
'post' => $post,
|
||||
'metadata' => array(
|
||||
'author_id' => $message->get_author_id(),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $post_data
|
||||
*
|
||||
* @return WPML_TF_Message
|
||||
*/
|
||||
public function to_object( array $post_data ) {
|
||||
$message_data = $this->build_object_data_for_constructor( $post_data );
|
||||
return new WPML_TF_Message( $message_data );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Message
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Message implements IWPML_TF_Data_Object {
|
||||
|
||||
/** @var int $id */
|
||||
private $id;
|
||||
|
||||
/** @var int $feedback_id */
|
||||
private $feedback_id;
|
||||
|
||||
/** @var string $date_created */
|
||||
private $date_created;
|
||||
|
||||
/** @var string $content */
|
||||
private $content;
|
||||
|
||||
/** @var string $author_id */
|
||||
private $author_id;
|
||||
|
||||
/**
|
||||
* WPML_Translation_Feedback constructor.
|
||||
*
|
||||
* @param array $data
|
||||
*/
|
||||
public function __construct( $data = array() ) {
|
||||
$this->id = array_key_exists( 'id', $data ) ? (int) $data['id'] : null;
|
||||
$this->feedback_id = array_key_exists( 'feedback_id', $data ) ? (int) $data['feedback_id'] : null;
|
||||
$this->date_created = array_key_exists( 'date_created', $data )
|
||||
? sanitize_text_field( $data['date_created'] ) : null;
|
||||
$this->content = array_key_exists( 'content', $data )
|
||||
? sanitize_text_field( $data['content'] ) : null;
|
||||
$this->author_id = array_key_exists( 'author_id', $data )
|
||||
? (int) $data['author_id'] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|mixed|null
|
||||
*/
|
||||
public function get_id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|null
|
||||
*/
|
||||
public function get_feedback_id() {
|
||||
return $this->feedback_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param \WPML_TF_Message $message
|
||||
*/
|
||||
public function add_message( WPML_TF_Message $message ) {
|
||||
return;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|null|string
|
||||
*/
|
||||
public function get_date_created() {
|
||||
return $this->date_created;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed|null|string
|
||||
*/
|
||||
public function get_content() {
|
||||
return $this->content;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int|null
|
||||
*/
|
||||
public function get_author_id() {
|
||||
return $this->author_id;
|
||||
}
|
||||
|
||||
/** @return string */
|
||||
public function get_author_display_label() {
|
||||
$label = __( 'Translator', 'sitepress' );
|
||||
|
||||
if ( user_can( $this->get_author_id(), 'manage_options' ) ) {
|
||||
$label = __( 'Admin', 'sitepress' );
|
||||
}
|
||||
|
||||
return $label;
|
||||
}
|
||||
|
||||
/** @return bool */
|
||||
public function author_is_current_user() {
|
||||
$current_user = wp_get_current_user();
|
||||
return $current_user->ID === $this->author_id;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,26 @@
|
||||
<?php
|
||||
|
||||
class WPML_TF_Collection_Filter_Factory {
|
||||
|
||||
/**
|
||||
* @param string $type
|
||||
* @param array $args
|
||||
*
|
||||
* @return null|IWPML_TF_Collection_Filter
|
||||
*/
|
||||
public function create( $type, array $args = array() ) {
|
||||
$collection_filter = null;
|
||||
|
||||
switch ( $type ) {
|
||||
case 'feedback':
|
||||
$collection_filter = new WPML_TF_Feedback_Collection_Filter( $args );
|
||||
break;
|
||||
|
||||
case 'message':
|
||||
$collection_filter = new WPML_TF_Message_Collection_Filter( $args );
|
||||
break;
|
||||
}
|
||||
|
||||
return $collection_filter;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Collection
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Collection implements Iterator, Countable {
|
||||
|
||||
/** @var array<\IWPML_TF_Data_Object> */
|
||||
protected $collection = array();
|
||||
|
||||
/**
|
||||
* @param \IWPML_TF_Data_Object $data_object
|
||||
*/
|
||||
public function add( IWPML_TF_Data_Object $data_object ) {
|
||||
$this->collection[ $data_object->get_id() ] = $data_object;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_ids() {
|
||||
return array_keys( $this->collection );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @return IWPML_TF_Data_Object|null
|
||||
*/
|
||||
public function get( $id ) {
|
||||
return array_key_exists( $id, $this->collection ) ? $this->collection[ $id ] : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function count() {
|
||||
return count( $this->collection );
|
||||
}
|
||||
|
||||
public function rewind() {
|
||||
reset( $this->collection );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function current() {
|
||||
return current( $this->collection );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return mixed
|
||||
*/
|
||||
public function key() {
|
||||
return key( $this->collection );
|
||||
}
|
||||
|
||||
public function next() {
|
||||
next( $this->collection );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function valid() {
|
||||
return key( $this->collection ) !== null;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,54 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Data_Object_Post_Convert
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
abstract class WPML_TF_Data_Object_Post_Convert {
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
abstract public function get_post_fields();
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
abstract public function get_meta_fields();
|
||||
|
||||
/**
|
||||
* @param IWPML_TF_Data_Object $data_object
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
abstract public function to_post_data( IWPML_TF_Data_Object $data_object );
|
||||
|
||||
/**
|
||||
* @param array $post_data
|
||||
*
|
||||
* @return object
|
||||
*/
|
||||
abstract public function to_object( array $post_data );
|
||||
|
||||
/**
|
||||
* @param array $post_data
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
protected function build_object_data_for_constructor( array $post_data ) {
|
||||
$object_data = array();
|
||||
|
||||
foreach ( $this->get_post_fields() as $feedback_field => $post_field ) {
|
||||
$object_data[ $feedback_field ] = isset( $post_data['post']->{$post_field} )
|
||||
? $post_data['post']->{$post_field} : null;
|
||||
}
|
||||
|
||||
foreach ( $this->get_meta_fields() as $meta_field ) {
|
||||
$object_data[ $meta_field ] = isset( $post_data['metadata'][ $meta_field ] )
|
||||
? $post_data['metadata'][ $meta_field ] : null;
|
||||
}
|
||||
|
||||
return $object_data;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Data_Object_Storage
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Data_Object_Storage {
|
||||
|
||||
const META_PREFIX = 'wpml_tf_';
|
||||
|
||||
/** @var WPML_TF_Data_Object_Post_Convert */
|
||||
private $post_convert;
|
||||
|
||||
/**
|
||||
* WPML_TF_Data_Object_Storage constructor.
|
||||
*
|
||||
* @param WPML_TF_Data_Object_Post_Convert $post_convert
|
||||
*/
|
||||
public function __construct( WPML_TF_Data_Object_Post_Convert $post_convert ) {
|
||||
$this->post_convert = $post_convert;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
*
|
||||
* @return IWPML_TF_Data_Object|null
|
||||
*/
|
||||
public function get( $id ) {
|
||||
$result = null;
|
||||
$post_data = array();
|
||||
|
||||
$post_data['post'] = get_post( $id );
|
||||
|
||||
if ( $post_data['post'] ) {
|
||||
foreach ( $this->post_convert->get_meta_fields() as $meta_field ) {
|
||||
$post_data['metadata'][ $meta_field ] = get_post_meta( $id, self::META_PREFIX . $meta_field, true );
|
||||
}
|
||||
|
||||
$result = $this->post_convert->to_object( $post_data );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IWPML_TF_Data_Object $data_object
|
||||
*
|
||||
* @return int|WP_Error
|
||||
*/
|
||||
public function persist( IWPML_TF_Data_Object $data_object ) {
|
||||
$post_data = $this->post_convert->to_post_data( $data_object );
|
||||
|
||||
$updated_id = wp_insert_post( $post_data['post'] );
|
||||
|
||||
if ( $updated_id && ! is_wp_error( $updated_id ) ) {
|
||||
foreach ( $post_data['metadata'] as $key => $value ) {
|
||||
update_post_meta( $updated_id, self::META_PREFIX . $key, $value );
|
||||
}
|
||||
}
|
||||
|
||||
return $updated_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param bool $force_delete
|
||||
*/
|
||||
public function delete( $id, $force_delete = false ) {
|
||||
if ( $force_delete ) {
|
||||
wp_delete_post( $id );
|
||||
} else {
|
||||
wp_trash_post( $id );
|
||||
}
|
||||
}
|
||||
|
||||
/** @param int $id */
|
||||
public function untrash( $id ) {
|
||||
wp_untrash_post( $id );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IWPML_TF_Collection_Filter $collection_filter
|
||||
*
|
||||
* @return WPML_TF_Collection
|
||||
*/
|
||||
public function get_collection( IWPML_TF_Collection_Filter $collection_filter ) {
|
||||
$collection = $collection_filter->get_new_collection();
|
||||
$posts_args = $collection_filter->get_posts_args();
|
||||
|
||||
if ( isset( $posts_args['meta_query']['relation'] ) && 'OR' === $posts_args['meta_query']['relation'] ) {
|
||||
$object_posts = $this->get_posts_from_split_queries( $posts_args );
|
||||
} else {
|
||||
$object_posts = get_posts( $posts_args );
|
||||
}
|
||||
|
||||
foreach ( $object_posts as $object_post ) {
|
||||
$collection->add( $this->get( $object_post->ID ) );
|
||||
}
|
||||
|
||||
return $collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* For more than 2 meta queries with "OR" relation, the standard WP query has a very bad performance.
|
||||
* It's much more efficient to make one query for each meta query.
|
||||
*
|
||||
* @param array $posts_args
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_posts_from_split_queries( array $posts_args ) {
|
||||
$object_posts = array();
|
||||
$meta_query_parts = $posts_args['meta_query'];
|
||||
unset( $meta_query_parts['relation'] );
|
||||
|
||||
foreach ( $meta_query_parts as $meta_query ) {
|
||||
$posts_args['meta_query'] = $meta_query;
|
||||
$object_posts = $object_posts + get_posts( $posts_args );
|
||||
}
|
||||
|
||||
return $object_posts;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,255 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Feedback_Edit
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Feedback_Edit {
|
||||
|
||||
/** @var WPML_TF_Feedback_Query */
|
||||
private $feedback_query;
|
||||
|
||||
/** @var WPML_TF_Data_Object_Storage $feedback_storage */
|
||||
private $feedback_storage;
|
||||
|
||||
/** @var WPML_TF_Data_Object_Storage $message_storage */
|
||||
private $message_storage;
|
||||
|
||||
/** @var null|WPML_TP_Client_Factory $tp_client_factory */
|
||||
private $tp_client_factory;
|
||||
|
||||
/** @var null|WPML_TP_Client $tp_client */
|
||||
private $tp_client;
|
||||
|
||||
/**
|
||||
* WPML_TF_Feedback_Edit constructor.
|
||||
*
|
||||
* @param \WPML_TF_Feedback_Query $feedback_query
|
||||
* @param \WPML_TF_Data_Object_Storage $feedback_storage
|
||||
* @param \WPML_TF_Data_Object_Storage $message_storage
|
||||
* @param \WPML_TP_Client_Factory|null $tp_client_factory
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_TF_Feedback_Query $feedback_query,
|
||||
WPML_TF_Data_Object_Storage $feedback_storage,
|
||||
WPML_TF_Data_Object_Storage $message_storage,
|
||||
WPML_TP_Client_Factory $tp_client_factory = null
|
||||
) {
|
||||
$this->feedback_query = $feedback_query;
|
||||
$this->feedback_storage = $feedback_storage;
|
||||
$this->message_storage = $message_storage;
|
||||
$this->tp_client_factory = $tp_client_factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $feedback_id
|
||||
* @param array $args
|
||||
*
|
||||
* @return null|WPML_TF_Feedback
|
||||
* @throws \WPML_TF_Feedback_Update_Exception
|
||||
*/
|
||||
public function update( $feedback_id, array $args ) {
|
||||
$feedback = $this->feedback_query->get_one( $feedback_id );
|
||||
|
||||
if ( $feedback ) {
|
||||
$this->update_feedback_content( $feedback, $args );
|
||||
$this->add_message_to_feedback( $feedback, $args );
|
||||
$this->assign_feedback_to_reviewer( $feedback, $args );
|
||||
$this->update_feedback_status( $feedback, $args );
|
||||
$this->feedback_storage->persist( $feedback );
|
||||
|
||||
$feedback = $this->feedback_query->get_one( $feedback_id, true );
|
||||
}
|
||||
|
||||
return $feedback;
|
||||
}
|
||||
/**
|
||||
* @param WPML_TF_Feedback $feedback
|
||||
* @param array $args
|
||||
*/
|
||||
private function update_feedback_content( WPML_TF_Feedback $feedback, array $args ) {
|
||||
if ( isset( $args['feedback_content'] ) && $this->is_admin_user() ) {
|
||||
$feedback->set_content( $args['feedback_content'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Feedback $feedback
|
||||
* @param array $args
|
||||
*/
|
||||
private function add_message_to_feedback( WPML_TF_Feedback $feedback, array $args ) {
|
||||
if ( isset( $args['message_content'] ) ) {
|
||||
$message_args = array(
|
||||
'feedback_id' => $feedback->get_id(),
|
||||
'content' => $args['message_content'],
|
||||
'author_id' => get_current_user_id(),
|
||||
);
|
||||
|
||||
$message = new WPML_TF_Message( $message_args );
|
||||
$feedback->add_message( $message );
|
||||
$this->message_storage->persist( $message );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Feedback $feedback
|
||||
* @param array $args
|
||||
*/
|
||||
private function assign_feedback_to_reviewer( WPML_TF_Feedback $feedback, array $args ) {
|
||||
if ( isset( $args['feedback_reviewer_id'] ) && $this->is_admin_user() ) {
|
||||
$feedback->set_reviewer( $args['feedback_reviewer_id'] );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Feedback $feedback
|
||||
* @param array $args
|
||||
*
|
||||
* @throws \WPML_TF_Feedback_Update_Exception
|
||||
*/
|
||||
private function update_feedback_status( WPML_TF_Feedback $feedback, array $args ) {
|
||||
if ( isset( $args['feedback_status'] )
|
||||
&& in_array( $args['feedback_status'], $this->get_feedback_statuses(), true )
|
||||
) {
|
||||
if ( 'sent_to_translator' === $args['feedback_status'] && ! $feedback->is_local_translation() ) {
|
||||
$this->send_feedback_to_tp( $feedback );
|
||||
} elseif ( 'sent_to_ts_api' === $args['feedback_status'] ) {
|
||||
$this->update_feedback_status_from_tp( $feedback );
|
||||
} else {
|
||||
$feedback->set_status( $args['feedback_status'] );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $feedback_id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function delete( $feedback_id ) {
|
||||
if ( $this->is_admin_user() ) {
|
||||
$this->feedback_storage->delete( $feedback_id );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/** @return bool */
|
||||
private function is_admin_user() {
|
||||
return current_user_can( 'manage_options' );
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
private function get_feedback_statuses() {
|
||||
return array(
|
||||
'pending',
|
||||
'sent_to_translator',
|
||||
'translator_replied',
|
||||
'admin_replied',
|
||||
'fixed',
|
||||
'sent_to_ts_api',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Feedback $feedback
|
||||
*
|
||||
* @throws WPML_TF_Feedback_Update_Exception
|
||||
*/
|
||||
private function send_feedback_to_tp( WPML_TF_Feedback $feedback ) {
|
||||
$current_user = wp_get_current_user();
|
||||
|
||||
$args = array(
|
||||
'email' => $current_user->user_email,
|
||||
);
|
||||
|
||||
$tp_feedback_id = $this->get_tp_client()->feedback()->send( $feedback, $args );
|
||||
|
||||
if ( ! $tp_feedback_id ) {
|
||||
throw new WPML_TF_Feedback_Update_Exception( $this->get_communication_error_message( 'send' ) );
|
||||
}
|
||||
|
||||
$feedback->get_tp_responses()->set_feedback_id( $tp_feedback_id );
|
||||
$active_service = $this->get_tp_client()->services()->get_active();
|
||||
$feedback->get_tp_responses()->set_feedback_forward_method( $active_service->get_feedback_forward_method() );
|
||||
$new_status = 'sent_to_ts_' . $active_service->get_feedback_forward_method();
|
||||
$feedback->set_status( $new_status );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Feedback $feedback
|
||||
*
|
||||
* @throws WPML_TF_Feedback_Update_Exception
|
||||
*/
|
||||
private function update_feedback_status_from_tp( WPML_TF_Feedback $feedback ) {
|
||||
$tp_feedback_status = $this->get_tp_client()->feedback()->status( $feedback );
|
||||
|
||||
if ( ! $tp_feedback_status ) {
|
||||
throw new WPML_TF_Feedback_Update_Exception( $this->get_communication_error_message( 'status' ) );
|
||||
} elseif ( 'closed' === $tp_feedback_status ) {
|
||||
$feedback->set_status( 'fixed' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $endpoint
|
||||
*
|
||||
* @return string
|
||||
* @throws \WPML_TF_Feedback_Update_Exception
|
||||
*/
|
||||
private function get_communication_error_message( $endpoint ) {
|
||||
$active_service = $this->get_tp_client()->services()->get_active();
|
||||
$service_name = isset( $active_service->name ) ? $active_service->name : esc_html__( 'Translation Service', 'sitepress' );
|
||||
|
||||
if ( 'send' === $endpoint ) {
|
||||
$error_message = sprintf(
|
||||
esc_html__( 'Could not send the report to %s.', 'sitepress' ),
|
||||
$service_name
|
||||
);
|
||||
|
||||
$error_message .= ' ' . sprintf(
|
||||
esc_html__( "This means that %s isn't yet aware of the problem in the translation and cannot fix it.", 'sitepress' ),
|
||||
$service_name
|
||||
);
|
||||
} else {
|
||||
$error_message = sprintf(
|
||||
esc_html__( 'Could not fetch the status from %s.', 'sitepress' ),
|
||||
$service_name
|
||||
);
|
||||
}
|
||||
|
||||
$error_message .= ' ' . sprintf(
|
||||
esc_html__( "Let's get it working for you. Please contact %1sWPML support%2s and give them the following error details:", 'sitepress' ),
|
||||
'<a href="https://wpml.org/forums/forum/english-support/" target="_blank">',
|
||||
'</a>'
|
||||
);
|
||||
|
||||
$error_message .= '<br><div class="js-wpml-tf-error-details"><a href="#">' .
|
||||
esc_html__( 'Show details', 'sitepress' ) . '</a>' .
|
||||
'<pre style="display:none;">' . esc_html( $this->get_tp_client()->feedback()->get_error_message() ) .
|
||||
'</pre></div>';
|
||||
|
||||
return $error_message;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|WPML_TP_Client
|
||||
*
|
||||
* @throws WPML_TF_Feedback_Update_Exception
|
||||
*/
|
||||
private function get_tp_client() {
|
||||
if ( ! $this->tp_client && $this->tp_client_factory ) {
|
||||
$this->tp_client = $this->tp_client_factory->create();
|
||||
|
||||
if ( ! $this->tp_client ) {
|
||||
throw new WPML_TF_Feedback_Update_Exception(
|
||||
esc_html__( 'WPML cannot communicate with the remote translation service. Please make sure WPML Translation Management is active.', 'sitepress' )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
return $this->tp_client;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,225 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Feedback_Query
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Feedback_Query {
|
||||
|
||||
/** @var WPML_TF_Data_Object_Storage $feedback_storage */
|
||||
private $feedback_storage;
|
||||
|
||||
/** @var WPML_TF_Data_Object_Storage $message_storage */
|
||||
private $message_storage;
|
||||
|
||||
/** @var WPML_TF_Collection_Filter_Factory $collection_filter_factory */
|
||||
private $collection_filter_factory;
|
||||
|
||||
/** @var WPML_TF_Feedback_Collection $unfiltered_feedback_collection */
|
||||
private $unfiltered_feedback_collection;
|
||||
|
||||
/** @var int $unfiltered_items_count */
|
||||
private $unfiltered_items_count;
|
||||
|
||||
/** @var int $trashed_items_count */
|
||||
private $trashed_items_count;
|
||||
|
||||
/** @var int $total_items_count */
|
||||
private $total_items_count;
|
||||
|
||||
/** @var int $filtered_items_count */
|
||||
private $filtered_items_count;
|
||||
|
||||
/** @var bool $is_in_trash */
|
||||
private $is_in_trash = false;
|
||||
|
||||
/**
|
||||
* WPML_TF_Feedback_Collection_Factory constructor.
|
||||
*
|
||||
* @param WPML_TF_Data_Object_Storage $feedback_storage
|
||||
* @param WPML_TF_Data_Object_Storage $message_storage
|
||||
* @param WPML_TF_Collection_Filter_Factory $collection_filter_factory
|
||||
*/
|
||||
public function __construct(
|
||||
WPML_TF_Data_Object_Storage $feedback_storage,
|
||||
WPML_TF_Data_Object_Storage $message_storage,
|
||||
WPML_TF_Collection_Filter_Factory $collection_filter_factory
|
||||
) {
|
||||
$this->feedback_storage = $feedback_storage;
|
||||
$this->message_storage = $message_storage;
|
||||
$this->collection_filter_factory = $collection_filter_factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_TF_Feedback_Collection
|
||||
*/
|
||||
public function get_unfiltered_collection() {
|
||||
if ( ! $this->unfiltered_feedback_collection ) {
|
||||
|
||||
$storage_filters = array(
|
||||
'exclude_rating_only' => true,
|
||||
);
|
||||
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
$storage_filters['reviewer_id'] = get_current_user_id();
|
||||
}
|
||||
|
||||
$feedback_collection_filter = $this->collection_filter_factory->create( 'feedback', $storage_filters );
|
||||
$this->unfiltered_feedback_collection = $this->feedback_storage->get_collection( $feedback_collection_filter );
|
||||
|
||||
$this->unfiltered_items_count = count( $this->unfiltered_feedback_collection );
|
||||
}
|
||||
|
||||
return $this->unfiltered_feedback_collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*
|
||||
* @return WPML_TF_Feedback_Collection
|
||||
*/
|
||||
public function get( array $args ) {
|
||||
$feedback_collection = clone $this->get_unfiltered_collection();
|
||||
$feedback_collection = $this->trash_filter_collection( $feedback_collection, $args );
|
||||
$feedback_collection = $this->filter_collection( $feedback_collection, $args );
|
||||
$feedback_collection = $this->sort_collection( $feedback_collection, $args );
|
||||
$feedback_collection = $this->apply_pagination( $feedback_collection, $args );
|
||||
|
||||
$message_filter_args = array( 'feedback_ids' => $feedback_collection->get_ids() );
|
||||
$message_collection_filter = $this->collection_filter_factory->create( 'message', $message_filter_args );
|
||||
|
||||
/** @var WPML_TF_Message_Collection $message_collection */
|
||||
$message_collection = $this->message_storage->get_collection( $message_collection_filter );
|
||||
|
||||
$feedback_collection->link_messages_to_feedback( $message_collection );
|
||||
|
||||
return $feedback_collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Feedback_Collection $feedback_collection
|
||||
* @param array $args
|
||||
*
|
||||
* @return WPML_TF_Feedback_Collection
|
||||
*/
|
||||
public function trash_filter_collection( WPML_TF_Feedback_Collection $feedback_collection, array $args ) {
|
||||
if ( isset( $args['status'] ) && 'trash' === $args['status'] ) {
|
||||
$this->is_in_trash = true;
|
||||
$feedback_collection->filter_by( 'status', 'trash' );
|
||||
$this->trashed_items_count = count( $feedback_collection );
|
||||
$this->total_items_count = $this->unfiltered_items_count - $this->trashed_items_count;
|
||||
} else {
|
||||
$feedback_collection->remove_trashed();
|
||||
$this->total_items_count = count( $feedback_collection );
|
||||
$this->trashed_items_count = $this->unfiltered_items_count - $this->total_items_count;
|
||||
}
|
||||
|
||||
return $feedback_collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Feedback_Collection $feedback_collection
|
||||
* @param array $args
|
||||
*
|
||||
* @return WPML_TF_Feedback_Collection
|
||||
*/
|
||||
private function filter_collection( WPML_TF_Feedback_Collection $feedback_collection, array $args ) {
|
||||
if ( isset( $args['status'] ) && 'trash' !== $args['status'] ) {
|
||||
$feedback_collection->filter_by( 'status', $args['status'] );
|
||||
} elseif ( isset( $args['language'] ) ) {
|
||||
$feedback_collection->filter_by( 'language', $args['language'] );
|
||||
} elseif ( isset( $args['post_id'] ) ) {
|
||||
$feedback_collection->filter_by( 'post_id', $args['post_id'] );
|
||||
}
|
||||
|
||||
$this->filtered_items_count = count( $feedback_collection );
|
||||
|
||||
return $feedback_collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Feedback_Collection $feedback_collection
|
||||
* @param array $args
|
||||
*
|
||||
* @return WPML_TF_Feedback_Collection
|
||||
*/
|
||||
private function sort_collection( WPML_TF_Feedback_Collection $feedback_collection, array $args ) {
|
||||
$order_by = 'pending';
|
||||
$order = 'desc';
|
||||
|
||||
if ( isset( $args['orderby'] ) ) {
|
||||
$order_by = $args['orderby'];
|
||||
}
|
||||
|
||||
if ( isset( $args['order'] ) ) {
|
||||
$order = $args['order'];
|
||||
}
|
||||
|
||||
$feedback_collection->sort_collection( $order_by, $order );
|
||||
|
||||
return $feedback_collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param WPML_TF_Feedback_Collection $feedback_collection
|
||||
* @param array $args
|
||||
*
|
||||
* @return WPML_TF_Feedback_Collection
|
||||
*/
|
||||
private function apply_pagination( WPML_TF_Feedback_Collection $feedback_collection, array $args ) {
|
||||
if ( isset( $args['paged'], $args['items_per_page'] ) ) {
|
||||
$offset = $args['items_per_page'] * max( 0, $args['paged'] - 1 );
|
||||
$feedback_collection->reduce_collection( $offset, $args['items_per_page'] );
|
||||
}
|
||||
|
||||
return $feedback_collection;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_total_items_count() {
|
||||
return $this->total_items_count;
|
||||
}
|
||||
|
||||
/** @return int */
|
||||
public function get_total_trashed_items_count() {
|
||||
return $this->trashed_items_count;
|
||||
}
|
||||
|
||||
/** @return int */
|
||||
public function get_filtered_items_count() {
|
||||
return $this->filtered_items_count;
|
||||
}
|
||||
|
||||
/** @return bool */
|
||||
public function is_in_trash() {
|
||||
return $this->is_in_trash;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $feedback_id
|
||||
* @param bool $with_messages
|
||||
*
|
||||
* @return null|\IWPML_TF_Data_Object
|
||||
*/
|
||||
public function get_one( $feedback_id, $with_messages = true ) {
|
||||
$feedback = $this->feedback_storage->get( $feedback_id );
|
||||
|
||||
if ( $feedback && $with_messages ) {
|
||||
$filter_args = array(
|
||||
'feedback_id' => $feedback_id,
|
||||
);
|
||||
|
||||
$filter = new WPML_TF_Message_Collection_Filter( $filter_args );
|
||||
$messages = $this->message_storage->get_collection( $filter );
|
||||
|
||||
foreach ( $messages as $message ) {
|
||||
$feedback->add_message( $message );
|
||||
}
|
||||
}
|
||||
|
||||
return $feedback;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Notices
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Notices {
|
||||
|
||||
const GROUP = 'wpml_tf_backend_notices';
|
||||
const BULK_UPDATED = 'bulk_updated';
|
||||
|
||||
/** @var WPML_Notices $admin_notices */
|
||||
private $admin_notices;
|
||||
|
||||
/**
|
||||
* @param array $updated_feedback_ids
|
||||
* @parem string
|
||||
*/
|
||||
public function add_bulk_updated_notice( array $updated_feedback_ids, $action ) {
|
||||
$count_feedback = count( $updated_feedback_ids );
|
||||
|
||||
$message = _n( '%d feedback was updated.', '%d feedback were updated.', $count_feedback, 'sitepress' );
|
||||
|
||||
if ( 'trash' === $action ) {
|
||||
$permanent_trash_delay = defined( 'EMPTY_TRASH_DAYS' ) ? EMPTY_TRASH_DAYS : 30;
|
||||
|
||||
$message = _n( '%d feedback was trashed.', '%d feedback were trashed.', $count_feedback, 'sitepress' );
|
||||
$message .= ' ' . sprintf(
|
||||
__( 'The trashed feedback will be permanently deleted after %d days.', 'sitepress' ),
|
||||
$permanent_trash_delay
|
||||
);
|
||||
} elseif ( 'untrash' === $action ) {
|
||||
$message = _n( '%d feedback was restored.', '%d feedback were restored.', $count_feedback, 'sitepress' );
|
||||
} elseif ( 'delete' === $action ) {
|
||||
$message = _n( '%d feedback was permanently deleted.', '%d feedback were permanently deleted.', $count_feedback, 'sitepress' );
|
||||
}
|
||||
|
||||
$text = sprintf( $message, $count_feedback );
|
||||
|
||||
$new_notice = $this->get_admin_notices()->get_new_notice( self::BULK_UPDATED, $text, self::GROUP );
|
||||
$new_notice->set_hideable( true );
|
||||
$new_notice->set_css_class_types( 'notice-success' );
|
||||
$this->get_admin_notices()->add_notice( $new_notice );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add action to remove updated notice after display
|
||||
*/
|
||||
public function remove_bulk_updated_notice_after_display() {
|
||||
add_action( 'admin_notices', array( $this, 'remove_bulk_updated_notice' ), PHP_INT_MAX );
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove bulk_updated notice
|
||||
*/
|
||||
public function remove_bulk_updated_notice() {
|
||||
$this->get_admin_notices()->remove_notice( self::GROUP, self::BULK_UPDATED );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return WPML_Notices
|
||||
*/
|
||||
private function get_admin_notices() {
|
||||
if ( ! $this->admin_notices ) {
|
||||
$this->admin_notices = wpml_get_admin_notices();
|
||||
}
|
||||
|
||||
return $this->admin_notices;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Promote_Notices
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Promote_Notices {
|
||||
|
||||
const NOTICE_GROUP = 'wpml-tf-promote';
|
||||
const NOTICE_NEW_SITE = 'notice-new-site';
|
||||
const DOC_URL = 'https://wpml.org/documentation/getting-started-guide/getting-visitor-feedback-about-your-sites-translations/?utm_source=plugin&utm_medium=gui&utm_campaign=wpmlcore';
|
||||
|
||||
/** @var SitePress $sitepress */
|
||||
private $sitepress;
|
||||
|
||||
public function __construct( SitePress $sitepress ) {
|
||||
$this->sitepress = $sitepress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $user_id
|
||||
*/
|
||||
public function show_notice_for_new_site( $user_id ) {
|
||||
$notices = wpml_get_admin_notices();
|
||||
$settings_url = admin_url( '?page=' . WPML_PLUGIN_FOLDER . '/menu/languages.php#wpml-translation-feedback-options' );
|
||||
|
||||
$user_lang = $this->sitepress->get_user_admin_language( $user_id );
|
||||
$this->sitepress->switch_lang( $user_lang );
|
||||
|
||||
$text = '<h2>' . __( 'Want to know if recent translations you received have problems?', 'sitepress' ) . '</h2>';
|
||||
$text .= '<p>';
|
||||
$text .= __( 'You got back several jobs from translation and they now appear on your site.', 'sitepress' );
|
||||
$text .= ' ' . __( 'WPML lets you open these pages for feedback, so that visitors can tell you if they notice anything wrong.', 'sitepress' );
|
||||
$text .= '<br><br>';
|
||||
$text .= '<a href="' . $settings_url . '" class="button-secondary">' . __( 'Enable Translation Feedback', 'sitepress' ) . '</a>';
|
||||
$text .= ' <a href="' . self::DOC_URL . '" target="_blank">' . __( 'Learn more about translation feedback', 'sitepress' ) . '</a>';
|
||||
$text .= '</p>';
|
||||
|
||||
$notice = $notices->get_new_notice( self::NOTICE_NEW_SITE, $text, self::NOTICE_GROUP );
|
||||
$notice->set_dismissible( true );
|
||||
$notice->set_css_class_types( 'notice-info' );
|
||||
$notice->add_user_restriction( $user_id );
|
||||
|
||||
if ( ! $notices->is_notice_dismissed( $notice ) ) {
|
||||
$notices->add_notice( $notice );
|
||||
}
|
||||
|
||||
$this->sitepress->switch_lang( null );
|
||||
}
|
||||
|
||||
public function remove() {
|
||||
$notices = wpml_get_admin_notices();
|
||||
$notices->remove_notice( self::NOTICE_GROUP, self::NOTICE_NEW_SITE );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Options_Scripts
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Options_Scripts {
|
||||
|
||||
const HANDLE = 'wpml-tf-backend-options';
|
||||
|
||||
/**
|
||||
* method enqueue
|
||||
*/
|
||||
public function enqueue() {
|
||||
$script = ICL_PLUGIN_URL . '/res/js/translation-feedback/wpml-tf-backend-options-script.js';
|
||||
wp_register_script( self::HANDLE, $script, array( 'jquery', 'wp-util' ), ICL_SITEPRESS_VERSION );
|
||||
wp_enqueue_script( self::HANDLE );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Scripts
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Scripts {
|
||||
|
||||
const HANDLE = 'wpml-tf-backend';
|
||||
|
||||
/**
|
||||
* method enqueue
|
||||
*/
|
||||
public function enqueue() {
|
||||
$script = ICL_PLUGIN_URL . '/res/js/translation-feedback/wpml-tf-backend-script.js';
|
||||
wp_register_script( self::HANDLE, $script, array( 'jquery', 'wp-util' ), ICL_SITEPRESS_VERSION );
|
||||
wp_enqueue_script( self::HANDLE );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Frontend_Scripts
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Frontend_Scripts {
|
||||
|
||||
const HANDLE = 'wpml-tf-frontend';
|
||||
|
||||
/**
|
||||
* method enqueue
|
||||
*/
|
||||
public function enqueue() {
|
||||
$script = ICL_PLUGIN_URL . '/res/js/translation-feedback/wpml-tf-frontend-script.js';
|
||||
wp_register_script( self::HANDLE, $script, array( 'jquery', 'jquery-ui-dialog', 'wp-util' ), ICL_SITEPRESS_VERSION );
|
||||
wp_enqueue_script( self::HANDLE );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Interface WPML_Settings_Interface
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
interface IWPML_TF_Settings {
|
||||
|
||||
/**
|
||||
* @return array of name/value pairs
|
||||
*
|
||||
* Each property should have its own setter "set_{$property_name}"
|
||||
*/
|
||||
public function get_properties();
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Settings_Handler
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
abstract class WPML_TF_Settings_Handler {
|
||||
|
||||
/**
|
||||
* @param string $class_name
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_option_name( $class_name ) {
|
||||
return sanitize_title( $class_name );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,57 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Settings_Read
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Settings_Read extends WPML_TF_Settings_Handler {
|
||||
|
||||
/**
|
||||
* @param string $settings_class
|
||||
*
|
||||
* @return IWPML_TF_Settings
|
||||
*
|
||||
* @throws InvalidArgumentException
|
||||
*/
|
||||
public function get( $settings_class ) {
|
||||
if ( ! class_exists( $settings_class ) ) {
|
||||
throw new InvalidArgumentException( $settings_class . ' does not exist.' );
|
||||
}
|
||||
|
||||
if ( ! in_array( 'IWPML_TF_Settings', class_implements( $settings_class ) ) ) {
|
||||
throw new InvalidArgumentException( $settings_class . ' should implement IWPML_TF_Settings.' );
|
||||
}
|
||||
|
||||
$settings_properties = get_option( $this->get_option_name( $settings_class ) );
|
||||
|
||||
/** @var IWPML_TF_Settings $settings */
|
||||
$settings = new $settings_class();
|
||||
|
||||
if ( is_array( $settings_properties ) ) {
|
||||
$this->set_properties( $settings, $settings_properties );
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param IWPML_TF_Settings $settings
|
||||
* @param array $settings_properties
|
||||
*
|
||||
* @throws BadMethodCallException
|
||||
*/
|
||||
private function set_properties( IWPML_TF_Settings $settings, array $settings_properties ) {
|
||||
foreach ( $settings->get_properties() as $property_name => $property_value ) {
|
||||
|
||||
if ( method_exists( $settings, 'set_' . $property_name ) ) {
|
||||
|
||||
if ( isset( $settings_properties[ $property_name ] ) ) {
|
||||
call_user_func( array( $settings, 'set_' . $property_name ), $settings_properties[ $property_name ] );
|
||||
}
|
||||
} else {
|
||||
throw new BadMethodCallException( 'The method set_' . $property_name . ' is required in ' . get_class( $settings ) . '.' );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,18 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Settings_Write
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Settings_Write extends WPML_TF_Settings_Handler {
|
||||
|
||||
/**
|
||||
* @param IWPML_TF_Settings $settings
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function save( IWPML_TF_Settings $settings ) {
|
||||
return update_option( $this->get_option_name( get_class( $settings ) ), $settings->get_properties() );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,180 @@
|
||||
<?php
|
||||
|
||||
use WPML\API\Sanitize;
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Settings
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Settings implements IWPML_TF_Settings {
|
||||
|
||||
const BUTTON_MODE_DISABLED = 'disabled';
|
||||
const BUTTON_MODE_LEFT = 'left';
|
||||
const BUTTON_MODE_RIGHT = 'right';
|
||||
const BUTTON_MODE_CUSTOM = 'custom';
|
||||
|
||||
const ICON_STYLE_LEGACY = 'translation';
|
||||
const ICON_STYLE_STAR = 'star';
|
||||
const ICON_STYLE_THUMBSUP = 'thumbsup';
|
||||
const ICON_STYLE_BULLHORN = 'bullhorn';
|
||||
const ICON_STYLE_COMMENT = 'comment';
|
||||
const ICON_STYLE_QUOTE = 'quote';
|
||||
|
||||
const DISPLAY_ALWAYS = 'always';
|
||||
const DISPLAY_CUSTOM = 'custom';
|
||||
|
||||
const EXPIRATION_ON_PUBLISH_OR_UPDATE = 'publish_or_update';
|
||||
const EXPIRATION_ON_PUBLISH_ONLY = 'publish_only';
|
||||
const EXPIRATION_ON_UPDATE_ONLY = 'update_only';
|
||||
|
||||
const DELAY_DAY = 1;
|
||||
const DELAY_WEEK = 7;
|
||||
const DELAY_MONTH = 30;
|
||||
|
||||
/** @var bool $enabled */
|
||||
private $enabled = false;
|
||||
|
||||
/** @var string $button_mode */
|
||||
private $button_mode = self::BUTTON_MODE_LEFT;
|
||||
|
||||
/** @var string $icon_style */
|
||||
private $icon_style = self::ICON_STYLE_LEGACY;
|
||||
|
||||
/** @var null|array $languages_to */
|
||||
private $languages_to = null;
|
||||
|
||||
/** @var string $display_mode */
|
||||
private $display_mode = self::DISPLAY_CUSTOM;
|
||||
|
||||
/** @var string $expiration_mode */
|
||||
private $expiration_mode = self::EXPIRATION_ON_PUBLISH_OR_UPDATE;
|
||||
|
||||
/** @var int $expiration_delay_quantity */
|
||||
private $expiration_delay_quantity = 1;
|
||||
|
||||
/** @var int $expiration_delay_unit */
|
||||
private $expiration_delay_unit = self::DELAY_MONTH;
|
||||
|
||||
/**
|
||||
* @param bool $enabled
|
||||
*/
|
||||
public function set_enabled( $enabled ) {
|
||||
$this->enabled = (bool) $enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function is_enabled() {
|
||||
return $this->enabled;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $button_mode
|
||||
*/
|
||||
public function set_button_mode( $button_mode ) {
|
||||
$this->button_mode = Sanitize::string( $button_mode );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_button_mode() {
|
||||
return $this->button_mode;
|
||||
}
|
||||
|
||||
/** @param string $style */
|
||||
public function set_icon_style( $style ) {
|
||||
$this->icon_style = Sanitize::string( $style );
|
||||
}
|
||||
|
||||
/** @return string */
|
||||
public function get_icon_style() {
|
||||
return $this->icon_style;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $languages_to
|
||||
*/
|
||||
public function set_languages_to( array $languages_to ) {
|
||||
$this->languages_to = array_map( 'sanitize_title', $languages_to );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|array
|
||||
*/
|
||||
public function get_languages_to() {
|
||||
return $this->languages_to;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $display_mode
|
||||
*/
|
||||
public function set_display_mode( $display_mode ) {
|
||||
$this->display_mode = Sanitize::string( $display_mode );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_display_mode() {
|
||||
return $this->display_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $expiration_mode
|
||||
*/
|
||||
public function set_expiration_mode( $expiration_mode ) {
|
||||
$this->expiration_mode = Sanitize::string( $expiration_mode );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_expiration_mode() {
|
||||
return $this->expiration_mode;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $expiration_delay_quantity
|
||||
*/
|
||||
public function set_expiration_delay_quantity( $expiration_delay_quantity ) {
|
||||
$this->expiration_delay_quantity = (int) $expiration_delay_quantity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_expiration_delay_quantity() {
|
||||
return $this->expiration_delay_quantity;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $expiration_delay_unit
|
||||
*/
|
||||
public function set_expiration_delay_unit( $expiration_delay_unit ) {
|
||||
$this->expiration_delay_unit = (int) $expiration_delay_unit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int
|
||||
*/
|
||||
public function get_expiration_delay_unit() {
|
||||
return $this->expiration_delay_unit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return int delay in days before expiration
|
||||
*/
|
||||
public function get_expiration_delay_in_days() {
|
||||
return $this->expiration_delay_quantity * $this->expiration_delay_unit;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_properties() {
|
||||
return get_object_vars( $this );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Options_Styles
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Options_Styles {
|
||||
|
||||
const HANDLE = 'wpml-tf-backend-options';
|
||||
|
||||
/**
|
||||
* method enqueue
|
||||
*/
|
||||
public function enqueue() {
|
||||
$style = ICL_PLUGIN_URL . '/res/css/translation-feedback/backend-options.css';
|
||||
wp_register_style( self::HANDLE, $style, array(), ICL_SITEPRESS_VERSION );
|
||||
wp_enqueue_style( self::HANDLE );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Styles
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Styles {
|
||||
|
||||
const HANDLE = 'wpml-tf-backend';
|
||||
|
||||
/**
|
||||
* method enqueue
|
||||
*/
|
||||
public function enqueue() {
|
||||
$style = ICL_PLUGIN_URL . '/res/css/translation-feedback/backend-feedback-list.css';
|
||||
wp_register_style( self::HANDLE, $style, array( 'otgs-ico' ), ICL_SITEPRESS_VERSION );
|
||||
wp_enqueue_style( self::HANDLE );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Frontend_Styles
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Frontend_Styles {
|
||||
|
||||
const HANDLE = 'wpml-tf-frontend';
|
||||
|
||||
/**
|
||||
* method enqueue
|
||||
*/
|
||||
public function enqueue() {
|
||||
$style = ICL_PLUGIN_URL . '/res/css/translation-feedback/front-style.css';
|
||||
wp_register_style( self::HANDLE, $style, array( 'otgs-dialogs', 'otgs-icons' ), ICL_SITEPRESS_VERSION );
|
||||
wp_enqueue_style( self::HANDLE );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,215 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Document_Information
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Document_Information extends WPML_TF_Document_Information {
|
||||
|
||||
/** @var WPML_TP_Client_Factory|null $tp_client_factory */
|
||||
private $tp_client_factory;
|
||||
|
||||
/** @var WPML_TP_Client|null $tp_client */
|
||||
private $tp_client;
|
||||
|
||||
/**
|
||||
* WPML_TF_Backend_Document_Information constructor.
|
||||
*
|
||||
* @param SitePress $sitepress
|
||||
* @param WPML_TP_Client_Factory $tp_client_factory
|
||||
*/
|
||||
public function __construct( SitePress $sitepress, WPML_TP_Client_Factory $tp_client_factory = null ) {
|
||||
parent::__construct( $sitepress );
|
||||
$this->tp_client_factory = $tp_client_factory;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return false|null|string
|
||||
*/
|
||||
public function get_url() {
|
||||
$url = null;
|
||||
|
||||
if ( $this->is_post_document() ) {
|
||||
$url = get_permalink( $this->id );
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
public function get_title() {
|
||||
$title = null;
|
||||
|
||||
if ( $this->is_post_document() ) {
|
||||
$title = $this->get_post_title( $this->id );
|
||||
}
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function is_post_document() {
|
||||
return 0 === strpos( $this->type, 'post_' );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $language_code
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_flag_url( $language_code ) {
|
||||
return $this->sitepress->get_flag_url( $language_code );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_edit_url() {
|
||||
$this->load_link_to_translation_tm_filters();
|
||||
|
||||
$url = 'post.php?' . http_build_query(
|
||||
array(
|
||||
'lang' => $this->get_language(),
|
||||
'action' => 'edit',
|
||||
'post_type' => $this->type,
|
||||
'post' => $this->id,
|
||||
)
|
||||
);
|
||||
|
||||
return apply_filters( 'wpml_link_to_translation', $url, $this->get_source_id(), $this->get_language(), $this->get_trid() );
|
||||
}
|
||||
|
||||
private function load_link_to_translation_tm_filters() {
|
||||
if ( ! did_action( 'wpml_pre_status_icon_display' ) ) {
|
||||
do_action( 'wpml_pre_status_icon_display' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|int
|
||||
*/
|
||||
public function get_source_id() {
|
||||
$source_id = null;
|
||||
$translations = $this->get_translations();
|
||||
|
||||
if ( isset( $translations[ $this->get_source_language() ]->element_id ) ) {
|
||||
$source_id = (int) $translations[ $this->get_source_language() ]->element_id;
|
||||
}
|
||||
|
||||
return $source_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
public function get_source_url() {
|
||||
$url = null;
|
||||
|
||||
if ( $this->get_source_id() ) {
|
||||
$url = get_the_permalink( $this->get_source_id() );
|
||||
}
|
||||
|
||||
return $url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|string
|
||||
*/
|
||||
public function get_source_title() {
|
||||
$title = null;
|
||||
|
||||
if ( $this->get_source_id() ) {
|
||||
$title = $this->get_post_title( $this->get_source_id() );
|
||||
}
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array|bool|mixed
|
||||
*/
|
||||
private function get_translations() {
|
||||
return $this->sitepress->get_element_translations( $this->get_trid(), $this->type );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $job_id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_translator_name( $job_id ) {
|
||||
$translation_job = $this->get_translation_job( $job_id );
|
||||
|
||||
if ( isset( $translation_job->translation_service ) ) {
|
||||
|
||||
if ( 'local' === $translation_job->translation_service && isset( $translation_job->translator_id ) ) {
|
||||
$translator_name = get_the_author_meta( 'display_name', $translation_job->translator_id );
|
||||
$translator_name .= ' (' . __( 'local translator', 'sitepress' ) . ')';
|
||||
} else {
|
||||
$translator_name = __( 'Unknown remote translation service', 'sitepress' );
|
||||
$tp_client = $this->get_tp_client();
|
||||
|
||||
if ( $tp_client ) {
|
||||
$translator_name = $tp_client->services()->get_name( $translation_job->translation_service );
|
||||
}
|
||||
}
|
||||
} else {
|
||||
$post_author_id = get_post_field( 'post_author', $this->id );
|
||||
$translator_name = get_the_author_meta( 'display_name', $post_author_id );
|
||||
}
|
||||
|
||||
return $translator_name;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $from
|
||||
* @param string $to
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_available_translators( $from, $to ) {
|
||||
$translators = array();
|
||||
|
||||
if ( function_exists( 'wpml_tm_load_blog_translators' ) ) {
|
||||
$args = array(
|
||||
'from' => $from,
|
||||
'to' => $to,
|
||||
);
|
||||
|
||||
$users = wpml_tm_load_blog_translators()->get_blog_translators( $args );
|
||||
$translators = wp_list_pluck( $users, 'display_name', 'ID' );
|
||||
}
|
||||
|
||||
return $translators;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $post_id
|
||||
*
|
||||
* @return null|string
|
||||
*/
|
||||
private function get_post_title( $post_id ) {
|
||||
$title = null;
|
||||
$post = get_post( $post_id );
|
||||
|
||||
if ( isset( $post->post_title ) ) {
|
||||
$title = $post->post_title;
|
||||
}
|
||||
|
||||
return $title;
|
||||
}
|
||||
|
||||
/** @return null|WPML_TP_Client */
|
||||
private function get_tp_client() {
|
||||
if ( ! $this->tp_client && $this->tp_client_factory ) {
|
||||
$this->tp_client = $this->tp_client_factory->create();
|
||||
}
|
||||
|
||||
return $this->tp_client;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,117 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Document_Information
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Document_Information {
|
||||
|
||||
/** @var SitePress $sitepress */
|
||||
protected $sitepress;
|
||||
|
||||
/** @var int $id */
|
||||
protected $id;
|
||||
|
||||
/** @var string $type */
|
||||
protected $type;
|
||||
|
||||
/** @var stdClass $language_details */
|
||||
protected $language_details;
|
||||
|
||||
/** @var null|int|stdClass */
|
||||
private $translation_job;
|
||||
|
||||
/**
|
||||
* WPML_TF_Document_Information constructor.
|
||||
*
|
||||
* @param SitePress $sitepress
|
||||
*/
|
||||
public function __construct( SitePress $sitepress ) {
|
||||
$this->sitepress = $sitepress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $id
|
||||
* @param string $type
|
||||
*/
|
||||
public function init( $id, $type ) {
|
||||
$this->id = $id;
|
||||
$this->type = $type;
|
||||
$this->language_details = $this->sitepress->get_element_language_details( $this->id, $this->type );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string|null
|
||||
*/
|
||||
public function get_source_language() {
|
||||
return isset( $this->language_details->source_language_code )
|
||||
? $this->language_details->source_language_code
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function get_language() {
|
||||
return isset( $this->language_details->language_code )
|
||||
? $this->language_details->language_code
|
||||
: null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|int
|
||||
*/
|
||||
public function get_job_id() {
|
||||
$args = array(
|
||||
'trid' => $this->get_trid(),
|
||||
'language_code' => $this->get_language(),
|
||||
);
|
||||
|
||||
$job_id = apply_filters( 'wpml_translation_job_id', false, $args );
|
||||
|
||||
return $job_id ? $job_id : null;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return null|int
|
||||
*/
|
||||
protected function get_trid() {
|
||||
$trid = null;
|
||||
|
||||
if ( isset( $this->language_details->trid ) ) {
|
||||
$trid = $this->language_details->trid;
|
||||
}
|
||||
|
||||
return $trid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $job_id
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_local_translation( $job_id ) {
|
||||
$is_local = true;
|
||||
$translation_job = $this->get_translation_job( $job_id );
|
||||
|
||||
if ( isset( $translation_job->translation_service ) && 'local' !== $translation_job->translation_service ) {
|
||||
$is_local = false;
|
||||
}
|
||||
|
||||
return $is_local;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $job_id
|
||||
*
|
||||
* @return int|stdClass
|
||||
*/
|
||||
protected function get_translation_job( $job_id ) {
|
||||
if ( ! $this->translation_job ) {
|
||||
$this->translation_job = apply_filters( 'wpml_get_translation_job', $job_id );
|
||||
}
|
||||
|
||||
return $this->translation_job;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,239 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Feedback_Page_Filter
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Feedback_Page_Filter {
|
||||
|
||||
/** @var SitePress $sitepress */
|
||||
private $sitepress;
|
||||
|
||||
/** @var WPML_TF_Feedback_Query $feedback_query */
|
||||
private $feedback_query;
|
||||
|
||||
/** @var array $statuses */
|
||||
private $statuses = array();
|
||||
|
||||
/** @var array $languages */
|
||||
private $languages = array();
|
||||
|
||||
/** @var array $url_args */
|
||||
private $url_args;
|
||||
|
||||
/** @var string $current_url */
|
||||
private $current_url;
|
||||
|
||||
/**
|
||||
* WPML_TF_Feedback_Page_Filter constructor.
|
||||
*
|
||||
* @param SitePress $sitepress
|
||||
* @param WPML_TF_Feedback_Query $feedback_query
|
||||
*/
|
||||
public function __construct( SitePress $sitepress, WPML_TF_Feedback_Query $feedback_query ) {
|
||||
$this->sitepress = $sitepress;
|
||||
$this->feedback_query = $feedback_query;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function get_filter_keys() {
|
||||
return array(
|
||||
'status',
|
||||
'language',
|
||||
'post_id',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Will not create filters inside the trash
|
||||
* And will not include the "trash" status in the status row
|
||||
*/
|
||||
public function populate_counters_and_labels() {
|
||||
if ( $this->feedback_query->is_in_trash() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $this->feedback_query->get_unfiltered_collection() as $feedback ) {
|
||||
/** @var WPML_TF_Feedback $feedback */
|
||||
if ( 'trash' === $feedback->get_status() ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( ! array_key_exists( $feedback->get_status(), $this->statuses ) ) {
|
||||
$this->statuses[ $feedback->get_status() ] = array(
|
||||
'count' => 1,
|
||||
'label' => $feedback->get_text_status(),
|
||||
);
|
||||
} else {
|
||||
$this->statuses[ $feedback->get_status() ]['count']++;
|
||||
}
|
||||
|
||||
if ( ! array_key_exists( $feedback->get_language_to(), $this->languages ) ) {
|
||||
$lang_details = $this->sitepress->get_language_details( $feedback->get_language_to() );
|
||||
|
||||
$this->languages[ $feedback->get_language_to() ] = array(
|
||||
'count' => 1,
|
||||
'label' => isset( $lang_details['display_name'] ) ? $lang_details['display_name'] : null,
|
||||
);
|
||||
} else {
|
||||
$this->languages[ $feedback->get_language_to() ]['count']++;
|
||||
}
|
||||
}
|
||||
|
||||
ksort( $this->statuses );
|
||||
ksort( $this->languages );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_all_and_trash_data() {
|
||||
$main_data = array(
|
||||
'all' => array(
|
||||
'count' => $this->feedback_query->get_total_items_count(),
|
||||
'label' => __( 'All', 'sitepress' ),
|
||||
'url' => $this->get_reset_filters_url(),
|
||||
'current' => $this->get_current_url() === $this->get_reset_filters_url(),
|
||||
),
|
||||
);
|
||||
|
||||
if ( $this->feedback_query->get_total_trashed_items_count() ) {
|
||||
$main_data['trashed'] = array(
|
||||
'count' => $this->feedback_query->get_total_trashed_items_count(),
|
||||
'label' => __( 'Trash', 'sitepress' ),
|
||||
'url' => $this->get_filter_url( 'status', 'trash' ),
|
||||
'current' => $this->get_current_url() === $this->get_filter_url( 'status', 'trash' ),
|
||||
);
|
||||
}
|
||||
|
||||
if ( $this->is_current_filter( 'post_id' ) ) {
|
||||
$filters = $this->get_current_filters();
|
||||
$post = get_post( $filters['post_id'] );
|
||||
|
||||
if ( isset( $post->post_title ) ) {
|
||||
$main_data['post_id'] = array(
|
||||
'label' => sprintf(
|
||||
__( 'For "%s"', 'sitepress' ),
|
||||
mb_strimwidth( $post->post_title, 0, 40, '...' )
|
||||
),
|
||||
'current' => true,
|
||||
);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return $main_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_statuses_data() {
|
||||
foreach ( $this->statuses as $status => $data ) {
|
||||
$this->statuses[ $status ]['url'] = $this->get_filter_url( 'status', $status );
|
||||
$this->statuses[ $status ]['current'] = false;
|
||||
|
||||
if ( $this->is_current_filter( 'status', $status ) ) {
|
||||
$this->statuses[ $status ]['current'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->statuses;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_languages_data() {
|
||||
foreach ( $this->languages as $language_code => $data ) {
|
||||
$this->languages[ $language_code ]['url'] = $this->get_filter_url( 'language', $language_code );
|
||||
$this->languages[ $language_code ]['current'] = false;
|
||||
|
||||
if ( $this->is_current_filter( 'language', $language_code ) ) {
|
||||
$this->languages[ $language_code ]['current'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $this->languages;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filter_name
|
||||
* @param string $filter_value
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function get_filter_url( $filter_name, $filter_value ) {
|
||||
return add_query_arg( $filter_name, $filter_value, $this->get_reset_filters_url() );
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string $filter_key
|
||||
* @param string $filter_value
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_current_filter( $filter_key, $filter_value = null ) {
|
||||
$is_current_filter = false;
|
||||
$query_args = $this->get_url_args();
|
||||
|
||||
if ( array_key_exists( $filter_key, $query_args )
|
||||
&& ( ! $filter_value || $query_args[ $filter_key ] === $filter_value )
|
||||
) {
|
||||
$is_current_filter = true;
|
||||
}
|
||||
|
||||
return $is_current_filter;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public function get_current_filters() {
|
||||
$filters = array();
|
||||
$query_args = $this->get_url_args();
|
||||
|
||||
foreach ( self::get_filter_keys() as $filter_key ) {
|
||||
if ( array_key_exists( $filter_key, $query_args ) ) {
|
||||
$filters[ $filter_key ] = $query_args[ $filter_key ];
|
||||
}
|
||||
}
|
||||
|
||||
return $filters;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_url_args() {
|
||||
if ( ! $this->url_args ) {
|
||||
$this->url_args = array();
|
||||
$url_query = wpml_parse_url( $this->get_current_url(), PHP_URL_QUERY );
|
||||
parse_str( $url_query, $this->url_args );
|
||||
}
|
||||
|
||||
return $this->url_args;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function get_current_url() {
|
||||
if ( ! $this->current_url ) {
|
||||
$this->current_url = set_url_scheme( 'http://' . $_SERVER['HTTP_HOST'] . $_SERVER['REQUEST_URI'] );
|
||||
$this->current_url = remove_query_arg( 'paged', $this->current_url );
|
||||
}
|
||||
|
||||
return $this->current_url;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
private function get_reset_filters_url() {
|
||||
return remove_query_arg( self::get_filter_keys(), $this->get_current_url() );
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,87 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Frontend_Display_Requirements
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Frontend_Display_Requirements {
|
||||
|
||||
/** @var WPML_Queried_Object $queried_object */
|
||||
private $queried_object;
|
||||
|
||||
/** @var WPML_TF_Settings $settings */
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* WPML_TF_Frontend_Display_Requirements constructor.
|
||||
*
|
||||
* @param WPML_Queried_Object $queried_object
|
||||
* @param WPML_TF_Settings $settings
|
||||
*/
|
||||
public function __construct( WPML_Queried_Object $queried_object, WPML_TF_Settings $settings ) {
|
||||
$this->queried_object = $queried_object;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
public function verify() {
|
||||
return $this->is_enabled_on_frontend()
|
||||
&& $this->is_translation()
|
||||
&& $this->is_allowed_language()
|
||||
&& $this->is_not_expired();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function is_enabled_on_frontend() {
|
||||
return $this->settings->is_enabled()
|
||||
&& $this->settings->get_button_mode() !== WPML_TF_Settings::BUTTON_MODE_DISABLED;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function is_translation() {
|
||||
return (bool) $this->queried_object->get_source_language_code();
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function is_allowed_language() {
|
||||
return is_array( $this->settings->get_languages_to() )
|
||||
&& in_array( $this->queried_object->get_language_code(), $this->settings->get_languages_to(), true );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return bool
|
||||
*/
|
||||
private function is_not_expired() {
|
||||
$is_expired = false;
|
||||
|
||||
if ( $this->settings->get_display_mode() === WPML_TF_Settings::DISPLAY_CUSTOM
|
||||
&& $this->queried_object->is_post()
|
||||
) {
|
||||
$post = get_post( $this->queried_object->get_id() );
|
||||
$now = strtotime( 'now' );
|
||||
|
||||
if ( $this->settings->get_expiration_mode() === WPML_TF_Settings::EXPIRATION_ON_PUBLISH_ONLY ) {
|
||||
$post_date = strtotime( $post->post_date );
|
||||
} else {
|
||||
$post_date = max( strtotime( $post->post_date ), strtotime( $post->post_modified ) );
|
||||
}
|
||||
|
||||
$post_age_in_days = ( $now - $post_date ) / DAY_IN_SECONDS;
|
||||
|
||||
if ( $post_age_in_days > $this->settings->get_expiration_delay_in_days() ) {
|
||||
$is_expired = true;
|
||||
}
|
||||
}
|
||||
|
||||
return ! $is_expired;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Rating_Average
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Post_Rating_Metrics {
|
||||
|
||||
const QUANTITY_KEY = 'wpml_tf_post_rating_quantity';
|
||||
const AVERAGE_KEY = 'wpml_tf_post_rating_average';
|
||||
|
||||
/** @var wpdb $wpdb */
|
||||
private $wpdb;
|
||||
|
||||
public function __construct( wpdb $wpdb ) {
|
||||
$this->wpdb = $wpdb;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $post_id
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_display( $post_id ) {
|
||||
$quantity = (int) get_post_meta( $post_id, self::QUANTITY_KEY, true );
|
||||
|
||||
if ( 0 === $quantity ) {
|
||||
return '';
|
||||
}
|
||||
|
||||
$average = get_post_meta( $post_id, self::AVERAGE_KEY, true );
|
||||
$title = sprintf( __( 'Average rating - %s', 'sitepress' ), $average );
|
||||
$stars = round( $average );
|
||||
$url = admin_url( 'admin.php?page=' . WPML_TF_Backend_Hooks::PAGE_HOOK . '&post_id=' . $post_id );
|
||||
|
||||
$output = '<div class="wpml-tf-rating" title="' . esc_attr( $title ) . '"><a href="'. esc_url( $url ) . '">';
|
||||
|
||||
for ( $i = 1; $i < 6; $i++ ) {
|
||||
$output .= '<span class="otgs-ico-star';
|
||||
|
||||
if ( $i <= $stars ) {
|
||||
$output .= ' full-star';
|
||||
}
|
||||
|
||||
$output .= '"></span>';
|
||||
}
|
||||
|
||||
$output .= '</a> <span class="rating-quantity">(' . esc_html( $quantity ) . ')</span></div>';
|
||||
|
||||
return $output;
|
||||
|
||||
}
|
||||
|
||||
/** @param int $post_id */
|
||||
public function refresh( $post_id ) {
|
||||
$document_id_key = WPML_TF_Data_Object_Storage::META_PREFIX . 'document_id';
|
||||
$rating_key = WPML_TF_Data_Object_Storage::META_PREFIX . 'rating';
|
||||
|
||||
$subquery = $this->wpdb->prepare(
|
||||
"SELECT post_id FROM {$this->wpdb->postmeta}
|
||||
WHERE meta_key = %s AND meta_value = %d",
|
||||
$document_id_key,
|
||||
$post_id
|
||||
);
|
||||
|
||||
$query = $this->wpdb->prepare(
|
||||
"SELECT meta_value FROM {$this->wpdb->postmeta}
|
||||
WHERE meta_key = %s AND post_id IN( {$subquery} )",
|
||||
$rating_key
|
||||
);
|
||||
|
||||
$ratings = $this->wpdb->get_results( $query );
|
||||
|
||||
if ( $ratings ) {
|
||||
|
||||
$total = 0;
|
||||
foreach ( $ratings as $rating ) {
|
||||
$total += (int) $rating->meta_value;
|
||||
}
|
||||
|
||||
$quantity = count( $ratings );
|
||||
$average = round( $total / $quantity, 1 );
|
||||
|
||||
update_post_meta( $post_id, self::QUANTITY_KEY, $quantity );
|
||||
update_post_meta( $post_id, self::AVERAGE_KEY, $average );
|
||||
} else {
|
||||
delete_post_meta( $post_id, self::QUANTITY_KEY );
|
||||
delete_post_meta( $post_id, self::AVERAGE_KEY );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,35 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Translation_Service
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Translation_Service {
|
||||
|
||||
/** @var WPML_TP_Client_Factory $tp_client_factory */
|
||||
private $tp_client_factory;
|
||||
/**
|
||||
* WPML_TF_Translation_Service constructor.
|
||||
*
|
||||
* @param WPML_TP_Client_Factory $tp_client_factory
|
||||
*/
|
||||
public function __construct( WPML_TP_Client_Factory $tp_client_factory = null ) {
|
||||
$this->tp_client_factory = $tp_client_factory;
|
||||
}
|
||||
|
||||
/** @return bool */
|
||||
public function allows_translation_feedback() {
|
||||
if ( ! $this->tp_client_factory ) {
|
||||
return true;
|
||||
}
|
||||
|
||||
$translation_service = $this->tp_client_factory->create()->services()->get_active();
|
||||
|
||||
if ( isset( $translation_service->translation_feedback ) && ! $translation_service->translation_feedback ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,222 @@
|
||||
<?php
|
||||
|
||||
use WPML\API\Sanitize;
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Feedback_List_View
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Feedback_List_View {
|
||||
|
||||
const TEMPLATE_FOLDER = '/templates/translation-feedback/backend/';
|
||||
const TEMPLATE_NAME = 'feedback-list-page.twig';
|
||||
const ITEMS_PER_PAGE = 20;
|
||||
|
||||
/** @var IWPML_Template_Service $template_service */
|
||||
private $template_service;
|
||||
|
||||
/** @var WPML_TF_Feedback_Query $feedback_query */
|
||||
private $feedback_query;
|
||||
|
||||
/** @var WPML_Admin_Pagination $pagination */
|
||||
private $pagination;
|
||||
|
||||
/** @var WPML_Admin_Table_Sort $table_sort */
|
||||
private $table_sort;
|
||||
|
||||
/** @var WPML_TF_Feedback_Page_Filter $page_filter */
|
||||
private $page_filter;
|
||||
|
||||
/**
|
||||
* WPML_TF_Backend_Feedback_List_View constructor.
|
||||
*
|
||||
* @param IWPML_Template_Service $template_service
|
||||
* @param WPML_TF_Feedback_Query $feedback_query
|
||||
* @param WPML_Admin_Pagination $pagination
|
||||
* @param WPML_Admin_Table_Sort $table_sort
|
||||
* @param WPML_TF_Feedback_Page_Filter $page_filter
|
||||
*/
|
||||
public function __construct(
|
||||
IWPML_Template_Service $template_service,
|
||||
WPML_TF_Feedback_Query $feedback_query,
|
||||
WPML_Admin_Pagination $pagination,
|
||||
WPML_Admin_Table_Sort $table_sort,
|
||||
WPML_TF_Feedback_Page_Filter $page_filter
|
||||
) {
|
||||
$this->template_service = $template_service;
|
||||
$this->feedback_query = $feedback_query;
|
||||
$this->pagination = $pagination;
|
||||
$this->table_sort = $table_sort;
|
||||
$this->page_filter = $page_filter;
|
||||
}
|
||||
|
||||
/** @return string */
|
||||
public function render_page() {
|
||||
$args = $this->parse_request_args();
|
||||
$feedback_collection = $this->feedback_query->get( $args );
|
||||
|
||||
$model = array(
|
||||
'strings' => $this->get_strings(),
|
||||
'columns' => $this->get_columns(),
|
||||
'pagination' => $this->get_pagination( $args ),
|
||||
'page_filters' => $this->get_page_filters(),
|
||||
'admin_page_hook' => WPML_TF_Backend_Hooks::PAGE_HOOK,
|
||||
'current_query' => $this->get_current_query(),
|
||||
'nonce' => wp_create_nonce( WPML_TF_Backend_Hooks::PAGE_HOOK ),
|
||||
'ajax_action' => WPML_TF_Backend_AJAX_Feedback_Edit_Hooks_Factory::AJAX_ACTION,
|
||||
'ajax_nonce' => wp_create_nonce( WPML_TF_Backend_AJAX_Feedback_Edit_Hooks_Factory::AJAX_ACTION ),
|
||||
'has_admin_capabilities' => current_user_can( 'manage_options' ),
|
||||
'is_in_trash' => $this->feedback_query->is_in_trash(),
|
||||
'feedback_collection' => $feedback_collection,
|
||||
);
|
||||
|
||||
return $this->template_service->show( $model, self::TEMPLATE_NAME );
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
private function parse_request_args() {
|
||||
$args = array(
|
||||
'paged' => 1,
|
||||
'items_per_page' => self::ITEMS_PER_PAGE,
|
||||
);
|
||||
|
||||
if ( isset( $_GET['paged'] ) ) {
|
||||
$args['paged'] = filter_var( $_GET['paged'], FILTER_SANITIZE_NUMBER_INT );
|
||||
}
|
||||
|
||||
if ( isset( $_GET['order'], $_GET['orderby'] ) ) {
|
||||
$args['order'] = Sanitize::stringProp( 'order', $_GET );
|
||||
$args['orderby'] = Sanitize::stringProp( 'orderby', $_GET );
|
||||
}
|
||||
|
||||
if ( isset( $_GET['status'] ) ) {
|
||||
$args['status'] = Sanitize::stringProp( 'status', $_GET );
|
||||
} elseif ( isset( $_GET['language'] ) ) {
|
||||
$args['language'] = Sanitize::stringProp( 'language', $_GET );
|
||||
}
|
||||
|
||||
if ( isset( $_GET['post_id'] ) ) {
|
||||
$args['post_id'] = filter_var( $_GET['post_id'], FILTER_SANITIZE_NUMBER_INT );
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
private function get_strings() {
|
||||
$strings = array(
|
||||
'page_title' => __( 'Translation Feedback', 'sitepress' ),
|
||||
'page_subtitle' => __( 'Issues with translations', 'sitepress' ),
|
||||
'table_header' => WPML_TF_Backend_Feedback_Row_View::get_columns_strings(),
|
||||
'screen_reader' => array(
|
||||
'select_all' => __( 'Select All', 'sitepress' ),
|
||||
),
|
||||
'pagination' => array(
|
||||
'list_navigation' => __( 'Feedback list navigation', 'sitepress' ),
|
||||
'first_page' => __( 'First page', 'sitepress' ),
|
||||
'previous_page' => __( 'Previous page', 'sitepress' ),
|
||||
'next_page' => __( 'Next page', 'sitepress' ),
|
||||
'last_page' => __( 'Last page', 'sitepress' ),
|
||||
'current_page' => __( 'Current page', 'sitepress' ),
|
||||
'of' => __( 'of', 'sitepress' ),
|
||||
),
|
||||
'bulk_actions' => array(
|
||||
'select' => __( 'Select bulk action', 'sitepress' ),
|
||||
'apply_button' => __( 'Apply', 'sitepress' ),
|
||||
'options' => array(
|
||||
'-1' => __( 'Bulk Actions', 'sitepress' ),
|
||||
'fixed' => __( 'Mark as fixed', 'sitepress' ),
|
||||
'pending' => __( 'Mark as new', 'sitepress' ),
|
||||
'trash' => __( 'Move to trash', 'sitepress' ),
|
||||
|
||||
),
|
||||
),
|
||||
'row_summary' => WPML_TF_Backend_Feedback_Row_View::get_summary_strings(),
|
||||
'row_details' => WPML_TF_Backend_Feedback_Row_View::get_details_strings(),
|
||||
'no_feedback' => __( 'No feedback found.', 'sitepress' ),
|
||||
);
|
||||
|
||||
if ( $this->feedback_query->is_in_trash() ) {
|
||||
$strings['bulk_actions']['options'] = array(
|
||||
'-1' => __( 'Bulk Actions', 'sitepress' ),
|
||||
'untrash' => __( 'Restore', 'sitepress' ),
|
||||
'delete' => __( 'Delete permanently', 'sitepress' ),
|
||||
|
||||
);
|
||||
}
|
||||
|
||||
return $strings;
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
private function get_columns() {
|
||||
$this->table_sort->set_primary_column( 'feedback' );
|
||||
|
||||
return array(
|
||||
'feedback' => array(
|
||||
'url' => $this->table_sort->get_column_url( 'feedback' ),
|
||||
'classes' => $this->table_sort->get_column_classes( 'feedback' ),
|
||||
),
|
||||
'rating' => array(
|
||||
'url' => $this->table_sort->get_column_url( 'rating' ),
|
||||
'classes' => $this->table_sort->get_column_classes( 'rating' ),
|
||||
),
|
||||
'status' => array(
|
||||
'url' => $this->table_sort->get_column_url( 'status' ),
|
||||
'classes' => $this->table_sort->get_column_classes( 'status' ),
|
||||
),
|
||||
'document_url' => array(
|
||||
'url' => $this->table_sort->get_column_url( 'document_title' ),
|
||||
'classes' => $this->table_sort->get_column_classes( 'document_title' ),
|
||||
),
|
||||
'date' => array(
|
||||
'url' => $this->table_sort->get_column_url( 'date' ),
|
||||
'classes' => $this->table_sort->get_column_classes( 'date' ),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
private function get_pagination( array $args ) {
|
||||
$this->pagination->set_total_items( $this->feedback_query->get_filtered_items_count() );
|
||||
$this->pagination->set_items_per_page( $args['items_per_page'] );
|
||||
$this->pagination->set_current_page( $args['paged'] );
|
||||
|
||||
return array(
|
||||
'first_page' => $this->pagination->get_first_page_url(),
|
||||
'previous_page' => $this->pagination->get_previous_page_url(),
|
||||
'next_page' => $this->pagination->get_next_page_url(),
|
||||
'last_page' => $this->pagination->get_last_page_url(),
|
||||
'current_page' => $this->pagination->get_current_page(),
|
||||
'total_pages' => $this->pagination->get_total_pages(),
|
||||
'total_items' => sprintf(
|
||||
_n( '%s item', '%s items', $this->pagination->get_total_items() ),
|
||||
$this->pagination->get_total_items()
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
private function get_page_filters() {
|
||||
$this->page_filter->populate_counters_and_labels();
|
||||
|
||||
return array(
|
||||
'all_and_trash' => $this->page_filter->get_all_and_trash_data(),
|
||||
'statuses' => $this->page_filter->get_statuses_data(),
|
||||
'languages' => $this->page_filter->get_languages_data(),
|
||||
);
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
private function get_current_query() {
|
||||
return array(
|
||||
'filters' => $this->page_filter->get_current_filters(),
|
||||
'sorters' => $this->table_sort->get_current_sorters(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Feedback_Row_View
|
||||
*/
|
||||
class WPML_TF_Backend_Feedback_Row_View {
|
||||
|
||||
const TEMPLATE_FOLDER = '/templates/translation-feedback/backend/';
|
||||
const SUMMARY_TEMPLATE = 'feedback-list-page-table-row.twig';
|
||||
const DETAILS_TEMPLATE = 'feedback-list-page-table-row-details.twig';
|
||||
|
||||
/** @var IWPML_Template_Service $template_service */
|
||||
private $template_service;
|
||||
|
||||
/**
|
||||
* WPML_TF_Backend_Feedback_Row_View constructor.
|
||||
*
|
||||
* @param IWPML_Template_Service $template_service
|
||||
*/
|
||||
public function __construct( IWPML_Template_Service $template_service ) {
|
||||
$this->template_service = $template_service;
|
||||
}
|
||||
|
||||
/** @param WPML_TF_Feedback $feedback */
|
||||
public function render_summary_row( WPML_TF_Feedback $feedback ) {
|
||||
$model = array(
|
||||
'strings' => self::get_summary_strings(),
|
||||
'has_admin_capabilities' => current_user_can( 'manage_options' ),
|
||||
'feedback' => $feedback,
|
||||
);
|
||||
|
||||
return $this->template_service->show( $model, self::SUMMARY_TEMPLATE );
|
||||
}
|
||||
|
||||
/** @param WPML_TF_Feedback $feedback */
|
||||
public function render_details_row( WPML_TF_Feedback $feedback ) {
|
||||
$model = array(
|
||||
'strings' => self::get_details_strings(),
|
||||
'has_admin_capabilities' => current_user_can( 'manage_options' ),
|
||||
'feedback' => $feedback,
|
||||
);
|
||||
|
||||
return $this->template_service->show( $model, self::DETAILS_TEMPLATE );
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
public static function get_columns_strings() {
|
||||
return array(
|
||||
'feedback' => __( 'Feedback', 'sitepress' ),
|
||||
'rating' => __( 'Rating', 'sitepress' ),
|
||||
'status' => __( 'Status', 'sitepress' ),
|
||||
'document' => __( 'Translated post', 'sitepress' ),
|
||||
'date' => __( 'Date', 'sitepress' ),
|
||||
);
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
public static function get_summary_strings() {
|
||||
return array(
|
||||
'select_validation' => __( 'Select Validation', 'sitepress' ),
|
||||
'inline_actions' => array(
|
||||
'review' => __( 'Review', 'sitepress' ),
|
||||
'trash' => __( 'Trash', 'sitepress' ),
|
||||
'view_post' => __( 'View post', 'sitepress' ),
|
||||
'untrash' => __( 'Restore', 'sitepress' ),
|
||||
'delete' => __( 'Delete permanently', 'sitepress' ),
|
||||
),
|
||||
'columns' => self::get_columns_strings(),
|
||||
);
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
public static function get_details_strings() {
|
||||
return array(
|
||||
'title' => __( 'Translation Feedback', 'sitepress' ),
|
||||
'translation' => __( 'Translation:', 'sitepress' ),
|
||||
'edit_translation' => __( 'Edit translation', 'sitepress' ),
|
||||
'original_post' => __( 'Original post:', 'sitepress' ),
|
||||
'rating' => __( 'Rating:', 'sitepress' ),
|
||||
'feedback' => __( 'Feedback:', 'sitepress' ),
|
||||
'edit_feedback' => __( 'Edit feedback', 'sitepress' ),
|
||||
'status' => __( 'Status:', 'sitepress' ),
|
||||
'refresh_status' => __( 'Check for updates', 'sitepress' ),
|
||||
'translated_by' => __( 'Translated by:', 'sitepress' ),
|
||||
'corrected_by' => __( 'Corrected by:', 'sitepress' ),
|
||||
'reviewed_by' => __( 'Reviewed by:', 'sitepress' ),
|
||||
'add_note_to_translator' => __( 'Add a note to the translator', 'sitepress' ),
|
||||
'add_note_to_admin' => __( 'Add a note to the administrator', 'sitepress' ),
|
||||
'communication' => __( 'Communication:', 'sitepress' ),
|
||||
'reply_to_translator_label' => __( 'Reply to translator:', 'sitepress' ),
|
||||
'reply_to_admin_label' => __( 'Reply to admin:', 'sitepress' ),
|
||||
'cancel_button' => __( 'Cancel', 'sitepress' ),
|
||||
'trash_button' => __( 'Trash', 'sitepress' ),
|
||||
'translation_fixed_button' => __( 'Mark as fixed', 'sitepress' ),
|
||||
'no_translator_available' => __( 'No translator available for this language pair.', 'sitepress' ),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,292 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Backend_Options_View
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Backend_Options_View {
|
||||
|
||||
const TEMPLATE_FOLDER = '/templates/translation-feedback/backend/';
|
||||
const TEMPLATE = 'options-ui.twig';
|
||||
const MAX_EXPIRATION_QUANTITY = 10;
|
||||
|
||||
/** @var IWPML_Template_Service $template_service */
|
||||
private $template_service;
|
||||
|
||||
/** @var WPML_TF_Settings $settings */
|
||||
private $settings;
|
||||
|
||||
/** @var SitePress $sitepress */
|
||||
private $sitepress;
|
||||
|
||||
/**
|
||||
* WPML_TF_Frontend_Hooks constructor.
|
||||
*
|
||||
* @param IWPML_Template_Service $template_service
|
||||
* @param WPML_TF_Settings $settings
|
||||
* @param SitePress $sitepress
|
||||
*/
|
||||
public function __construct(
|
||||
IWPML_Template_Service $template_service,
|
||||
WPML_TF_Settings $settings,
|
||||
SitePress $sitepress
|
||||
) {
|
||||
$this->template_service = $template_service;
|
||||
$this->settings = $settings;
|
||||
$this->sitepress = $sitepress;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function render() {
|
||||
$model = array(
|
||||
'strings' => self::get_strings(),
|
||||
'action' => WPML_TF_Backend_Options_AJAX_Hooks_Factory::AJAX_ACTION,
|
||||
'nonce' => wp_create_nonce( WPML_TF_Backend_Options_AJAX_Hooks_Factory::AJAX_ACTION ),
|
||||
'module_toggle' => $this->get_module_toggle(),
|
||||
'button_modes' => $this->get_button_modes(),
|
||||
'icon_styles' => $this->get_icon_styles(),
|
||||
'languages_to' => $this->get_languages_to(),
|
||||
'display_modes' => $this->get_display_modes(),
|
||||
'expiration_modes' => $this->get_expiration_modes(),
|
||||
'expiration_quantities' => $this->get_expiration_quantities(),
|
||||
'expiration_units' => $this->get_expiration_units(),
|
||||
);
|
||||
|
||||
return $this->template_service->show( $model, self::TEMPLATE );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
public static function get_strings() {
|
||||
return array(
|
||||
'section_title' => __( 'Translation Feedback', 'sitepress' ),
|
||||
'button_mode_section_title' => __( 'Translation Feedback button on front-end:', 'sitepress' ),
|
||||
'icon_style_section_title' => __( 'Icon style:', 'sitepress' ),
|
||||
'languages_to_section_title' => __( 'Show Translation Feedback module for these languages:', 'sitepress' ),
|
||||
'expiration_section_title' => __( 'Expiration date for Translation Feedback module:', 'sitepress' ),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_module_toggle() {
|
||||
return array(
|
||||
'value' => 1,
|
||||
'label' => __( 'Enable Translation Feedback module', 'sitepress' ),
|
||||
'selected' => $this->settings->is_enabled(),
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_button_modes() {
|
||||
$modes = array(
|
||||
WPML_TF_Settings::BUTTON_MODE_LEFT => array(
|
||||
'value' => WPML_TF_Settings::BUTTON_MODE_LEFT,
|
||||
'label' => __( 'Show on the left side of the screen', 'sitepress' ),
|
||||
'selected' => false,
|
||||
),
|
||||
WPML_TF_Settings::BUTTON_MODE_RIGHT => array(
|
||||
'value' => WPML_TF_Settings::BUTTON_MODE_RIGHT,
|
||||
'label' => __( 'Show on the right side of the screen', 'sitepress' ),
|
||||
'selected' => false,
|
||||
),
|
||||
WPML_TF_Settings::BUTTON_MODE_CUSTOM => array(
|
||||
'value' => WPML_TF_Settings::BUTTON_MODE_CUSTOM,
|
||||
'label' => __( 'I will add it manually (%1$sinstructions%2$s)', 'sitepress' ),
|
||||
'link' => 'https://wpml.org/wpml-hook/wpml_tf_feedback_open_link/?utm_source=plugin&utm_medium=gui&utm_campaign=wpmlcore',
|
||||
'selected' => false,
|
||||
),
|
||||
WPML_TF_Settings::BUTTON_MODE_DISABLED => array(
|
||||
'value' => WPML_TF_Settings::BUTTON_MODE_DISABLED,
|
||||
'label' => __( 'Do not show it', 'sitepress' ),
|
||||
'selected' => false,
|
||||
),
|
||||
);
|
||||
|
||||
if ( isset( $modes[ $this->settings->get_button_mode() ] ) ) {
|
||||
$modes[ $this->settings->get_button_mode() ]['selected'] = true;
|
||||
}
|
||||
|
||||
return $modes;
|
||||
}
|
||||
|
||||
private function get_icon_styles() {
|
||||
$css_classes = WPML_TF_Frontend_Feedback_View::get_icon_css_classes();
|
||||
|
||||
$styles = array(
|
||||
WPML_TF_Settings::ICON_STYLE_LEGACY => array(
|
||||
'value' => WPML_TF_Settings::ICON_STYLE_LEGACY,
|
||||
'image_class' => $css_classes[ WPML_TF_Settings::ICON_STYLE_LEGACY ],
|
||||
'selected' => false,
|
||||
),
|
||||
WPML_TF_Settings::ICON_STYLE_STAR => array(
|
||||
'value' => WPML_TF_Settings::ICON_STYLE_STAR,
|
||||
'image_class' => $css_classes[ WPML_TF_Settings::ICON_STYLE_STAR ],
|
||||
'selected' => false,
|
||||
),
|
||||
WPML_TF_Settings::ICON_STYLE_THUMBSUP => array(
|
||||
'value' => WPML_TF_Settings::ICON_STYLE_THUMBSUP,
|
||||
'image_class' => $css_classes[ WPML_TF_Settings::ICON_STYLE_THUMBSUP ],
|
||||
'selected' => false,
|
||||
),
|
||||
WPML_TF_Settings::ICON_STYLE_BULLHORN => array(
|
||||
'value' => WPML_TF_Settings::ICON_STYLE_BULLHORN,
|
||||
'image_class' => $css_classes[ WPML_TF_Settings::ICON_STYLE_BULLHORN ],
|
||||
'selected' => false,
|
||||
),
|
||||
WPML_TF_Settings::ICON_STYLE_COMMENT => array(
|
||||
'value' => WPML_TF_Settings::ICON_STYLE_COMMENT,
|
||||
'image_class' => $css_classes[ WPML_TF_Settings::ICON_STYLE_COMMENT ],
|
||||
'selected' => false,
|
||||
),
|
||||
WPML_TF_Settings::ICON_STYLE_QUOTE => array(
|
||||
'value' => WPML_TF_Settings::ICON_STYLE_QUOTE,
|
||||
'image_class' => $css_classes[ WPML_TF_Settings::ICON_STYLE_QUOTE ],
|
||||
'selected' => false,
|
||||
),
|
||||
);
|
||||
|
||||
if ( isset( $styles[ $this->settings->get_icon_style() ] ) ) {
|
||||
$styles[ $this->settings->get_icon_style() ]['selected'] = true;
|
||||
}
|
||||
|
||||
return $styles;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_languages_to() {
|
||||
$languages_to = array();
|
||||
$active_languages = $this->sitepress->get_active_languages();
|
||||
$allowed_languages = $this->settings->get_languages_to();
|
||||
|
||||
if ( null === $allowed_languages ) {
|
||||
$allowed_languages = array_keys( $active_languages );
|
||||
}
|
||||
|
||||
foreach ( $active_languages as $code => $language ) {
|
||||
$languages_to[ $code ] = array(
|
||||
'value' => $code,
|
||||
'label' => $language['display_name'],
|
||||
'flag_url' => $this->sitepress->get_flag_url( $code ),
|
||||
'selected' => false,
|
||||
);
|
||||
|
||||
if ( in_array( $code, $allowed_languages ) ) {
|
||||
$languages_to[ $code ]['selected'] = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $languages_to;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_display_modes() {
|
||||
$modes = array(
|
||||
WPML_TF_Settings::DISPLAY_CUSTOM => array(
|
||||
'value' => WPML_TF_Settings::DISPLAY_CUSTOM,
|
||||
'label' => esc_html__( 'Ask for feedback about translated content that was %1$s in the last %2$s %3$s', 'sitepress' ),
|
||||
'selected' => false,
|
||||
),
|
||||
WPML_TF_Settings::DISPLAY_ALWAYS => array(
|
||||
'value' => WPML_TF_Settings::DISPLAY_ALWAYS,
|
||||
'label' => __( 'Always ask for feedback (no time limit for feedback)', 'sitepress' ),
|
||||
'selected' => false,
|
||||
),
|
||||
);
|
||||
|
||||
if ( isset( $modes[ $this->settings->get_display_mode() ] ) ) {
|
||||
$modes[ $this->settings->get_display_mode() ]['selected'] = true;
|
||||
}
|
||||
|
||||
return $modes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_expiration_modes() {
|
||||
$modes = array(
|
||||
WPML_TF_Settings::EXPIRATION_ON_PUBLISH_OR_UPDATE => array(
|
||||
'value' => WPML_TF_Settings::EXPIRATION_ON_PUBLISH_OR_UPDATE,
|
||||
'label' => __( 'published or updated', 'sitepress' ),
|
||||
'selected' => false,
|
||||
),
|
||||
WPML_TF_Settings::EXPIRATION_ON_PUBLISH_ONLY => array(
|
||||
'value' => WPML_TF_Settings::EXPIRATION_ON_PUBLISH_ONLY,
|
||||
'label' => __( 'published', 'sitepress' ),
|
||||
'selected' => false,
|
||||
),
|
||||
WPML_TF_Settings::EXPIRATION_ON_UPDATE_ONLY => array(
|
||||
'value' => WPML_TF_Settings::EXPIRATION_ON_UPDATE_ONLY,
|
||||
'label' => __( 'updated', 'sitepress' ),
|
||||
'selected' => false,
|
||||
),
|
||||
);
|
||||
|
||||
if ( isset( $modes[ $this->settings->get_expiration_mode() ] ) ) {
|
||||
$modes[ $this->settings->get_expiration_mode() ]['selected'] = true;
|
||||
}
|
||||
|
||||
return $modes;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_expiration_quantities() {
|
||||
$quantities = array();
|
||||
|
||||
for ( $i = 1; $i < self::MAX_EXPIRATION_QUANTITY + 1; $i++ ) {
|
||||
$quantities[ $i ] = array(
|
||||
'value' => $i,
|
||||
'selected' => false,
|
||||
);
|
||||
}
|
||||
|
||||
if ( isset( $quantities[ $this->settings->get_expiration_delay_quantity() ] ) ) {
|
||||
$quantities[ $this->settings->get_expiration_delay_quantity() ]['selected'] = true;
|
||||
}
|
||||
|
||||
return $quantities;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_expiration_units() {
|
||||
$units = array(
|
||||
WPML_TF_Settings::DELAY_DAY => array(
|
||||
'value' => WPML_TF_Settings::DELAY_DAY,
|
||||
'label' => __( 'day(s)', 'sitepress' ),
|
||||
'selected' => false,
|
||||
),
|
||||
WPML_TF_Settings::DELAY_WEEK => array(
|
||||
'value' => WPML_TF_Settings::DELAY_WEEK,
|
||||
'label' => __( 'week(s)', 'sitepress' ),
|
||||
'selected' => false,
|
||||
),
|
||||
WPML_TF_Settings::DELAY_MONTH => array(
|
||||
'value' => WPML_TF_Settings::DELAY_MONTH,
|
||||
'label' => __( 'month(s)', 'sitepress' ),
|
||||
'selected' => false,
|
||||
),
|
||||
);
|
||||
|
||||
if ( isset( $units[ $this->settings->get_expiration_delay_unit() ] ) ) {
|
||||
$units[ $this->settings->get_expiration_delay_unit() ]['selected'] = true;
|
||||
}
|
||||
|
||||
return $units;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,159 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Frontend_Feedback_View
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Frontend_Feedback_View {
|
||||
|
||||
const TEMPLATE_FOLDER = '/templates/translation-feedback/frontend/';
|
||||
const FORM_TEMPLATE = 'feedback-form.twig';
|
||||
const OPEN_TEMPLATE = 'feedback-open-button.twig';
|
||||
const CUSTOM_OPEN_LINK_TEMPLATE = 'feedback-custom-open-link.twig';
|
||||
const JS_OPEN_NODE_CLASS = 'js-wpml-tf-feedback-icon';
|
||||
|
||||
/** @var IWPML_Template_Service $template_service */
|
||||
private $template_service;
|
||||
|
||||
/** @var SitePress $sitepress */
|
||||
private $sitepress;
|
||||
|
||||
/** @var WPML_Queried_Object $queried_object */
|
||||
private $queried_object;
|
||||
|
||||
/** @var WPML_TF_Settings $settings */
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* WPML_TF_Frontend_Hooks constructor.
|
||||
*
|
||||
* @param IWPML_Template_Service $template_service
|
||||
* @param SitePress $sitepress
|
||||
* @param WPML_Queried_Object $queried_object
|
||||
* @param WPML_TF_Settings $settings
|
||||
*/
|
||||
public function __construct(
|
||||
IWPML_Template_Service $template_service,
|
||||
SitePress $sitepress,
|
||||
WPML_Queried_Object $queried_object,
|
||||
WPML_TF_Settings $settings
|
||||
) {
|
||||
$this->template_service = $template_service;
|
||||
$this->sitepress = $sitepress;
|
||||
$this->queried_object = $queried_object;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function render_form() {
|
||||
$model = array(
|
||||
'strings' => array(
|
||||
'dialog_title' => __( 'Rate translation', 'sitepress' ),
|
||||
'thank_you_rating' => __( 'Thank you for your rating!', 'sitepress' ),
|
||||
'thank_you_comment' => __( 'Thank you for your rating and comment!', 'sitepress' ),
|
||||
'translated_from' => __( 'This page was translated from:', 'sitepress' ),
|
||||
'please_rate' => __( 'Please rate this translation:', 'sitepress' ),
|
||||
'your_rating' => __( 'Your rating:', 'sitepress' ),
|
||||
'star5_title' => __( 'It is perfect!', 'sitepress' ),
|
||||
'star4_title' => __( 'It is OK', 'sitepress' ),
|
||||
'star3_title' => __( 'It could be improved', 'sitepress' ),
|
||||
'star2_title' => __( 'I can see a lot of language errors', 'sitepress' ),
|
||||
'star1_title' => __( "I can't understand anything", 'sitepress' ),
|
||||
'change_rating' => __( 'Change', 'sitepress' ),
|
||||
'error_examples' => __( 'Please give some examples of errors and how would you improve them:', 'sitepress' ),
|
||||
'send_button' => __( 'Send', 'sitepress' ),
|
||||
'honeypot_label' => __( 'If you are a human, do not fill in this field.', 'sitepress' ),
|
||||
),
|
||||
'flag_url' => $this->sitepress->get_flag_url( $this->queried_object->get_source_language_code() ),
|
||||
'language_name' => $this->sitepress->get_display_language_name( $this->queried_object->get_source_language_code() ),
|
||||
'document_id' => $this->queried_object->get_id(),
|
||||
'document_type' => $this->queried_object->get_element_type(),
|
||||
'action' => WPML_TF_Frontend_AJAX_Hooks_Factory::AJAX_ACTION,
|
||||
'nonce' => wp_create_nonce( WPML_TF_Frontend_AJAX_Hooks_Factory::AJAX_ACTION ),
|
||||
'source_url' => $this->queried_object->get_source_url(),
|
||||
);
|
||||
|
||||
return $this->template_service->show( $model, self::FORM_TEMPLATE );
|
||||
}
|
||||
|
||||
/**
|
||||
* @return string
|
||||
*/
|
||||
public function render_open_button() {
|
||||
$rendering = '';
|
||||
|
||||
if ( WPML_TF_Settings::BUTTON_MODE_CUSTOM !== $this->settings->get_button_mode() ) {
|
||||
$model = array(
|
||||
'strings' => array(
|
||||
'form_open_title' => __( 'Rate translation of this page', 'sitepress' ),
|
||||
),
|
||||
'wrapper_css_classes' => $this->get_wrapper_css_classes(),
|
||||
'icon_css_class' => $this->get_icon_css_class(),
|
||||
);
|
||||
|
||||
$rendering = $this->template_service->show( $model, self::OPEN_TEMPLATE );
|
||||
}
|
||||
|
||||
return $rendering;
|
||||
}
|
||||
|
||||
/** @return string */
|
||||
private function get_wrapper_css_classes() {
|
||||
$base_classes = self::JS_OPEN_NODE_CLASS . ' wpml-tf-feedback-icon ';
|
||||
$class = $base_classes . 'wpml-tf-feedback-icon-left';
|
||||
|
||||
if ( WPML_TF_Settings::BUTTON_MODE_RIGHT === $this->settings->get_button_mode() ) {
|
||||
$class = $base_classes . 'wpml-tf-feedback-icon-right';
|
||||
}
|
||||
|
||||
return $class;
|
||||
}
|
||||
|
||||
/** @return string */
|
||||
private function get_icon_css_class() {
|
||||
$icon_style = $this->settings->get_icon_style();
|
||||
$css_classes = self::get_icon_css_classes();
|
||||
|
||||
if ( array_key_exists( $icon_style, $css_classes ) ) {
|
||||
return $css_classes[ $icon_style ];
|
||||
}
|
||||
|
||||
return $css_classes[ WPML_TF_Settings::ICON_STYLE_LEGACY ];
|
||||
}
|
||||
|
||||
/**
|
||||
* @param string|array $args
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function render_custom_open_link( $args ) {
|
||||
$model = wp_parse_args( $args, self::get_default_arguments_for_open_link() );
|
||||
|
||||
$model['classes'] = self::JS_OPEN_NODE_CLASS . ' ' . $model['classes'];
|
||||
|
||||
return $this->template_service->show( $model, self::CUSTOM_OPEN_LINK_TEMPLATE );
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
public static function get_default_arguments_for_open_link() {
|
||||
return array(
|
||||
'title' => __( 'Rate translation of this page', 'sitepress' ),
|
||||
'classes' => 'wpml-tf-feedback-custom-link',
|
||||
);
|
||||
}
|
||||
|
||||
/** @return array */
|
||||
public static function get_icon_css_classes() {
|
||||
return array(
|
||||
WPML_TF_Settings::ICON_STYLE_LEGACY => 'otgs-ico-translation',
|
||||
WPML_TF_Settings::ICON_STYLE_STAR => 'otgs-ico-star',
|
||||
WPML_TF_Settings::ICON_STYLE_THUMBSUP => 'otgs-ico-thumbsup',
|
||||
WPML_TF_Settings::ICON_STYLE_BULLHORN => 'otgs-ico-bullhorn',
|
||||
WPML_TF_Settings::ICON_STYLE_COMMENT => 'otgs-ico-comment',
|
||||
WPML_TF_Settings::ICON_STYLE_QUOTE => 'otgs-ico-quote',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_Module
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_Module {
|
||||
|
||||
/** @var WPML_Action_Filter_Loader $action_filter_loader */
|
||||
private $action_filter_loader;
|
||||
|
||||
/** @var WPML_TF_Settings $settings */
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* WPML_TF_Module constructor.
|
||||
*
|
||||
* @param WPML_Action_Filter_Loader $action_filter_loader
|
||||
* @param IWPML_TF_Settings $settings
|
||||
*/
|
||||
public function __construct( WPML_Action_Filter_Loader $action_filter_loader, IWPML_TF_Settings $settings ) {
|
||||
$this->action_filter_loader = $action_filter_loader;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
public function run() {
|
||||
$this->action_filter_loader->load( $this->get_actions_to_load_always() );
|
||||
|
||||
if ( $this->settings->is_enabled() ) {
|
||||
$this->action_filter_loader->load( $this->get_actions_to_load_when_module_enabled() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_actions_to_load_always() {
|
||||
return array(
|
||||
'WPML_TF_Backend_Options_Hooks_Factory',
|
||||
'WPML_TF_Backend_Options_AJAX_Hooks_Factory',
|
||||
'WPML_TF_Backend_Promote_Hooks_Factory',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_actions_to_load_when_module_enabled() {
|
||||
return array(
|
||||
'WPML_TF_Common_Hooks_Factory',
|
||||
'WPML_TF_Backend_Hooks_Factory',
|
||||
'WPML_TF_Frontend_Hooks_Factory',
|
||||
'WPML_TF_Frontend_AJAX_Hooks_Factory',
|
||||
'WPML_TF_Backend_AJAX_Feedback_Edit_Hooks_Factory',
|
||||
'WPML_TF_Backend_Post_List_Hooks_Factory',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,56 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TM_TF_Module
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TM_TF_Module {
|
||||
|
||||
/** @var WPML_Action_Filter_Loader $action_filter_loader */
|
||||
private $action_filter_loader;
|
||||
|
||||
/** @var WPML_TF_Settings $settings */
|
||||
private $settings;
|
||||
|
||||
/**
|
||||
* WPML_TF_Module constructor.
|
||||
*
|
||||
* @param WPML_Action_Filter_Loader $action_filter_loader
|
||||
* @param WPML_TF_Settings $settings
|
||||
*/
|
||||
public function __construct( WPML_Action_Filter_Loader $action_filter_loader, WPML_TF_Settings $settings ) {
|
||||
$this->action_filter_loader = $action_filter_loader;
|
||||
$this->settings = $settings;
|
||||
}
|
||||
|
||||
public function run() {
|
||||
$this->action_filter_loader->load( $this->get_actions_to_load_always() );
|
||||
|
||||
if ( $this->settings->is_enabled() ) {
|
||||
$this->action_filter_loader->load( $this->get_actions_to_load_when_module_enabled() );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_actions_to_load_always() {
|
||||
return array(
|
||||
'WPML_TF_WP_Cron_Events_Factory',
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @return array
|
||||
*/
|
||||
private function get_actions_to_load_when_module_enabled() {
|
||||
return array(
|
||||
'WPML_TF_XML_RPC_Hooks_Factory',
|
||||
'WPML_TF_Translation_Service_Change_Hooks_Factory',
|
||||
'WPML_TF_Translation_Queue_Hooks_Factory',
|
||||
'WPML_TM_TF_Feedback_List_Hooks_Factory',
|
||||
'WPML_TM_TF_AJAX_Feedback_List_Hooks_Factory',
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,72 @@
|
||||
<?php
|
||||
|
||||
/**
|
||||
* Class WPML_TF_XML_RPC_Feedback_Update
|
||||
*
|
||||
* @author OnTheGoSystems
|
||||
*/
|
||||
class WPML_TF_XML_RPC_Feedback_Update {
|
||||
|
||||
/** @var WPML_TF_Data_Object_Storage $feedback_storage */
|
||||
private $feedback_storage;
|
||||
|
||||
/** @var WPML_TP_Project $tp_project */
|
||||
private $tp_project;
|
||||
|
||||
public function __construct( WPML_TF_Data_Object_Storage $feedback_storage, WPML_TP_Project $tp_project ) {
|
||||
$this->feedback_storage = $feedback_storage;
|
||||
$this->tp_project = $tp_project;
|
||||
}
|
||||
|
||||
public function set_status( array $args ) {
|
||||
if ( $this->valid_arguments( $args ) ) {
|
||||
$feedback = $this->get_feedback( $args['feedback']['id'] );
|
||||
|
||||
if ( $feedback ) {
|
||||
/** @var WPML_TF_Feedback $feedback */
|
||||
$feedback->set_status( $args['feedback']['status'] );
|
||||
$this->feedback_storage->persist( $feedback );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @param array $args
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function valid_arguments( array $args ) {
|
||||
$valid = false;
|
||||
|
||||
if ( isset( $args['feedback']['id'], $args['feedback']['status'], $args['authorization_hash'] ) ) {
|
||||
$expected_hash = sha1( $this->tp_project->get_id() . $this->tp_project->get_access_key() . $args['feedback']['id'] );
|
||||
|
||||
if ( $expected_hash === $args['authorization_hash'] ) {
|
||||
$valid = true;
|
||||
}
|
||||
}
|
||||
|
||||
return $valid;
|
||||
}
|
||||
|
||||
/**
|
||||
* @param int $tp_feedback_id
|
||||
*
|
||||
* @return null|WPML_TF_Feedback
|
||||
*/
|
||||
private function get_feedback( $tp_feedback_id ) {
|
||||
$feedback = null;
|
||||
$filter_args = array(
|
||||
'tp_feedback_id' => $tp_feedback_id,
|
||||
);
|
||||
|
||||
$collection_filter = new WPML_TF_Feedback_Collection_Filter( $filter_args );
|
||||
$collection = $this->feedback_storage->get_collection( $collection_filter );
|
||||
|
||||
if ( $collection->count() ) {
|
||||
$feedback = $collection->current();
|
||||
}
|
||||
|
||||
return $feedback;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user