Skip to content

Commit

Permalink
First try
Browse files Browse the repository at this point in the history
  • Loading branch information
andrey-helldar committed Jun 10, 2024
1 parent ec1c539 commit 837cbdf
Show file tree
Hide file tree
Showing 10 changed files with 269 additions and 1 deletion.
7 changes: 7 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,13 @@
[![Github Workflow Status][badge_build]][link_build]
[![License][badge_license]](https://laravel-lang.com/license.html)

## ToDo

У астрономик взять принцип хранения данных, а у Спати - способ их использования.

- https://github.com/Astrotomic/laravel-translatable
- https://github.com/spatie/laravel-translatable

## Documentation

See the [documentation](https://laravel-lang.com/packages-models.html) for detailed installation.
Expand Down
4 changes: 3 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -29,8 +29,10 @@
},
"require": {
"php": "^8.1",
"illuminate/database": "^10.0 || ^11.0",
"illuminate/support": "^10.0 || ^11.0",
"laravel-lang/config": "^1.1"
"laravel-lang/config": "^1.1",
"laravel-lang/locales": "^2.8"
},
"require-dev": {
"orchestra/testbench": "^8.23 || ^9.1",
Expand Down
19 changes: 19 additions & 0 deletions config/localization.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?php

declare(strict_types=1);

return [
'models' => [
'connection' => null,

'table' => 'translations',

'json_flags' => JSON_UNESCAPED_UNICODE ^ JSON_UNESCAPED_SLASHES,
],

'translators' => [
'GoogleTranslate',
'YandexTranslate',
'DeeplTranslate',
],
];
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
<?php

declare(strict_types=1);

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
use LaravelLang\Config\Facades\Config;

return new class extends Migration {
public function up(): void
{
$config = $this->config();

Schema::connection($config->connection)
->create($config->table, function (Blueprint $table) use ($config) {
$table->id();

$table->string('model_type', 255);
$table->string('model_id', 255);

$table->jsonb('content');

$table->timestamps();
$table->softDeletes();

// TODO: Заменить на условный индекс
$table->unique(['model_type', 'model_id']);
});
}

public function down(): void
{
$config = $this->config();

Schema::connection($config->connection)->dropIfExists($config->table);
}

protected function config(): ModelsData
{
return Config::shared()->models;
}
};
Empty file removed src/.gitkeep
Empty file.
41 changes: 41 additions & 0 deletions src/Casts/TranslationCast.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
<?php

declare(strict_types=1);

namespace LaravelLang\Models\Casts;

use Illuminate\Contracts\Database\Eloquent\CastsAttributes;
use Illuminate\Database\Eloquent\Model;
use LaravelLang\Config\Facades\Config;
use LaravelLang\Models\Data\ContentData;

class TranslationCast implements CastsAttributes
{
public function get(Model $model, string $key, mixed $value, array $attributes): ?ContentData
{
if ($value) {
return new ContentData(
json_decode($value, true)
);
}

return null;
}

/**
* @param \Illuminate\Database\Eloquent\Model $model
* @param string $key
* @param ContentData $value
* @param array $attributes
*
* @return string
*/
public function set(Model $model, string $key, mixed $value, array $attributes): ?string
{
if ($value) {
return $value->toJson(Config::shared()->models->jsonFlags);
}

return null;
}
}
21 changes: 21 additions & 0 deletions src/Concerns/Initialize.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
<?php

declare(strict_types=1);

namespace LaravelLang\Models\Concerns;

use LaravelLang\Config\Facades\Config;

trait Initialize
{
protected function bootInitialize(): void
{
$config = Config::shared()->models;

$this->connection = $config->connection;
$this->table = $config->table;

$this->incrementing = $config->incrementing;
$this->timestamps = $config->timestamps;
}
}
46 changes: 46 additions & 0 deletions src/Data/ContentData.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
<?php

declare(strict_types=1);

namespace LaravelLang\Models\Data;

use Illuminate\Contracts\Support\Jsonable;
use LaravelLang\LocaleList\Locale;
use LaravelLang\Locales\Facades\Locales;

class ContentData implements Jsonable
{
public function __construct(
protected array $locales
) {}

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

if (is_null($value) || $value === '') {
unset($this->locales[$column][$locale]);

return;
}

$this->locales[$column][$locale] = $value;
}

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

return $this->locales[$column][$locale] ?? null;
}

public function toJson($options = 0): string
{
return json_encode($this->locales, $options);
}

protected function locale(Locale|string|null $locale): string
{
return Locales::get($locale)->code ?? Locales::getDefault()->code;
}
}
52 changes: 52 additions & 0 deletions src/HasTranslations.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
<?php

declare(strict_types=1);

namespace LaravelLang\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphOne;
use LaravelLang\LocaleList\Locale;
use LaravelLang\Models\Models\Translation;

/** @mixin \Illuminate\Database\Eloquent\Model */
trait HasTranslations
{
/*
* Translatable columns
*/
protected array $translatable = [];

public static function bootHasTranslations(): void
{
static::saved(function (Model $model) {
/** @var \LaravelLang\Models\HasTranslations $model */
return $model->translation?->save() ?? $model;
});

static::deleting(function (Model $model) {
/** @var \LaravelLang\Models\HasTranslations $model */
return $model->translation()->delete();
});
}

public function translation(): MorphOne
{
return $this->morphOne(Translation::class, 'model');
}

public function setTranslation(
string $column,
int|float|string|null $value,
Locale|string|null $locale = null
): static {
$this->translation->content->set($column, $value, $locale);

return $this;
}

public function getTranslation(string $column, Locale|string|null $locale = null): int|float|string|null
{
return $this->translation->content->get($column, $locale);
}
}
37 changes: 37 additions & 0 deletions src/Models/Translation.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
<?php

declare(strict_types=1);

namespace LaravelLang\Models\Models;

use Illuminate\Database\Eloquent\Model;
use Illuminate\Database\Eloquent\Relations\MorphTo;
use Illuminate\Database\Eloquent\SoftDeletes;
use LaravelLang\Models\Casts\TranslationCast;
use LaravelLang\Models\Concerns\Initialize;

class Translation extends Model
{
use Initialize;
use SoftDeletes;

/*
* Backward compatibility for Laravel 10
*/
protected $casts = [
'model_type' => 'string',
'model_id' => 'string',

'content' => TranslationCast::class,
];

public function parent(): MorphTo
{
return $this->morphTo();
}

protected function casts(): array
{
return $this->casts;
}
}

0 comments on commit 837cbdf

Please sign in to comment.