decor-6-site/kirby/src/Panel/Ui/Buttons/LanguagesDropdown.php

121 lines
2.7 KiB
PHP
Raw Normal View History

2026-01-05 19:33:15 +01:00
<?php
namespace Kirby\Panel\Ui\Buttons;
use Kirby\Cms\App;
use Kirby\Cms\Language;
use Kirby\Cms\Languages;
use Kirby\Cms\ModelWithContent;
use Kirby\Toolkit\Str;
/**
* View button to switch content translation languages
*
* @package Kirby Panel
* @author Nico Hoffmann <nico@getkirby.com>
* @link https://getkirby.com
* @copyright Bastian Allgeier
* @license https://getkirby.com/license
* @since 5.0.0
* @unstable
*/
class LanguagesDropdown extends ViewButton
{
protected App $kirby;
public function __construct(
ModelWithContent $model
) {
$this->kirby = $model->kirby();
parent::__construct(
component: 'k-languages-dropdown',
model: $model,
class: 'k-languages-dropdown',
icon: 'translate',
// Fiber dropdown endpoint to load options
// only when dropdown is opened
options: $model->panel()->url(true) . '/languages',
responsive: 'text',
text: Str::upper($this->kirby->language()?->code())
);
}
/**
* Returns if any translation other than the current one has unsaved changes
* (the current language has to be handled in `k-languages-dropdown` as its
* state can change dynamically without another backend request)
*/
public function hasDiff(): bool
{
foreach (Languages::ensure() as $language) {
if ($this->kirby->language()?->code() !== $language->code()) {
if ($this->model->version('changes')->exists($language) === true) {
return true;
}
}
}
return false;
}
public function option(Language $language): array
{
$changes = $this->model->version('changes');
return [
'text' => $language->name(),
'code' => $language->code(),
'current' => $language->code() === $this->kirby->language()?->code(),
'default' => $language->isDefault(),
'changes' => $changes->exists($language),
'lock' => $changes->isLocked('*')
];
}
/**
* Options are used in the Fiber dropdown routes
*/
public function options(): array
{
$languages = $this->kirby->languages();
$options = [];
if ($this->kirby->multilang() === false) {
return $options;
}
// add the primary/default language first
if ($default = $languages->default()) {
$options[] = $this->option($default);
$options[] = '-';
$languages = $languages->not($default);
}
// add all secondary languages after the separator
foreach ($languages as $language) {
$options[] = $this->option($language);
}
return $options;
}
public function props(): array
{
return [
...parent::props(),
'hasDiff' => $this->hasDiff()
];
}
public function render(): array|null
{
// hides the language selector when there are less than 2 languages
if ($this->kirby->languages()->count() < 2) {
return null;
}
return parent::render();
}
}