- 상태
- 해결됨
- 유형
- 수정 안 함
- 보고된 제품
- WPML Multilingual CMS 5.0
- 주제 태그
- Compatibility
문제 개요
WPML 5.0부터 언어 전환이 중첩됩니다. 모든 언어 코드는 새로운 범위를 열며, null만 범위를 닫습니다.
WPML 4.x용으로 작성된 플러그인은 주로 저장했던 언어를 지정하는 방식으로 다시 전환합니다.
$current = apply_filters( 'wpml_current_language', null ); do_action( 'wpml_switch_language', 'de' ); // ... do_action( 'wpml_switch_language', $current ); // Meant as "and back".
WPML 4.x는 이를 허용했습니다. 단일 언어 슬롯을 유지했기 때문에 현재 언어가 올바르게 지정되었고, 불균형한 전환은 드러나지 않았습니다. 이는 전환을 닫는 올바른 방법이 결코 아니었습니다. WPML 5.0은 더 이상 이를 수용하지 않습니다. 마지막 호출은 첫 번째 범위를 닫는 대신 두 번째 범위를 열며, WPML은 언어가 전환되었다고 계속 보고합니다.
동일한 호출이 주변 코드의 원래 언어로의 유효한 전환이기도 하므로 WPML은 이를 감지할 수 없습니다.
증상은 나중에 나타납니다. 전환 쌍 직후에는 현재 언어가 올바르므로, 해당 부분만 확인하는 테스트는 통과합니다. 그런 다음 주변의 다음 올바른 복원 작업이 자체 범위 대신 열려 있는 범위를 닫게 되며, 해당 코드는 잘못된 언어로 실행됩니다. 이메일, REST 응답 및 관리 화면에서 이 문제가 나타납니다.
복원이 없거나 비어 있는 언어 코드를 사용한 전환도 동일한 방식으로 범위를 열어 둡니다.
임시 해결 방법
finally 블록에서 null을 사용하여 모든 범위를 닫으세요:
do_action( 'wpml_switch_language', 'de' );
try {
// ...your work in German...
} finally {
do_action( 'wpml_switch_language', null ); // Closes the scope above.
}
단일 릴리스에서 WPML 4.x 및 5.0 지원
다음 헬퍼를 복사하여 접두사를 변경하세요:
// Opens a scope. Returns the value for the close helper, or false if none opened.
function myplugin_wpml_open_language_switch( $language_code ) {
// '', false and 0 open a scope without changing the language. Only null closes one.
if ( ! $language_code ) {
return false;
}
$previous = apply_filters( 'wpml_current_language', '' );
do_action( 'wpml_switch_language', $language_code );
return $previous;
}
// Closes the scope the open helper opened. WPML 4.x has no stack: there null
// means "the language before the FIRST switch", so restore by name.
function myplugin_wpml_close_language_switch( $previous ) {
if ( ! $previous ) {
return;
}
$has_stack = defined( 'ICL_SITEPRESS_VERSION' )
&& version_compare( ICL_SITEPRESS_VERSION, '5.0', '>=' );
do_action( 'wpml_switch_language', $has_stack ? null : $previous );
}
그러면 각 호출 위치는 다음과 같이 변경됩니다:
$previous = myplugin_wpml_open_language_switch( 'de' );
try {
// ... work ...
} finally {
myplugin_wpml_close_language_switch( $previous );
}
grep -rn "wpml_switch_language" .을 실행하여 모든 호출 위치를 찾으세요. 각각 일치하는 닫기 코드가 필요합니다. 언어 이름을 지정하여 복원하지 말고, 비어 있을 수 있는 코드로 전환하지 마세요.
이메일 훅도 중첩됩니다. 각 wpml_switch_language_for_email에 대해 wpml_restore_language_from_email을 한 번씩 호출하세요.