Skip to content

Commit

Permalink
Get tests is ready
Browse files Browse the repository at this point in the history
  • Loading branch information
andrey-helldar committed Jun 19, 2024
1 parent ff33e87 commit 5465f4e
Show file tree
Hide file tree
Showing 11 changed files with 255 additions and 184 deletions.
22 changes: 0 additions & 22 deletions src/Casts/ColumnCast.php

This file was deleted.

2 changes: 1 addition & 1 deletion src/Exceptions/UnavailableLocaleException.php
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,6 @@ public function __construct(Locale|string|null $locale)

protected function available(): string
{
return Locales::installed()->pluck('locale.code')->filter()->implode(', ');
return Locales::installed()->pluck('code')->filter()->implode(', ');
}
}
255 changes: 145 additions & 110 deletions src/HasTranslations.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,84 +4,72 @@

namespace LaravelLang\Models;

use Illuminate\Database\Eloquent\Relations\HasOne;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\HasMany;
use Illuminate\Support\Arr;
use LaravelLang\Config\Facades\Config;
use LaravelLang\LocaleList\Locale;
use LaravelLang\Locales\Facades\Locales;
use LaravelLang\Models\Eloquent\Translation;
use LaravelLang\Models\Events\TranslationHasBeenSetEvent;
use LaravelLang\Models\Exceptions\AttributeIsNotTranslatableException;
use LaravelLang\Models\Exceptions\UnavailableLocaleException;
use LaravelLang\Models\Services\Registry;
use LaravelLang\Models\Services\Relation;

/**
* @mixin \Illuminate\Database\Eloquent\Concerns\HasAttributes
* @mixin \Illuminate\Database\Eloquent\Model
*/
trait HasTranslations
{
//public static function bootHasTranslations(): void
//{
// static::saved(function (Model $model) {
// // @var \LaravelLang\Models\HasTranslations $model
// $model->translation?->setAttribute('model_id', $model->getKey());
// $model->translation?->save();
//
// if (! $model->translation) {
// $model->setRelation('translation', $model->translation()->make());
// }
// });
//
// static::deleting(function (Model $model) {
// // @var \LaravelLang\Models\HasTranslations $model
// return $model->translation?->delete() ?? $model->translation()->delete();
// });
//
// if (method_exists(static::class, 'forceDeleted')) {
// static::forceDeleted(function (Model $model) {
// // @var \LaravelLang\Models\HasTranslations $model
// return $model->translation?->forceDelete() ?? $model->translation()->forceDelete();
// });
// }
//
// if (method_exists(static::class, 'restored')) {
// static::restored(function (Model $model) {
// // @var \LaravelLang\Models\HasTranslations $model
// $model->translation()->onlyTrashed()?->restore();
// });
// }
//}
//
public function translation(): HasOne
public static function bootHasTranslations(): void
{
$suffix = Config::shared()->models->suffix;
static::retrieved(function (Model $model) {
Relation::initializeModel($model);
});

return $this->hasOne(static::class . $suffix, 'item_id');
static::saved(function (Model $model) {
/** @var \LaravelLang\Models\HasTranslations $model */
$model->translations?->each?->save();
});
//
// static::deleting(function (Model $model) {
// // @var \LaravelLang\Models\HasTranslations $model
// return $model->translation?->delete() ?? $model->translation()->delete();
// });
//
// if (method_exists(static::class, 'forceDeleted')) {
// static::forceDeleted(function (Model $model) {
// // @var \LaravelLang\Models\HasTranslations $model
// return $model->translation?->forceDelete() ?? $model->translation()->forceDelete();
// });
// }
//
// if (method_exists(static::class, 'restored')) {
// static::restored(function (Model $model) {
// // @var \LaravelLang\Models\HasTranslations $model
// $model->translation()->onlyTrashed()?->restore();
// });
// }
}

protected static function translationModelName(): string
{
return static::class . Config::shared()->models->suffix;
}

//
//public function setTranslation(
// string $column,
// array|ContentData|float|int|string|null $value,
// Locale|string|null $locale = null
//): static {
// $this->validateTranslationColumn($column, $locale, true);
//
// if (is_null($this->translation)) {
// $this->setRelation('translation', $this->translation()->make());
// }
//
// TranslationHasBeenSetEvent::dispatch(
// $this,
// $column,
// $locale?->value ?? $locale,
// $this->getTranslation($column, $locale),
// $value
// );
//
// $this->translation->content->set($column, $value, $locale);
//
// return $this;
//}
//
//public function getTranslation(string $column, Locale|string|null $locale = null): float|int|string|null
//{
// $this->validateTranslationColumn($column, $locale);
//
// return $this->translation?->content?->get($column, $locale);
//}

public function initializeHasTranslations(): void
{
$this->with = array_unique($this->with + ['translations']);
}

public function translations(): HasMany
{
return $this->hasMany(static::translationModelName(), 'item_id');
}
//
//public function hasTranslated(string $column, Locale|string|null $locale = null): bool
//{
Expand All @@ -90,10 +78,48 @@ public function translation(): HasOne
// return $this->translation->content?->has($column, $locale) ?? false;
//}
//
//public function isTranslatable(string $column): bool
//{
// return in_array($column, $this->translatable(), true);
//}
//
public function setTranslation(
string $column,
array|float|int|string|null $value,
Locale|string|null $locale = null
): static {
$this->validateTranslationColumn($column, $locale);

Relation::initializeModel($this);

TranslationHasBeenSetEvent::dispatch(
$this,
$column,
$locale?->value ?? $locale,
$this->getTranslation($column, $locale),
$value
);

$this->translation($locale)->setAttribute($column, $value);

return $this;
}

public function getTranslation(string $column, Locale|string|null $locale = null): float|int|string|null
{
$this->validateTranslationColumn($column, $locale);

if (! $locale) {
$current = Locales::getCurrent()->code;
$fallback = Locales::getFallback()->code;

return $this->translation($current)?->getAttribute($column)
?? $this->translation($fallback)?->getAttribute($column);
}

return $this->translation($locale)?->getAttribute($column);
}

public function isTranslatable(string $column): bool
{
return in_array($column, $this->translatable(), true);
}
//
//public function forgetTranslation(string $column, Locale|string|null $locale = null): void
//{
Expand All @@ -111,45 +137,54 @@ public function translation(): HasOne
// AllTranslationsHasBeenForgetEvent::dispatch($this);
//}
//
//public function translatable(): array
//{
// return [];
//}
//
//public function getAttribute($key): mixed
//{
// if ($this->isTranslatable($key)) {
// return $this->getTranslation($key);
// }
//
// return parent::getAttribute($key);
//}
//
//public function newInstance($attributes = [], $exists = false): static
//{
// $basic = Arr::except($attributes, $this->translatable());
// $translatable = Arr::only($attributes, $this->translatable());
//
// $model = parent::newInstance($basic, $exists);
//
// foreach ($translatable as $key => $value) {
// $model->setTranslation($key, $value);
// }
//
// return $model;
//}
//
//protected function validateTranslationColumn(
// string $column,
// Locale|string|null $locale,
// bool $withInstalled = false
//): void {
// if (! $this->isTranslatable($column)) {
// throw new AttributeIsNotTranslatableException($column, $this);
// }

public function getAttribute($key): mixed
{
if ($this->isTranslatable($key)) {
return $this->getTranslation($key);
}

return parent::getAttribute($key);
}

//
// if ($locale && ! $withInstalled && ! Locales::isInstalled($locale)) {
// throw new UnavailableLocaleException($locale);
// }
//}

public function newInstance($attributes = [], $exists = false): static
{
$basic = Arr::except($attributes, $this->translatable());
$translatable = Arr::only($attributes, $this->translatable());

$model = parent::newInstance($basic, $exists);

foreach ($translatable as $key => $value) {
$model->setTranslation($key, $value);
}

return $model;
}

public function translatable(): array
{
return Registry::get(__METHOD__, function () {
return (new (static::translationModelName())())->translatable();
});
}

protected function translation(Locale|string|null $locale = null): ?Translation
{
return $this->translations->get(
Locales::get($locale)->code
);
}

protected function validateTranslationColumn(string $column, Locale|string|null $locale): void
{
if (! $this->isTranslatable($column)) {
throw new AttributeIsNotTranslatableException($column, $this);
}

if ($locale && ! Locales::isInstalled($locale)) {
throw new UnavailableLocaleException($locale);
}
}
}
17 changes: 17 additions & 0 deletions src/Services/Registry.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace LaravelLang\Models\Services;

