Plugin Directory

Changeset 3727697


Ignore:
Timestamp:
10/04/2026 06:19:43 PM (4 weeks ago)
Author:
adrianincode
Message:

Release 2.10.5: fix critical error when adding the Language Switcher widget; 301 for URLs with two language prefixes

Location:
incode-translate-master
Files:
79 added
4 edited

Legend:

Unmodified
Added
Removed
  • incode-translate-master/trunk/includes/class-language-switcher.php

    r3709678 r3727697  
    865865
    866866// ─── Classic WP Widget ────────────────────────────────────────────────────────
     867// get_display() es de WPTM_Language_Switcher, no de esta clase: con self:: un widget
     868// recién añadido (sin estilo guardado) daba error crítico en el editor (2.10.1–2.10.4).
    867869
    868870class WPTM_Language_Widget extends WP_Widget {
    … …  
    886888        // una sola línea, porque `phpcs:ignore` solo alcanza a la línea siguiente.
    887889        $html = WPTM_Language_Switcher::render([
    888             'display'      => ( $instance['display'] ?? '' ) ?: self::get_display(),
     890            'display'      => ( $instance['display'] ?? '' ) ?: WPTM_Language_Switcher::get_display(),
    889891            'show_flags'   => ($instance['show_flags']   ?? '1') !== '0',
    890892            'show_names'   => ($instance['show_names']   ?? '1') !== '0',
    … …  
    899901
    900902    public function form( $instance ): void {
    901         $d = ( $instance['display'] ?? '' ) ?: self::get_display();
     903        $d = ( $instance['display'] ?? '' ) ?: WPTM_Language_Switcher::get_display();
    902904        $l = $instance['layout']       ?? 'horizontal';
    903905        $f = $instance['show_flags']   ?? '1';
  • incode-translate-master/trunk/includes/class-url-manager.php

    r3688387 r3727697  
    258258        }
    259259
     260        // Dos prefijos de idioma seguidos (/de/en/blog/…): 301 a la URL con uno solo.
     261        $this->redirect_nested_language_prefix( $first, $parts, $request_uri );
     262
    260263        // Found a language slug
    261264        $this->current_language = $lang;
    … …  
    326329
    327330        wp_safe_redirect( $destino, 302 );
     331        exit;
     332    }
     333
     334    /**
     335     * Consolida con 301 las URLs con varios prefijos de idioma seguidos:
     336     * «/de/en/blog/x/» y «/de/en/en/blog/x/» → «/de/blog/x/».
     337     *
     338     * POR QUÉ. early_detect() solo quita el primer prefijo, así que
     339     * «/de/en/blog/x/» llegaba a WordPress como «/en/blog/x/», que resolvía la
     340     * entrada igualmente (redirect_canonical está bloqueado en URLs de idioma) y
     341     * la servía con 200, en alemán y con canonical a sí misma. Además, su hreflang
     342     * se calcula sobre «/en/blog/x/» y anuncia «/en/en/…» y «/fr/en/…», de modo
     343     * que cada URL anidada que Google encontraba le enseñaba tres más. En
     344     * adrianalcala.es llegaron a 22 URLs indexadas con 3.266 impresiones en
     345     * 90 días (medido el 25/09/2026).
     346     *
     347     * Gana el PRIMER prefijo porque es el idioma que se estaba sirviendo en esa
     348     * URL: el 301 lleva a Google a la misma página que tenía indexada.
     349     */
     350    private function redirect_nested_language_prefix( string $first, array $parts, string $request_uri ): void {
     351        if ( count( $parts ) < 2 )       return;
     352        if ( ! $this->is_get_request() ) return; // un POST perdería el cuerpo
     353        if ( headers_sent() )            return;
     354        if ( isset( $_GET['wc-ajax'] ) ) return;
     355
     356        $resto    = array_slice( $parts, 1 );
     357        $quitados = 0;
     358        while ( $resto && '' !== $resto[0] && WPTM_Language_Manager::get_language_by_slug( $resto[0] ) ) {
     359            array_shift( $resto );
     360            $quitados++;
     361        }
     362        if ( ! $quitados ) return;
     363
     364        $path    = wp_parse_url( $request_uri, PHP_URL_PATH ) ?? '/';
     365        $destino = '/' . $first . '/' . implode( '/', $resto );
     366        if ( substr( $path, -1 ) === '/' ) $destino = trailingslashit( $destino );
     367        $destino = untrailingslashit( get_option( 'home' ) ) . $destino;
     368
     369        $query = wp_parse_url( $request_uri, PHP_URL_QUERY );
     370        if ( $query ) $destino .= '?' . $query;
     371
     372        wp_safe_redirect( $destino, 301, 'Incode Translate Master' );
    328373        exit;
    329374    }
  • incode-translate-master/trunk/incode-translate-master.php

    r3709749 r3727697  
    44 * Plugin URI:        https://wptranslate.es
    55 * Description:       Visual translation for your site: front-end editor, batch translation with a free keyless engine or your own Gemini, DeepL or Google key, per-language URL and hreflang, and Elementor and WooCommerce support.
    6  * Version:           2.10.4
     6 * Version:           2.10.5
    77 * Requires at least: 6.1
    88 * Requires PHP:      8.0
    … …  
    1717if ( ! defined( 'ABSPATH' ) ) exit;
    1818
    19 define( 'WPTM_VERSION',     '2.10.4' );
     19define( 'WPTM_VERSION',     '2.10.5' );
    2020define( 'WPTM_PLUGIN_DIR',  plugin_dir_path( __FILE__ ) );
    2121define( 'WPTM_PLUGIN_URL',  plugin_dir_url( __FILE__ ) );
  • incode-translate-master/trunk/readme.txt

    r3723287 r3727697  
    55Tested up to: 7.1
    66Requires PHP: 8.0
    7 Stable tag: 2.10.4
     7Stable tag: 2.10.5
    88License: GPLv2 or later
    99License URI: https://www.gnu.org/licenses/gpl-2.0.html
    … …  
    120120== Changelog ==
    121121
     122= 2.10.5 =
     123* Fixed: adding the classic "Language Switcher — Incode Translate Master" widget -- under Appearance > Widgets, in the Customizer or in Elementor -- stopped the page with a critical error. A widget that had not been saved with a display style yet looked up the default style through a method the widget does not have. Widgets already saved with a style kept working. The error came in with 2.10.1.
     124* Fixed: an address with two language prefixes in a row, such as /de/en/blog/post/, was served as an ordinary page with a 200 status and a canonical pointing at itself, so search engines indexed it as one more page. Its hreflang links then announced further addresses of the same kind (/en/en/…, /fr/en/…), so every one of them led to more. These addresses now redirect permanently (301) to the same page with a single prefix -- the first one, which is the language the page was being served in -- keeping the query string. Form submissions and WooCommerce AJAX calls are never redirected.
     125
    122126= 2.10.4 =
    123127* Housekeeping: nothing changes in the free plugin. This release only keeps the version in step with the paid edition, which got a follow-up to the 2.10.3 caching fix covering automatic browser language detection -- a feature the free plugin does not include. If you are already on 2.10.3 there is nothing you need to do.
    … …  
    211215== Upgrade Notice ==
    212216
     217= 2.10.5 =
     218Recommended. Fixes a critical error when adding the Language Switcher widget, and redirects addresses with two language prefixes (/de/en/…) with a 301 so they stop being indexed as separate pages.
     219
    213220= 2.10.4 =
    214221Optional. Nothing changes in the free plugin; this release only keeps the version in step with the paid edition.
Note: See TracChangeset for help on using the changeset viewer.