Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

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

yoavf opened this issue Aug 28, 2016 · 2 comments

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

yoavf opened this issue Aug 28, 2016 · 2 comments


Copy link

@yoavf yoavf commented Aug 28, 2016

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.*, as 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 = t.original_id AND t.translation_set_id = " . (int) $translation_set->id . " $join_where
+                       $join_type JOIN $wpdb->gp_translations AS t ON = 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.

Copy link

@toolstack toolstack commented Aug 31, 2016

Related to #226.

Copy link

@ocean90 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:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
None yet
Linked pull requests

Successfully merging a pull request may close this issue.

None yet
3 participants