Skip to content

Commit

Permalink
feat: list strings merged default and custom (#51)
Browse files Browse the repository at this point in the history
* feat: list strings merged default and custom

* fix: refs not translated correctly, improve performance
  • Loading branch information
imorland authored Jan 15, 2025
1 parent 81d9055 commit fb5356b
Show file tree
Hide file tree
Showing 5 changed files with 129 additions and 20 deletions.
1 change: 1 addition & 0 deletions extend.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
->get('/fof/linguist/string-keys/{key}', 'fof.linguist.api.string-keys.show', Controllers\ShowStringKeyController::class)
->get('/fof/linguist/strings', 'fof.linguist.api.strings.index', Controllers\StringIndexController::class)
->get('/fof/linguist/strings/{key}', 'fof.linguist.api.strings.show', Controllers\ShowStringController::class)
->get('/fof/linguist/merged', 'fof/linguist.api.merged.index', Controllers\MergedIndexController::class)
->post('/fof/linguist/strings', 'fof.linguist.api.strings.store', Controllers\StringStoreController::class)
->patch('/fof/linguist/strings/{id:[0-9]+}', 'fof.linguist.api.strings.update', Controllers\StringUpdateController::class)
->delete('/fof/linguist/strings/{id:[0-9]+}', 'fof.linguist.api.strings.delete', Controllers\StringDeleteController::class)
Expand Down
93 changes: 93 additions & 0 deletions src/Api/Controllers/MergedIndexController.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,93 @@
<?php

namespace FoF\Linguist\Api\Controllers;

use Flarum\Api\Controller\AbstractListController;
use Flarum\Http\RequestUtil;
use FoF\Linguist\Api\Serializers\StringKeySerializer;
use FoF\Linguist\Repositories\DefaultStringsRepository;
use FoF\Linguist\Repositories\StringRepository;
use FoF\Linguist\TextString;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;
use Psr\Http\Message\ServerRequestInterface;
use Symfony\Contracts\Translation\TranslatorInterface;
use Tobscure\JsonApi\Document;

class MergedIndexController extends AbstractListController
{
public $serializer = StringKeySerializer::class;

/**
* @var DefaultStringsRepository
*/
protected $defaultStrings;

/**
* @var StringRepository
*/
protected $strings;

/**
* @var TranslatorInterface
*/
protected $translator;

public function __construct(
DefaultStringsRepository $defaultStrings,
StringRepository $strings,
TranslatorInterface $translator
) {
$this->defaultStrings = $defaultStrings;
$this->strings = $strings;
$this->translator = $translator;
}

protected function data(ServerRequestInterface $request, Document $document)
{
RequestUtil::getActor($request)->assertCan('viewStringKeys');

// Extract filters from the request.
$filters = $this->extractFilter($request);
$filter = $this->defaultStrings->getPrefix($filters);

// Retrieve all translations from the default repository and returns a Collection.
// @example
// array:2 [▼
// "key" => "acme-foobar.forum.example_string"
// "locales" => array:4 [▼
// "en" => "${count} more ${ count === 1 ? `question` : `questions` }"
// "de" => "${count} weitere ${ count === 1 ? `Frage` : `Fragen` }"
// "it" => "${count} altre ${ count === 1 ? `domanda` : `domande` }"
// "fr" => "${count} autres ${ count === 1 ? `question` : `questions` }"
// ]
// ]
$all = $this->defaultStrings->allTranslations($filter);
$allKeys = $all->pluck('key');

$modified = $this->strings->getByKeys($allKeys->toArray());

foreach ($modified as $textString) {
$updates = [];
$locale = $textString->locale;
$translation = $textString->value;

if (Str::startsWith($translation, '=>')) {
$key = trim(Str::after($translation, '=>'));

if (empty($key)) {
continue;
}
$translation = $this->translator->trans($key, [], null, $locale);
}

$updates[$locale] = $translation;

$locales = array_merge($all[$textString->key]['locales'], $updates);

$all->put($textString->key, ['key' => $textString->key, 'locales' => $locales]);
}

return $all;
}
}
20 changes: 2 additions & 18 deletions src/Api/Controllers/StringKeyIndexController.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,7 @@
use FoF\Linguist\Repositories\DefaultStringsRepository;
use Flarum\Api\Controller\AbstractListController;
use Flarum\Http\RequestUtil;
use Illuminate\Support\Arr;
use Illuminate\Support\Collection;
use Illuminate\Support\Str;
use Psr\Http\Message\ServerRequestInterface;
use Tobscure\JsonApi\Document;

Expand Down Expand Up @@ -37,21 +35,7 @@ protected function data(ServerRequestInterface $request, Document $document)
// Extract filters from the request.
$filters = $this->extractFilter($request);

// Look for the 'prefix' key in the filters.
$prefix = Arr::get($filters, 'prefix', null);

// Retrieve all translations from the repository.
$all = $this->repository->allTranslations();

// If a prefix is provided, filter the translations by that prefix.
if ($prefix) {
return $all->filter(function ($item) use ($prefix) {
// Return true if the item's key starts with the provided prefix.
return Str::startsWith($item['key'], $prefix);
});
} else {
// If no prefix is provided, return all translations.
return $all;
}
// Retrieve all translations from the default repository.
return $this->repository->allTranslations($this->repository->getPrefix($filters));
}
}
25 changes: 23 additions & 2 deletions src/Repositories/DefaultStringsRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
use FoF\Linguist\Translator\NoOpConfigCacheFactory;
use Illuminate\Contracts\Events\Dispatcher;
use Illuminate\Support\Arr;
use Illuminate\Support\Str;

