wenpai.org/wp-content/plugins/gp-translation-helpers/includes/class-gp-route-translation-helpers.php
2024-06-21 23:57:39 +08:00

428 lines
14 KiB
PHP

<?php
/**
* Routes: GP_Route_Translation_Helpers class
*
* @package gp-translation-helpers
* @since 0.0.1
*/
class GP_Route_Translation_Helpers extends GP_Route {
/**
* Stores an instance of each helper.
*
* @since 0.0.1
* @var array
*/
private $helpers = array();
/**
* GP_Route_Translation_Helpers constructor.
*
* @since 0.0.1
*/
public function __construct() {
$this->helpers = GP_Translation_Helpers::load_helpers();
$this->template_path = dirname( __FILE__ ) . '/../templates/';
}
/**
* Loads the 'discussions-dashboard' template.
*
* @since 0.0.2
*
* @param string|null $locale_slug Optional. The locale slug. E.g. "es".
*
* @return void
*/
public function discussions_dashboard( $locale_slug ) {
if ( ! is_user_logged_in() ) {
$this->die_with_404();
}
$user_id = wp_get_current_user()->ID;
$all_comments_post_ids = $this->get_comment_post_ids( $locale_slug );
$comments_count = count( $all_comments_post_ids );
$comment_post_ids = $all_comments_post_ids;
$participating = $this->get_user_comments( $locale_slug, $user_id );
$participating_post_ids = array_unique( array_column( $participating, 'comment_post_ID' ) );
$not_participating_post_ids = array_diff( $all_comments_post_ids, $participating_post_ids );
$comments_per_page = 12;
$page_num_from_query = (int) get_query_var( 'page' );
$offset = $page_num_from_query > 0 ? ( $page_num_from_query - 1 ) * $comments_per_page : 0;
$filter = isset( $_GET['filter'] ) ? esc_html( $_GET['filter'] ) : '';
$page_number = ( ! empty( $page_num_from_query ) && is_int( $page_num_from_query ) ) ? $page_num_from_query : 1;
$gp_locale = GP_Locales::by_slug( $locale_slug );
if ( 'participating' == $filter ) {
$comment_post_ids = $participating_post_ids;
$comments_count = count( $participating_post_ids );
}
if ( 'not_participating' == $filter ) {
$comment_post_ids = $not_participating_post_ids;
$comments_count = count( $not_participating_post_ids );
}
$total_pages = (int) ceil( $comments_count / $comments_per_page );
$post_ids = array();
$post_ids = array_splice( $comment_post_ids, $offset, $comments_per_page );
$args = array(
'meta_key' => 'locale',
'meta_value' => $locale_slug,
'post__in' => $post_ids,
);
$comments_query = new WP_Comment_Query( $args );
$comments = $comments_query->comments;
$this->tmpl( 'discussions-dashboard', get_defined_vars() );
}
/**
* Loads the 'original-permalink' template.
*
* @since 0.0.2
*
* @param string $project_path The project path. E.g. "wp/dev".
* @param int $original_id The original id. E.g. "2440".
* @param string|null $locale_slug Optional. The locale slug. E.g. "es".
* @param string $translation_set_slug The translation slug. E.g. "default".
* @param int|null $translation_id Optional. The translation id. E.g. "4525".
*
* @return void
*/
public function original_permalink( $project_path, $original_id, $locale_slug = null, $translation_set_slug = null, $translation_id = null ) {
$original = GP::$original->get( $original_id );
if ( ! $original ) {
$this->die_with_404();
}
$project = GP::$project->by_path( $project_path );
if ( ! $project ) {
$this->die_with_404();
}
if ( $project->id !== $original->project_id ) {
$project = GP::$project->get( $original->project_id );
// Let's use the parameters that we have to create a URL in the right project.
$corrected_url = self::get_permalink( $project->path, $original_id, $locale_slug, $translation_set_slug );
wp_safe_redirect( $corrected_url );
exit;
}
if ( ! $original ) {
$this->die_with_404();
}
$args = array(
'project_id' => $project->id,
'locale_slug' => $locale_slug,
'set_slug' => $translation_set_slug,
'original_id' => $original_id,
'translation_id' => $translation_id,
'project' => $project,
);
$translation_set = GP::$translation_set->by_project_id_slug_and_locale( $project->id, $translation_set_slug, $locale_slug );
$all_translation_sets = GP::$translation_set->by_project_id( $project->id );
$row_id = $original_id;
$translation = null;
if ( $translation_id ) {
$row_id .= '-' . $translation_id;
$translation = GP::$translation->get( $translation_id );
}
$original_permalink = gp_url_project( $project, array( 'filters[original_id]' => $original_id ) );
$original_translation_permalink = false;
if ( $translation_set ) {
$original_translation_permalink = gp_url_project_locale( $project, $locale_slug, $translation_set->slug, array( 'filters[original_id]' => $original_id ) );
}
/** Get translation for this original */
$existing_translations = array();
if ( ! $translation && $translation_set && $original_id ) {
$translation = GP::$translation->find_one(
array(
'status' => 'current',
'original_id' => $original_id,
'translation_set_id' => $translation_set->id,
)
);
if ( ! $translation ) {
$existing_translations = GP::$translation->find_many_no_map(
array(
'original_id' => $original_id,
'translation_set_id' => $translation_set->id,
)
);
usort(
$existing_translations,
function ( $t1, $t2 ) {
$cmp_prop_t1 = $t1->date_modified ?? $t1->date_added;
$cmp_prop_t2 = $t2->date_modified ?? $t2->date_added;
return $cmp_prop_t1 < $cmp_prop_t2;
}
);
// Something falsy is not enough.
$translation = null;
}
}
$priorities_key_value = $original->get_static( 'priorities' );
$priority = $priorities_key_value[ $original->priority ];
$args = compact( 'project', 'locale_slug', 'translation_set_slug', 'original_id', 'translation_id', 'translation', 'original_permalink' );
$sections = $this->get_translation_helper_sections( $args );
$translations = GP::$translation->find_many_no_map(
array(
'status' => 'current',
'original_id' => $original_id,
)
);
$no_of_translations = count( $translations );
add_action(
'gp_head',
function() use ( $original, $no_of_translations ) {
echo '<meta property="og:title" content="' . esc_html( $original->singular ) . ' | ' . esc_html( $no_of_translations ) . ' translations" />';
}
);
$this->tmpl( 'original-permalink', get_defined_vars() );
}
/**
* Gets the sections of each active helper.
*
* @param array $data The data to be passed on to the sections.
*
* @return array The translation helper sections.
*/
public function get_translation_helper_sections( $data ) {
$sections = array();
foreach ( $this->helpers as $helper => $translation_helper ) {
$translation_helper->set_data( $data );
if ( ! $translation_helper->activate() ) {
continue;
}
$sections[] = array(
'title' => $translation_helper->get_title(),
'content' => $translation_helper->get_output(),
'classname' => $translation_helper->get_div_classname(),
'id' => $translation_helper->get_div_id(),
'priority' => $translation_helper->get_priority(),
'has_async_content' => $translation_helper->has_async_content(),
'count' => $translation_helper->get_count(),
'load_inline' => $translation_helper->load_inline(),
'helper' => $helper,
);
}
usort(
$sections,
function( $s1, $s2 ) {
return $s1['priority'] <=> $s2['priority'];
}
);
return $sections;
}
/**
* Returns the content of each section (tab).
*
* @since 0.0.2
*
* @param string $project_path The project path. E.g. "wp/dev".
* @param string $locale_slug The locale slug. E.g. "es".
* @param string $set_slug The translation set slug. E.g. "default".
* @param int $original_id The original id. E.g. "2440".
* @param int|null $translation_id Optional. The translation id. E.g. "4525".
*
* @return string JSON with the content of each section.
*/
public function ajax_translation_helpers_locale( string $project_path, string $locale_slug, string $set_slug, int $original_id, int $translation_id = null ) {
return $this->ajax_translation_helpers( $project_path, $original_id, $translation_id, $locale_slug, $set_slug );
}
/**
* Returns the content of each section (tab).
*
* @since 0.0.1
*
* @param string $project_path The project path. E.g. "wp/dev".
* @param int $original_id The original id. E.g. "2440".
* @param int|null $translation_id Optional. The translation id. E.g. "4525".
* @param string|null $locale_slug The locale slug. E.g. "es".
* @param string|null $set_slug The translation set slug. E.g. "default".
*
* @return void Prints the JSON with the content of each section.
*/
public function ajax_translation_helpers( string $project_path, int $original_id, int $translation_id = null, string $locale_slug = null, string $set_slug = null ): void {
$project = GP::$project->by_path( $project_path );
if ( ! $project ) {
$this->die_with_404();
}
$permalink = self::get_permalink( $project->path, $original_id, $set_slug, $locale_slug );
$args = array(
'project_id' => $project->id,
'locale_slug' => $locale_slug,
'translation_set_slug' => $set_slug,
'original_id' => $original_id,
'translation_id' => $translation_id,
'permalink' => $permalink,
'project' => $project,
);
$selected = gp_get( 'helpers' );
if ( ! empty( $selected ) ) {
$helpers = array_filter(
$this->helpers,
function ( $key ) use ( $selected ) {
return in_array( $key, (array) $selected, true );
},
ARRAY_FILTER_USE_KEY
);
} else {
$helpers = $this->helpers;
}
$sections = array();
foreach ( $helpers as $translation_helper ) {
$translation_helper->set_data( $args );
if ( $translation_helper->has_async_content() && $translation_helper->activate() ) {
$sections[ $translation_helper->get_div_id() ] = array(
'content' => $translation_helper->get_async_output(),
'count' => $translation_helper->get_count(),
);
};
}
wp_send_json( $sections );
}
/**
* Gets the locales with comments.
*
* @since 0.0.2
*
* @param array|null $comments Array with comments.
*
* @return array Array with the locales with comments.
*/
private function get_locales_with_comments( ?array $comments ): array {
$comment_locales = array();
if ( $comments ) {
foreach ( $comments as $comment ) {
$comment_meta = get_comment_meta( $comment->comment_ID, 'locale' );
$single_comment_locale = is_array( $comment_meta ) && ! empty( $comment_meta ) ? $comment_meta[0] : '';
if ( $single_comment_locale && ! in_array( $single_comment_locale, $comment_locales, true ) ) {
$comment_locales[] = $single_comment_locale;
}
}
}
return $comment_locales;
}
/**
* Gets the full permalink.
*
* @since 0.0.2
*
* @param string $project_path The project path. E.g. "wp/dev".
* @param int|null $original_id The original id. E.g. "2440".
* @param string|null $set_slug The translation set slug. E.g. "default".
* @param string|null $locale_slug Optional. The locale slug. E.g. "es".
*
* @return string The full permalink.
*/
public static function get_permalink( string $project_path, ?int $original_id, string $set_slug = null, string $locale_slug = null ): string {
$permalink = $project_path . '/' . $original_id;
if ( $set_slug && $locale_slug ) {
$permalink .= '/' . $locale_slug . '/' . $set_slug;
}
return home_url( gp_url_project( $permalink ) );
}
/**
* Gets the translation permalink.
*
* @param GP_Project $project The project.
* @param string $locale_slug The locale slug.
* @param string $translation_set_slug The translation set slug.
* @param int $original_id The original id.
* @param int $translation_id The translation id.
*
* @return bool The translation permalink.
*/
public static function get_translation_permalink( $project, $locale_slug, $translation_set_slug, $original_id, $translation_id = null ) {
if ( ! $project || ! $locale_slug || ! $translation_set_slug || ! $original_id ) {
return false;
}
$args = array(
'filters[original_id]' => $original_id,
);
if ( $translation_id ) {
$args['filters[status]'] = 'either';
$args['filters[translation_id]'] = $translation_id;
}
$translation_permalink = gp_url_project_locale(
$project,
$locale_slug,
$translation_set_slug,
$args
);
return $translation_permalink;
}
/**
* Gets distinct post_ids for all comments made by user
*
* @param string $locale_slug The locale slug.
* @param int $user_id The user id.
*
* @return array The array of comment_post_IDs.
*/
private function get_user_comments( $locale_slug, $user_id ) {
$args = array(
'meta_key' => 'locale',
'meta_value' => $locale_slug,
'user_id' => $user_id,
);
$query = new WP_Comment_Query( $args );
$comments = $query->comments;
return $comments;
}
/**
* Run a query to fetch comment_post_ID of all comments
*
* @param string $locale_slug The locale slug.
*
* @return array Array of unique comment_post_IDs for all comments.
*/
private function get_comment_post_ids( $locale_slug ) {
global $wpdb;
return $wpdb->get_col(
$wpdb->prepare(
"SELECT DISTINCT {$wpdb->comments}.comment_post_ID FROM {$wpdb->comments} INNER JOIN {$wpdb->commentmeta} ON {$wpdb->comments}.comment_ID = {$wpdb->commentmeta}.comment_id WHERE meta_key='locale' AND meta_value = %s ORDER BY comment_date DESC",
$locale_slug
)
);
}
}