first commit

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

View File

@@ -0,0 +1,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();
}
}

View File

@@ -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 ] );
}
}
}
}

View File

@@ -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 );
}
}

View File

@@ -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 );
}
}

View File

@@ -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;
}
}

View File

@@ -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 );
}
}

View File

@@ -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;
}
}

View File

@@ -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' ),
);
}
}

View File

@@ -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();
}

View File

@@ -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 );
}

View File

@@ -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();
}
}

View File

@@ -0,0 +1,10 @@
<?php
/**
* Class WPML_TF_Message_Collection
*
* @author OnTheGoSystems
*/
class WPML_TF_Message_Collection extends WPML_TF_Collection {
}

View File

@@ -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 );
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}

View File

@@ -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;
}
}