use Closure;

class Registry
{
public static array $values = [];

public static function get(string $key, Closure $callback): mixed
{
return static::$values[$key] ?? $callback();
}
}
46 changes: 46 additions & 0 deletions src/Services/Relation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace LaravelLang\Models\Services;

use Illuminate\Database\Eloquent\Collection as DBCollection;
use Illuminate\Database\Eloquent\Model;
use Illuminate\Support\Collection;
use LaravelLang\Config\Facades\Config;
use LaravelLang\Locales\Data\LocaleData;
use LaravelLang\Locales\Facades\Locales;
use LaravelLang\Models\Eloquent\Translation;

class Relation
{
public static function initializeModel(Model $model): void
{
if (blank($model->translations) && blank($model->load('translations')->translations)) {
$model->setRelation('translations', new DBCollection());
}

static::locales()->each(function (LocaleData $locale) use ($model) {
if (! $model->translations?->has($locale->code)) {
$model->translations->put($locale->code, static::initializeLocale($model, $locale->code));
}
});
}

public static function initializeLocale(Model $model, string $locale): Translation
{
return (new (static::modelName($model))())
->setAttribute('item_id', $model->getKey())
->setAttribute('locale', $locale);
}

protected static function modelName(Model $model): string
{
return get_class($model) . Config::shared()->models->suffix;
}

protected static function locales(): Collection
{
return Locales::installed();
}
}
3 changes: 2 additions & 1 deletion stubs/helper.stub
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,12 @@
namespace {{namespace}} {

use {{translationNamespace}};
use Illuminate\Database\Eloquent\Collection;
use Illuminate\Database\Eloquent\Model;

/**
{{properties}}
* @property-read {{translationModel}} $translation
* @property-read Collection<{{translationModel}}> $translations
*/
class {{model}} extends Model {}
}
Loading

0 comments on commit 5465f4e

Please sign in to comment.