Skip to content
Merged
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 .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ assets/js/msls-widget-block/
assets/js/msls.js
build/translations.json
composer.phar
docs/specs/
multisite-language-switcher.zip
multisite-language-switcher/
node_modules/
Expand Down
6 changes: 5 additions & 1 deletion CLAUDE.md
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ npm run build-msls-block # Build only the Gutenberg block

### E2E Tests
```bash
npx playwright install chromium # Once per machine: every project launches Chromium
npx wp-env start # Required first: the local suite runs against wp-env
npm run playwright:local # Admin + frontend specs (skips visual)
npm run playwright:visual # Visual specs inside the Playwright Linux image
Expand All @@ -40,6 +41,9 @@ npm run playwright:update-snapshots # Regenerate visual baselines
npm run playwright:live # Only specs/live, against msls.co (no wp-env needed)
npx playwright test --ui # Run with UI
```
Without the browser every spec fails with `browserType.launch: Executable doesn't exist`.
The three container scripts are exempt: the Playwright Linux image ships its own browsers.

Visual baselines are committed and only pixel-stable when generated inside the container —
always use the `:visual` / `:update-snapshots` scripts, never a bare `npx playwright test`
for them.
Expand Down Expand Up @@ -80,7 +84,7 @@ it, so activate it once per fresh **development** environment with the command a
- PSR-4 (dev): `lloc\MslsTests\` maps to `tests/phpunit/`
- Plugin bootstrap: `MultisiteLanguageSwitcher.php` — defines constants, requires `vendor/autoload.php` plus `includes/aliases.php`, `includes/deprecated.php` and `includes/api.php` **at file-load time**, then calls `lloc\Msls\Plugin::init()` and `lloc\Msls\Cli\Cli::init()` on `plugins_loaded`. Do not move those requires into the hook: add-ons may load before us, and they need the aliases and the `msls_*()` functions to exist the moment the plugin file is included
- **Backwards-compatibility aliases**: `lloc\Msls\Compat\Aliases::MAP` (`includes/Compat/Aliases.php`) maps the ~60 pre-3.0 flat class names (`MslsOptions`, `MslsLink`, `MslsPlugin`, …) to their namespaced replacements. `::register()` — invoked from the thin `includes/aliases.php` — creates them with `class_alias()` **eagerly**, plus an autoloader for the handful in `::LAZY_ONLY`. Do not make them lazy across the board: PHP resolves the class named in a parameter/return/property type with `ZEND_FETCH_CLASS_NO_AUTOLOAD`, so an alias created on demand never gets its chance and the call fatals with a `TypeError` (MslsMenu declares `get_msls_output(): lloc\Msls\MslsOutput`). `LAZY_ONLY` is limited to names that never shipped before 3.0, so nothing can be holding them. Write new code against the namespaced names; the aliases exist only for third-party consumers
- **PHP-DI**: `lloc\Msls\Container::get()` builds the container from `config.php` on first use and caches it. `config.php` is still empty — nothing is injected through it yet
- **Service container**: `lloc\Msls\Container::get()` builds a `lloc\Msls\ServiceContainer` from `config.php` on first use and caches it for the request. Definitions are closures (called with the container), plain values, or nothing at all, in which case an existing class name is instantiated. `config.php` is still empty, nothing is injected through it yet. This replaced PHP-DI in 3.1.0: the 6.4 series is unmaintained and emits PHP 8.4 deprecations from its autoloaded `functions.php`, while PHP-DI 7 requires PHP 8.0 and the plugin declares PHP 7.4. Do not reintroduce a DI library while that floor stands

### Key Patterns
- **Registry/Singleton**: `Registry\Instance` is the base class providing the `::instance()` static accessor (backed by `Registry\Registry`); `Registry\GetSet` extends it to add overloaded property access
Expand Down
9 changes: 9 additions & 0 deletions Changelog.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,12 @@
## 3.1.0
* Add pagination to the links of the switcher: a visitor on page 3 of an archive is sent to page 3 of the translated archive instead of the first page. That applies to the pages of an archive as well as to the pages of a post which is split by `<!--nextpage-->`.
* Add `Options::get_max_pages()` to the whole options hierarchy, together with the `Options::PAGINATION_ARCHIVE` and `Options::PAGINATION_SINGLE` constants. A page is only added when the other blog has it, so a link which would be out of range still points to the first page.
* Add `msls_preserve_pagination` to switch the feature off, `msls_pagination_max_pages` to correct the number of pages MSLS calculates, and `msls_pagination_get` to adjust the finished link. All three are documented in `docs/hooks.md`.
* Fix: PHP 8.4 raised deprecation notices on every request. They came from the bundled PHP-DI 6.4, which declares its helper functions with implicitly nullable parameters and loads them through the autoloader on every page load. The 6.4 series is unmaintained and PHP-DI 7 requires PHP 8.0, so the library has been replaced by a small container of the plugin's own.
* Fix: three parameters of the content import were declared as implicitly nullable, which PHP 8.4 deprecates as well.
* Internal: `Container::get()` returns a `lloc\Msls\ServiceContainer` instead of a `DI\Container`. It reads the same `config.php` and resolves closures, plain values, and class names.
* Internal: `OptionsInterface` is unchanged, so a custom implementation keeps working and simply gets no page appended.

## 3.0.3
* Fix: the plugin required PHP-DI 7, which needs PHP 8.0, while MSLS itself declares PHP 7.4 as its minimum. PHP-DI is back on the 6.4 series, so an installation on PHP 7.4 can resolve the dependencies again.
* Internal: declare `Requires PHP: 7.4` in the plugin header so WordPress blocks activation on older PHP versions, and check the production dependencies against PHP 7.4 in CI.
Expand Down
4 changes: 2 additions & 2 deletions MultisiteLanguageSwitcher.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* Multisite Language Switcher Plugin
*
* Plugin Name: Multisite Language Switcher
* Version: 3.0.3
* Version: 3.1.0
* Plugin URI: http://msls.co/
* Description: A simple but powerful plugin that will help you to manage the relations of your contents in a multilingual multisite-installation.
* Requires PHP: 7.4
Expand Down Expand Up @@ -43,7 +43,7 @@
* @author Dennis Ploetner <re@lloc.de>
*/
if ( ! defined( 'MSLS_PLUGIN_VERSION' ) ) {
define( 'MSLS_PLUGIN_VERSION', '3.0.3' );
define( 'MSLS_PLUGIN_VERSION', '3.1.0' );
define( 'MSLS_PLUGIN_PATH', plugin_basename( __FILE__ ) );
define( 'MSLS_PLUGIN__FILE__', __FILE__ );

Expand Down
25 changes: 13 additions & 12 deletions assets/css-flags/flags.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/**
* File is auto-generated
*
* 132 translations-teams for WordPress found
* 133 translations-teams for WordPress found
*/
// Unhandled language: am (Amharic)
// Unhandled language: arg (Aragonese)
Expand All @@ -13,6 +13,7 @@
// Unhandled language: hsb (Upper Sorbian)
// Unhandled language: kn (Kannada)
// Unhandled language: kir (Kyrgyz)
// Unhandled language: pcm (Nigerian Pidgin)
// Unhandled language: snd (Sindhi)
// Unhandled language: sw (Swahili)
// Unhandled language: yor (Yoruba)
Expand All @@ -33,39 +34,39 @@
'cy' => 'flag-icon-gb-wls',
'da_DK' => 'flag-icon-dk',
'de_AT' => 'flag-icon-at',
'de_CH_informal' => 'flag-icon-ch',
'de_DE' => 'flag-icon-de',
'de_DE_formal' => 'flag-icon-de',
'de_CH' => 'flag-icon-ch',
'de_CH_informal' => 'flag-icon-ch',
'dzo' => 'flag-icon-bt',
'el' => 'flag-icon-gr',
'en_AU' => 'flag-icon-au',
'en_CA' => 'flag-icon-ca',
'en_NZ' => 'flag-icon-nz',
'en_GB' => 'flag-icon-gb',
'en_ZA' => 'flag-icon-za',
'en_NZ' => 'flag-icon-nz',
'en_CA' => 'flag-icon-ca',
'en_AU' => 'flag-icon-au',
'eo' => 'flag-icon-eu',
'es_AR' => 'flag-icon-ar',
'es_CR' => 'flag-icon-cr',
'es_CL' => 'flag-icon-cl',
'es_ES' => 'flag-icon-es',
'es_MX' => 'flag-icon-mx',
'es_CO' => 'flag-icon-co',
'es_PE' => 'flag-icon-pe',
'es_VE' => 'flag-icon-ve',
'es_EC' => 'flag-icon-ec',
'es_DO' => 'flag-icon-do',
'es_UY' => 'flag-icon-uy',
'es_PR' => 'flag-icon-pr',
'es_CL' => 'flag-icon-cl',
'es_GT' => 'flag-icon-gt',
'es_ES' => 'flag-icon-es',
'es_CR' => 'flag-icon-cr',
'es_CO' => 'flag-icon-co',
'et' => 'flag-icon-ee',
'eu' => 'flag-icon-es',
'fa_IR' => 'flag-icon-ir',
'fa_AF' => 'flag-icon-af',
'fi' => 'flag-icon-fi',
'fr_CA' => 'flag-icon-ca',
'fr_FR' => 'flag-icon-fr',
'fr_BE' => 'flag-icon-be',
'fr_FR' => 'flag-icon-fr',
'fur' => 'flag-icon-it',
'gd' => 'flag-icon-gb-sct',
'gl_ES' => 'flag-icon-es',
Expand Down Expand Up @@ -98,18 +99,18 @@
'my_MM' => 'flag-icon-mm',
'nb_NO' => 'flag-icon-no',
'ne_NP' => 'flag-icon-np',
'nl_BE' => 'flag-icon-be',
'nl_NL' => 'flag-icon-nl',
'nl_NL_formal' => 'flag-icon-nl',
'nl_BE' => 'flag-icon-be',
'nn_NO' => 'flag-icon-no',
'oci' => 'flag-icon-es-ca',
'pa_IN' => 'flag-icon-in',
'pl_PL' => 'flag-icon-pl',
'ps' => 'flag-icon-af',
'pt_BR' => 'flag-icon-br',
'pt_AO' => 'flag-icon-ao',
'pt_PT' => 'flag-icon-pt',
'pt_PT_ao90' => 'flag-icon-90',
'pt_AO' => 'flag-icon-ao',
'ro_RO' => 'flag-icon-ro',
'ru_RU' => 'flag-icon-ru',
'sah' => 'flag-icon-ru',
Expand Down
25 changes: 13 additions & 12 deletions assets/flags/flags.php
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
/**
* File is auto-generated
*
* 132 translations-teams for WordPress found
* 133 translations-teams for WordPress found
*/
// Unhandled language: am (Amharic)
// Unhandled language: arg (Aragonese)
Expand All @@ -12,6 +12,7 @@
// Unhandled language: hsb (Upper Sorbian)
// Unhandled language: kn (Kannada)
// Unhandled language: kir (Kyrgyz)
// Unhandled language: pcm (Nigerian Pidgin)
// Unhandled language: snd (Sindhi)
// Unhandled language: sw (Swahili)
// Unhandled language: yor (Yoruba)
Expand All @@ -33,39 +34,39 @@
'cy' => 'wales.png',
'da_DK' => 'dk.png',
'de_AT' => 'at.png',
'de_CH_informal' => 'ch.png',
'de_DE' => 'de.png',
'de_DE_formal' => 'de.png',
'de_CH' => 'ch.png',
'de_CH_informal' => 'ch.png',
'dzo' => 'bt.png',
'el' => 'gr.png',
'en_AU' => 'au.png',
'en_CA' => 'ca.png',
'en_NZ' => 'nz.png',
'en_GB' => 'gb.png',
'en_ZA' => 'za.png',
'en_NZ' => 'nz.png',
'en_CA' => 'ca.png',
'en_AU' => 'au.png',
'eo' => 'europeanunion.png',
'es_AR' => 'ar.png',
'es_CR' => 'cr.png',
'es_CL' => 'cl.png',
'es_ES' => 'es.png',
'es_MX' => 'mx.png',
'es_CO' => 'co.png',
'es_PE' => 'pe.png',
'es_VE' => 've.png',
'es_EC' => 'ec.png',
'es_DO' => 'do.png',
'es_UY' => 'uy.png',
'es_PR' => 'pr.png',
'es_CL' => 'cl.png',
'es_GT' => 'gt.png',
'es_ES' => 'es.png',
'es_CR' => 'cr.png',
'es_CO' => 'co.png',
'et' => 'ee.png',
'eu' => 'es.png',
'fa_IR' => 'ir.png',
'fa_AF' => 'af.png',
'fi' => 'fi.png',
'fr_CA' => 'ca.png',
'fr_FR' => 'fr.png',
'fr_BE' => 'be.png',
'fr_FR' => 'fr.png',
'fur' => 'it.png',
'gd' => 'scotland.png',
'gl_ES' => 'es.png',
Expand Down Expand Up @@ -98,18 +99,18 @@
'my_MM' => 'mm.png',
'nb_NO' => 'no.png',
'ne_NP' => 'np.png',
'nl_BE' => 'be.png',
'nl_NL' => 'nl.png',
'nl_NL_formal' => 'nl.png',
'nl_BE' => 'be.png',
'nn_NO' => 'no.png',
'oci' => 'catalonia.png',
'pa_IN' => 'in.png',
'pl_PL' => 'pl.png',
'ps' => 'af.png',
'pt_BR' => 'br.png',
'pt_AO' => 'ao.png',
'pt_PT' => 'pt.png',
'pt_PT_ao90' => '90.png',
'pt_AO' => 'ao.png',
'ro_RO' => 'ro.png',
'ru_RU' => 'ru.png',
'sah' => 'ru.png',
Expand Down
1 change: 0 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
"require": {
"php": ">=7.4",
"composer/installers": "~2.3.0",
"php-di/php-di": "^6.4",
"ext-json": "*"
},
"require-dev": {
Expand Down
Loading
Loading