Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
- Changing post's language via bulk edit (#66).
- Filter for posts without language or unknown languages in the back-office post list for translatable post types.
- Filter `ubb_translatable_routes` for routes outside of post/term/archives that the user wants to be available in other languages when using the method `LangInterface::translate_current_url()`.
- `SDK\LanguageContext` to provide a more human readable interface for language context switching.

### Changed

Expand Down
41 changes: 21 additions & 20 deletions lib/LangInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
use TwentySixB\WP\Plugin\Unbabble\DB\PostTable;
use TwentySixB\WP\Plugin\Unbabble\DB\TermTable;
use TwentySixB\WP\Plugin\Unbabble\Options;
use TwentySixB\WP\Plugin\Unbabble\SDK\LanguageContext;
use WP_Post;
use WP_Query;
use WP_Term;
Expand Down Expand Up @@ -135,7 +136,7 @@ public static function get_current_language() : string {
*
* @param string $language Current language.
*/
return apply_filters( 'ubb_current_lang', \sanitize_text_field( $lang ) );
return \apply_filters( 'ubb_current_lang', \sanitize_text_field( $lang ) );
}

/**
Expand Down Expand Up @@ -939,21 +940,21 @@ public static function translate_current_url( string $lang ) : string {

// Try to translate posts archive url.
if ( $wp_the_query instanceof WP_Query && $wp_the_query->is_posts_page ) {
add_filter( 'ubb_current_lang', $fn = fn () => $lang );
$page_for_posts = get_option( 'page_for_posts' );
$home_url = home_url();
remove_filter( 'ubb_current_lang', $fn );
LanguageContext::switch_to_language( $lang );
$page_for_posts = \get_option( 'page_for_posts' );
$home_url = \home_url();
LanguageContext::restore_language();
if ( empty( $page_for_posts ) ) {
return $home_url;
}
return get_permalink( $page_for_posts );
return \get_permalink( $page_for_posts );
}

// Try to translate a post types archive url.
if ( $wp_the_query instanceof WP_Query && $wp_the_query->is_post_type_archive() ) {
add_filter( 'ubb_current_lang', $fn = fn () => $lang );
$archive_link = get_post_type_archive_link( $wp_the_query->query['post_type'] );
remove_filter( 'ubb_current_lang', $fn );
LanguageContext::switch_to_language( $lang );
$archive_link = \get_post_type_archive_link( $wp_the_query->query['post_type'] );
LanguageContext::restore_language();
return $archive_link;
}

Expand All @@ -964,17 +965,17 @@ public static function translate_current_url( string $lang ) : string {
) {
$term_id = $wp_the_query->queried_object->term_id ?? null;
if ( $term_id === null ) {
add_filter( 'ubb_current_lang', $fn = fn () => $lang );
LanguageContext::switch_to_language( $lang );
$home_url = home_url();
remove_filter( 'ubb_current_lang', $fn );
LanguageContext::restore_language();
return $home_url;
}

$translation = self::get_term_translation( $term_id, $lang );
if ( $translation ) {
add_filter( 'ubb_current_lang', $fn = fn () => $lang );
$translation_permalink = get_term_link( $translation );
remove_filter( 'ubb_current_lang', $fn );
LanguageContext::switch_to_language( $lang );
$translation_permalink = \get_term_link( $translation );
LanguageContext::restore_language();
return $translation_permalink;
}
}
Expand All @@ -983,17 +984,17 @@ public static function translate_current_url( string $lang ) : string {
if ( $wp_the_query instanceof WP_Query && $wp_the_query->is_singular() ) {
$post_id = $wp_the_query->queried_object->ID ?? null;
if ( $post_id === null ) {
add_filter( 'ubb_current_lang', $fn = fn () => $lang );
LanguageContext::switch_to_language( $lang );
$home_url = home_url();
remove_filter( 'ubb_current_lang', $fn );
LanguageContext::restore_language();
return $home_url;
}

$translation = self::get_post_translation( $post_id, $lang );
if ( $translation ) {
add_filter( 'ubb_current_lang', $fn = fn () => $lang );
LanguageContext::switch_to_language( $lang );
$translation_permalink = get_permalink( $translation );
remove_filter( 'ubb_current_lang', $fn );
LanguageContext::restore_language();
return $translation_permalink;
}
}
Expand Down Expand Up @@ -1042,9 +1043,9 @@ public static function translate_current_url( string $lang ) : string {
}

// Default to home_url of the language.
add_filter( 'ubb_current_lang', $fn = fn () => $lang );
LanguageContext::switch_to_language( $lang );
$lang_link = home_url();
remove_filter( 'ubb_current_lang', $fn );
LanguageContext::restore_language();
return $lang_link;
}

Expand Down
5 changes: 3 additions & 2 deletions lib/Router/Directory.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use TwentySixB\WP\Plugin\Unbabble\LangInterface;
use TwentySixB\WP\Plugin\Unbabble\Options;
use TwentySixB\WP\Plugin\Unbabble\SDK\LanguageContext;
use WP_Post;
use WP_Term;

Expand Down Expand Up @@ -440,7 +441,7 @@ public function network_home_url( string $url, string $path ) : string {
$curr_origin_lang !== LangInterface::get_default_language()
&& LangInterface::is_language_allowed( $curr_origin_lang )
) {
add_filter( 'ubb_current_lang', $fn = fn () => $curr_origin_lang );
LanguageContext::switch_to_language( $curr_origin_lang );
$router_type = Options::get_router();
if ( $router_type === 'query_var' ) {
add_filter( 'ubb_home_url', '__return_true' );
Expand All @@ -450,7 +451,7 @@ public function network_home_url( string $url, string $path ) : string {
} else {
$new_url = home_url( $path );
}
remove_filter( 'ubb_current_lang', $fn );
LanguageContext::restore_language();
}
}
restore_current_blog();
Expand Down
5 changes: 3 additions & 2 deletions lib/Router/QueryVar.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

use TwentySixB\WP\Plugin\Unbabble\LangInterface;
use TwentySixB\WP\Plugin\Unbabble\Options;
use TwentySixB\WP\Plugin\Unbabble\SDK\LanguageContext;
use WP_Post;
use WP_Term;

Expand Down Expand Up @@ -305,7 +306,7 @@ public function network_home_url( string $url, string $path ) : string {
$curr_origin_lang !== LangInterface::get_default_language()
&& LangInterface::is_language_allowed( $curr_origin_lang )
) {
add_filter( 'ubb_current_lang', $fn = fn () => $curr_origin_lang );
LanguageContext::switch_to_language( $curr_origin_lang );
$router_type = Options::get_router();
if ( $router_type === 'directory' ) {
add_filter( 'ubb_home_url', '__return_true' );
Expand All @@ -315,7 +316,7 @@ public function network_home_url( string $url, string $path ) : string {
} else {
$new_url = home_url( $path );
}
remove_filter( 'ubb_current_lang', $fn );
LanguageContext::restore_language();
}
}
restore_current_blog();
Expand Down
75 changes: 75 additions & 0 deletions lib/SDK/LanguageContext.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
<?php

namespace TwentySixB\WP\Plugin\Unbabble\SDK;

/**
* Provide an interface to switch language contexts.
*
* @since [unreleased]
*/
class LanguageContext {

/**
* The language stack.
*
* @since [unreleased]
*
* @var array
*/
static $language_stack = [];

/**
* Switch to the language at the top of the stack.
*
* @since [unreleased]
*
* @param string $lang The language to switch to.
* @return string
*/
private static function switch() {
return static::$language_stack[ count( static::$language_stack ) - 1 ];
}

/**
* Push a to a specific language.
*
* @since [unreleased]
*
* @param string $lang The language to switch to.
* @return void
*
* @throws \InvalidArgumentException If the language is empty.
*/
public static function switch_to_language( string $lang ) {

// Throw to prevent empty language issues.
if ( empty( $lang ) ) {
throw new \InvalidArgumentException( 'Language cannot be empty' );
}

// Add only one filter instance to the hook.
if ( empty( static::$language_stack ) ) {
\add_filter( 'ubb_current_lang', [ self::class, 'switch' ] );
}

static::$language_stack[] = $lang;
}

/**
* Restore the previous language in the stack.
*
* @since [unreleased]
*
* @return void
*/
public static function restore_language() {

// Take the last language off the stack.
array_pop( static::$language_stack );

// Remove the filter if the stack is empty.
if ( empty( static::$language_stack ) ) {
\remove_filter( 'ubb_current_lang', [ self::class, 'switch' ] );
}
}
}