class DefaultStringsRepository
{
Expand All @@ -22,7 +23,7 @@ public function __construct(SettingsRepositoryInterface $settings, Dispatcher $e
$this->manager = $manager;
}

public function allTranslations()
public function allTranslations(?string $filter = null)
{
$translator = $this->manager->getTranslator();

Expand Down Expand Up @@ -59,9 +60,18 @@ public function allTranslations()
// so no need to make Flarum use the cached version again to finish answering this request.
// We would only miss Linguist-defined strings inside the eventual errors happening later in this very request.

return collect($translations)->sortBy(function ($value, $key) {
$all = collect($translations)->sortBy(function ($value, $key) {
return $key;
});

if (!empty($filter)) {
return $all->filter(function ($item) use ($filter) {
// Return true if the item's key starts with the provided prefix.
return Str::startsWith($item['key'], $filter);
});
}

return $all;
}

public function getTranslation($key)
Expand Down Expand Up @@ -107,4 +117,15 @@ protected function localeKeys(): array
// This is nessesary to show "ref" strings correctly when en is not the default language
return array_merge(['en'], array_diff($locales, ['en']));
}

/**
* Look for the 'prefix' key in the filters.
*
* @param array $filters
* @return string|null
*/
public function getPrefix(array $filters): ?string
{
return Arr::get($filters, 'prefix', null);
}
}
10 changes: 10 additions & 0 deletions src/Repositories/StringRepository.php
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@

namespace FoF\Linguist\Repositories;

use Flarum\Database\Eloquent\Collection;
use FoF\Linguist\TextString;
use FoF\Linguist\Validators\StringValidator;
use Illuminate\Database\Eloquent\Model;
Expand Down Expand Up @@ -51,6 +52,15 @@ public function getByKey($key)
return $this->query()->where('key', $key)->get();
}

/**
* @param array $keys
* @return Collection<TextString>
*/
public function getByKeys(array $keys): Collection
{
return $this->query()->whereIn('key', $keys)->get();
}

/**
* @param array $attributes
* @return TextString
Expand Down

0 comments on commit fb5356b

Please sign in to comment.