2023-03-02 21:11:54 -05:00
|
|
|
<?php
|
|
|
|
|
|
|
|
namespace App\Data;
|
|
|
|
|
|
|
|
use App\Exceptions\ItemNotFoundException;
|
|
|
|
use Illuminate\Support\Collection;
|
2023-03-02 21:13:20 -05:00
|
|
|
use Illuminate\Support\Facades\Cache;
|
2023-03-02 21:11:54 -05:00
|
|
|
use Illuminate\Support\Facades\Http;
|
|
|
|
use Illuminate\Support\Str;
|
|
|
|
use App\Config\GiteaConfig;
|
2023-03-02 21:13:20 -05:00
|
|
|
use Illuminate\Support\Facades\Log;
|
2023-03-02 21:11:54 -05:00
|
|
|
|
|
|
|
class ItemsCollection
|
|
|
|
{
|
2023-03-02 21:13:20 -05:00
|
|
|
protected Collection $items;
|
|
|
|
protected Collection $locales;
|
2023-03-02 21:11:54 -05:00
|
|
|
|
2023-03-02 21:13:20 -05:00
|
|
|
private string $items_cache_key = 'items';
|
|
|
|
private string $locales_cache_key = 'locales';
|
2023-03-02 21:11:54 -05:00
|
|
|
|
|
|
|
public function __construct()
|
|
|
|
{
|
2023-03-02 21:13:20 -05:00
|
|
|
if (!Cache::has($this->items_cache_key)) {
|
2023-03-02 21:11:54 -05:00
|
|
|
$this->refreshItemsCache();
|
|
|
|
} else {
|
2023-03-02 21:13:20 -05:00
|
|
|
$this->items = Cache::get($this->items_cache_key);
|
2023-03-02 21:11:54 -05:00
|
|
|
}
|
|
|
|
|
2023-03-02 21:13:20 -05:00
|
|
|
if (!Cache::has($this->locales_cache_key)) {
|
2023-03-02 21:11:54 -05:00
|
|
|
$this->refreshLocalesCache();
|
|
|
|
} else {
|
2023-03-02 21:13:20 -05:00
|
|
|
$this->locales = Cache::get($this->locales_cache_key);
|
2023-03-02 21:11:54 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
public function refreshLocalesCache(): void
|
|
|
|
{
|
2023-03-02 21:13:20 -05:00
|
|
|
$this->locales = collect();
|
2023-03-02 21:11:54 -05:00
|
|
|
$rawLocalesGlobalBaseUrl = GiteaConfig::RAW_LOCALES_GLOBAL_BASE_URL;
|
|
|
|
|
|
|
|
// Getting all locales in project/assets/database/locales/global from the Server development branch repository
|
2023-03-02 21:13:20 -05:00
|
|
|
|
|
|
|
$localesList = collect(Http::withOptions(['verify' => false])->get(GiteaConfig::LOCALES_GLOBAL_URL)->json());
|
2023-03-02 21:11:54 -05:00
|
|
|
foreach ($localesList as $item) {
|
|
|
|
// Extract the json name for the locale
|
|
|
|
preg_match('/([a-z]{2}(-[a-z]{2})?).json/', $item['name'], $currentLocaleName, PREG_OFFSET_CAPTURE);
|
|
|
|
|
|
|
|
// If the name is not supported for any reason, dont add it to the locales
|
|
|
|
if (empty($currentLocaleName) || !$currentLocaleName[1][0]) continue;
|
|
|
|
|
|
|
|
$trimmedCurrentLocaleName = trim($currentLocaleName[1][0]);
|
|
|
|
$currentLocaleJson = Http::withOptions(['verify' => false])
|
2023-03-02 21:13:20 -05:00
|
|
|
->get("${rawLocalesGlobalBaseUrl}/${trimmedCurrentLocaleName}.json")->json();
|
|
|
|
$templateLocale = collect($currentLocaleJson['templates']);
|
|
|
|
$customizationLocale = collect($currentLocaleJson['customization']);
|
|
|
|
$this->locales = $this->locales->merge([$trimmedCurrentLocaleName => $templateLocale->concat($customizationLocale)]);
|
2023-03-02 21:13:18 -05:00
|
|
|
}
|
2023-03-02 21:13:20 -05:00
|
|
|
Cache::put($this->locales_cache_key, $this->locales);
|
2023-03-02 21:11:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function refreshItemsCache(): void
|
|
|
|
{
|
2023-03-02 21:13:20 -05:00
|
|
|
$this->items = collect(Http::withOptions(['verify' => false])->get(GiteaConfig::RAW_ITEMS_URL)->json());
|
|
|
|
$this->items = $this->items->merge(collect(Http::withOptions(['verify' => false])
|
|
|
|
->get(GiteaConfig::RAW_CUSTOMIZATION_URL)->json()));
|
|
|
|
Cache::put($this->items_cache_key, $this->items);
|
2023-03-02 21:11:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
2023-03-02 21:13:20 -05:00
|
|
|
* @return Collection
|
2023-03-02 21:11:54 -05:00
|
|
|
*/
|
2023-03-02 21:13:20 -05:00
|
|
|
public function getLocales(): Collection
|
2023-03-02 21:11:54 -05:00
|
|
|
{
|
2023-03-02 21:13:20 -05:00
|
|
|
return $this->locales->keys();
|
2023-03-02 21:11:54 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @return void
|
|
|
|
*/
|
|
|
|
public function refreshAllCache(): void
|
|
|
|
{
|
|
|
|
$this->refreshItemsCache();
|
|
|
|
$this->refreshLocalesCache();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks if the query is in the key
|
|
|
|
* @param string $key
|
|
|
|
* @param string $query
|
|
|
|
* @return bool
|
|
|
|
*/
|
|
|
|
private function contains(string $key, string $query): bool
|
|
|
|
{
|
|
|
|
$key = Str::lower(trim($key));
|
|
|
|
$query = Str::lower(trim($query));
|
|
|
|
|
|
|
|
return Str::contains($key, $query);
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $query the content of the query eg. 'AK'
|
|
|
|
* @param string $locale the chosen local. Default to 'en'
|
|
|
|
* @return Collection
|
|
|
|
*/
|
|
|
|
public function findItem(string $query, string $locale): Collection
|
|
|
|
{
|
2023-03-02 21:13:20 -05:00
|
|
|
return $this->items->filter(function ($val, $key) use ($query, $locale) {
|
2023-03-02 21:11:54 -05:00
|
|
|
return $this->contains($val['_id'], $query)
|
|
|
|
|| $this->contains($val['_name'], $query)
|
|
|
|
|| $this->contains($val['_parent'], $query)
|
|
|
|
|| (($this->locales[$locale][$key] ?? false)
|
|
|
|
&& ($this->contains($this->locales[$locale][$key]['Name'], $query) || $this->contains($this->locales[$locale][$key]['ShortName'], $query))
|
|
|
|
);
|
|
|
|
})->map(function ($item) use ($locale) {
|
|
|
|
return [
|
|
|
|
'item' => [
|
|
|
|
'_id' => $item['_id'],
|
|
|
|
'_name' => $item['_name'],
|
2023-03-02 21:13:20 -05:00
|
|
|
],
|
2023-03-02 21:11:54 -05:00
|
|
|
'locale' => $this->locales[$locale][$item['_id']] ?? ''
|
|
|
|
];
|
|
|
|
})->values();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $id the item ID to look for
|
|
|
|
* @param string $locale the chosen local. Default to 'en'
|
|
|
|
* @return array
|
|
|
|
* @throws ItemNotFoundException
|
|
|
|
*/
|
|
|
|
public function getItemById(string $id, string $locale): array
|
|
|
|
{
|
2023-03-02 21:13:20 -05:00
|
|
|
$item = $this->items[$id] ?? throw new ItemNotFoundException('Item not found');
|
2023-03-02 21:11:54 -05:00
|
|
|
return [
|
|
|
|
'item' => $item,
|
|
|
|
'locale' => $this->locales[$locale][$id] ?? ''
|
|
|
|
];
|
|
|
|
}
|
|
|
|
|
2023-03-02 21:13:20 -05:00
|
|
|
public function getHierarchy(string $id, string $locale = 'en'): Collection {
|
2023-03-02 21:11:54 -05:00
|
|
|
// Return 404 if the item does not exist
|
2023-03-02 21:13:20 -05:00
|
|
|
$itemData = $this->items[$id] ?? throw new ItemNotFoundException('Item not found');
|
2023-03-02 21:11:54 -05:00
|
|
|
|
|
|
|
// Initialize the hierarchy with the current item
|
|
|
|
$item = [
|
2023-03-02 21:13:20 -05:00
|
|
|
'item'=> [
|
2023-03-02 21:11:54 -05:00
|
|
|
'_id' => $itemData['_id'],
|
|
|
|
'_name' => $itemData['_name'],
|
|
|
|
'_parent' => $itemData['_parent']
|
|
|
|
],
|
|
|
|
'locale' => $this->locales[$locale][$id] ?? ''
|
|
|
|
];
|
|
|
|
$hierarchy = collect([$id => $item]);
|
|
|
|
|
|
|
|
// Check the whole hierarchy and merge into the return variable
|
|
|
|
while (!empty($item['item']['_parent'] ?? '')) {
|
|
|
|
$itemtId = $item['item']['_parent'];
|
2023-03-02 21:13:20 -05:00
|
|
|
$itemData = $this->items[$itemtId] ?? null;
|
2023-03-02 21:11:54 -05:00
|
|
|
$item = [
|
2023-03-02 21:13:20 -05:00
|
|
|
'item'=> [
|
2023-03-02 21:11:54 -05:00
|
|
|
'_id' => $itemData['_id'],
|
|
|
|
'_name' => $itemData['_name'],
|
|
|
|
'_parent' => $itemData['_parent']
|
|
|
|
],
|
|
|
|
'locale' => $this->locales[$locale][$itemtId] ?? ''
|
|
|
|
];
|
|
|
|
$hierarchy = $hierarchy->merge([$itemtId => $item]);
|
|
|
|
}
|
|
|
|
|
|
|
|
return $hierarchy;
|
|
|
|
}
|
2023-03-02 21:13:20 -05:00
|
|
|
|
|
|
|
public function getItemLocale(string $locale, string $itemID): array {
|
|
|
|
return $this->locales[$locale][$itemID] ?? [];
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $locale the chosen local. Default to 'en'
|
|
|
|
* @return array
|
|
|
|
* @throws ItemNotFoundException
|
|
|
|
*/
|
|
|
|
public function getAllItemsName(string $locale): Collection
|
|
|
|
{
|
|
|
|
return $this->items->map(function ($item) use ($locale) {
|
|
|
|
return [
|
|
|
|
'item' => [
|
|
|
|
'_id' => $item['_id'],
|
|
|
|
],
|
|
|
|
'locale' => collect($this->getItemLocale($locale, $item['_id']))->only(['Name', 'ShortName'])
|
|
|
|
];
|
|
|
|
})->filter(function ($item) {
|
|
|
|
return json_encode($item['locale']) != '[]';
|
|
|
|
})->values();
|
|
|
|
}
|
|
|
|
|
|
|
|
/**
|
|
|
|
* @param string $id the item ID to look for
|
|
|
|
* @param string $locale the chosen local. Default to 'en'
|
|
|
|
* @return array
|
|
|
|
* @throws ItemNotFoundException
|
|
|
|
*/
|
|
|
|
public function getItemNameById(string $id, string $locale): array
|
|
|
|
{
|
|
|
|
$itemLocale = $this->locales[$locale][$id] ?? '';
|
|
|
|
|
|
|
|
if ($itemLocale == '') {
|
|
|
|
return $itemLocale;
|
|
|
|
}
|
|
|
|
|
|
|
|
return [
|
|
|
|
'locale' => collect($itemLocale)->only(['Name', 'ShortName'])
|
|
|
|
];
|
|
|
|
}
|
|
|
|
}
|