Allow querying for translations with fallback to another translation set #524

Closed
yoavf opened this Issue Aug 28, 2016 · 2 comments

Projects

None yet

3 participants

@yoavf
Member
yoavf commented Aug 28, 2016 edited

We'd like to be able to plug into for_export()/for_translation() and make the functions fallback to an additional translation set in case no translation are found in the current set.

The use case: language variants, such as de_formal, where even if only a subset of the strings are translated, an export should fallback to de for the rest.

It's not possible to write this as 100% plugin without adding one or more filters to for_translation(), especially if attempting to prevent a serious performance hit. I'm happy to consider any alternatives, but here's an implementation path I'd like to propose:

  1. Add a filter to for_translation() that will expand the $sql_for_translations join to an additional translation set id.
+               /**
+                * Filter the translations sets to allow falling back to another translation set
+                *
+                * @since 2.2.0
+                *
+                * @param null Default for no additional translation set
+                * @param GP_Translation_Set $translation_set Current translation set.
+                */
+               $fallback_translation_set = apply_filters( 'gp_for_translation_fallback_translation_set', null, $translation_set );
+
+               $translation_sets = array( $translation_set->id );
+               if ( $fallback_translation_set ) {
+                       $translation_sets[] = (int) $fallback_translation_set;
+               }
+               $translation_sets = implode( ',', $translation_sets );
+
                $sql_for_translations = "
                        SELECT SQL_CALC_FOUND_ROWS t.*, o.*, t.id as id, o.id as original_id, t.status as translation_status, o.status as original_status, t.date_added as translation_added, o.date_added as original_added
                        FROM $wpdb->gp_originals as o
-                       $join_type JOIN $wpdb->gp_translations AS t ON o.id = t.original_id AND t.translation_set_id = " . (int) $translation_set->id . " $join_where
+                       $join_type JOIN $wpdb->gp_translations AS t ON o.id = t.original_id AND t.translation_set_id IN( " . $wpdb->esc_like( $translation_sets ) . " ) $join_where
                        WHERE o.project_id = " . (int) $project->id . " AND o.status = '+active' $where ORDER BY $sql_sort $limit";
                $rows = $this->many_no_map( $sql_for_translations );
                $this->found_rows = $this->found_rows();
  1. The $rows array may now contain two translations per original id. Filter using something like the following:
+               if ( $fallback_translation_set ) {
+                       $oids = array();
+                       foreach( $rows as $key => $val ) {
+                               if( in_array( $val->original_id, $oids ) ) {
+                                       if ( $val->translation_set_id === $translation_set->id ) {
+                                               $old_key = array_search( $val->original_id, $oids );
+                                               unset( $rows[ $old_key ] );
+                                               unset( $oids[ $old_key ] );
+                                               $this->found_rows--;
+                                       } else {
+                                               unset( $rows[ $key ] );
+                                               continue;
+                                       }
+                               }
+                               $oids[ $key ] = $val->original_id;
+                       }
+               }

I think the above is the minimal required core changes to enable this, but I'll be happy to be corrected.

Next, we'd want to enable plugins to style both the translation-row template and alter the translation editor so that translator are aware the translation they're seeing is a fallback, and can use it as a basis when editing.

The code here is just a POC. If this issue is accepted, I'll flesh it into a full PR with tests etc.

@toolstack
Contributor

Related to #226.

@ocean90
Member
ocean90 commented Sep 4, 2016

There was already some discussion on the PR (note for the future: general discussions should be held on the issue).

This should start in a plugin and GlotPress should only provide the filters to support the idea.

It seems like you need a way to filter $sql_for_translations and $rows. To make filtering the SQL easier we should separate the query into clauses which then can be filtered. Take WP_Term_Query as an example: https://github.com/WordPress/WordPress/blob/77a3cc733e52a444374235caf27b31744c3e028e/wp-includes/class-wp-term-query.php#L585-L635.

@ocean90 ocean90 added this to the 2.3 milestone Sep 20, 2016
@ocean90 ocean90 closed this in #530 Nov 28, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment