Skip to content

Commit

Permalink
Merge pull request #140 from ARCANEDEV/update-2
Browse files Browse the repository at this point in the history
Updating the package
  • Loading branch information
arcanedev-maroc authored Feb 5, 2019
2 parents 174dcee + d6c094c commit de77949
Show file tree
Hide file tree
Showing 8 changed files with 228 additions and 60 deletions.
2 changes: 1 addition & 1 deletion .scrutinizer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ checks:
tools:
external_code_coverage:
timeout: 1200
runs: 3
runs: 4
php_code_sniffer:
enabled: true
config:
Expand Down
1 change: 1 addition & 0 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ php:
- 7.1.3
- 7.1
- 7.2
- 7.3
- nightly

matrix:
Expand Down
2 changes: 1 addition & 1 deletion LICENSE.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
The MIT License (MIT)

Copyright (c) 2015-2017 | ARCANEDEV <[email protected]> - Localization
Copyright (c) 2015-2019 | ARCANEDEV <[email protected]> - Localization

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
Expand Down
1 change: 1 addition & 0 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
"license": "MIT",
"require": {
"php": ">=7.1.3",
"ext-json": "*",
"arcanedev/support": "~4.4.0"
},
"require-dev": {
Expand Down
12 changes: 11 additions & 1 deletion src/Exceptions/UntranslatableAttributeException.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,4 +6,14 @@
* @package Arcanedev\Localization\Exceptions
* @author ARCANEDEV <[email protected]>
*/
class UntranslatableAttributeException extends LocalizationException {}
class UntranslatableAttributeException extends LocalizationException
{
public static function make(string $key, array $translatableAttributes)
{
$translatableAttributes = implode(', ', $translatableAttributes);

return new static(
"The attribute `{$key}` is untranslatable because it's not available in the translatable array: `$translatableAttributes`"
);
}
}
148 changes: 95 additions & 53 deletions src/Traits/HasTranslations.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,31 @@
*
* @package Arcanedev\Localization\Traits
* @author ARCANEDEV <[email protected]>
*
* @property array attributes
* @property-read array translations
*/
trait HasTranslations
{
/* -----------------------------------------------------------------
| Getters
| -----------------------------------------------------------------
*/

/**
* Get the translations.
*
* @return array
*/
public function getTranslationsAttribute(): array
{
return collect($this->getTranslatableAttributes())
->mapWithKeys(function (string $key) {
return [$key => $this->getTranslations($key)];
})
->toArray();
}

/* -----------------------------------------------------------------
| Main Methods
| -----------------------------------------------------------------
Expand All @@ -34,10 +56,25 @@ abstract public function getTranslatableAttributes();
public function getAttributeValue($key)
{
return $this->isTranslatableAttribute($key)
? $this->getTranslation($key, config('app.locale'))
? $this->getTranslation($key, $this->getLocale())
: parent::getAttributeValue($key);
}

/**
* Set a given attribute on the model.
*
* @param string $key
* @param mixed $value
*
* @return self
*/
public function setAttribute($key, $value)
{
return ( ! $this->isTranslatableAttribute($key) || is_array($value))
? parent::setAttribute($key, $value)
: $this->setTranslation($key, $this->getLocale(), $value);
}

/**
* Get the translated attribute (alias).
*
Expand All @@ -56,13 +93,13 @@ public function trans($key, $locale = '')
*
* @param string $key
* @param string $locale
* @param bool $useFallback
* @param bool $useFallbackLocale
*
* @return mixed
*/
public function getTranslation($key, $locale, $useFallback = true)
public function getTranslation($key, $locale, $useFallbackLocale = true)
{
$locale = $this->normalizeLocale($key, $locale, $useFallback);
$locale = $this->normalizeLocale($key, $locale, $useFallbackLocale);
$translations = $this->getTranslations($key);
$translation = $translations[$locale] ?? '';

Expand All @@ -74,15 +111,25 @@ public function getTranslation($key, $locale, $useFallback = true)
/**
* Get the translations for the given key.
*
* @param string $key
* @param string|null $key
*
* @return array
*/
public function getTranslations($key)
public function getTranslations($key = null)
{
$this->guardAgainstUntranslatableAttribute($key);
if ($key !== null) {
$this->guardAgainstNonTranslatableAttribute($key);

return array_filter(json_decode($this->getAttributeFromArray($key) ?? '' ?: '{}', true) ?: [], function ($value) {
return $value !== null && $value !== false && $value !== '';
});
}

return json_decode($this->getAttributeFromArray($key) ?: '{}', true);
return array_reduce($this->getTranslatableAttributes(), function ($result, $item) {
$result[$item] = $this->getTranslations($item);

return $result;
});
}

/**
Expand All @@ -96,16 +143,18 @@ public function getTranslations($key)
*/
public function setTranslation($key, $locale, $value)
{
$this->guardAgainstUntranslatableAttribute($key);
$this->guardAgainstNonTranslatableAttribute($key);

$translations = $this->getTranslations($key);
$oldValue = $translations[$locale] ?? '';

if ($this->hasSetMutator($key))
$value = $this->{'set'.Str::studly($key).'Attribute'}($value);
if ($this->hasSetMutator($key)) {
$this->{'set'.Str::studly($key).'Attribute'}($value);
$value = $this->attributes[$key];
}

$translations[$locale] = $value;
$this->attributes[$key] = json_encode($translations);
$this->attributes[$key] = $this->asJson($translations);

event(new TranslationHasBeenSet($this, $key, $locale, $oldValue, $value));

Expand All @@ -122,7 +171,7 @@ public function setTranslation($key, $locale, $value)
*/
public function setTranslations($key, array $translations)
{
$this->guardAgainstUntranslatableAttribute($key);
$this->guardAgainstNonTranslatableAttribute($key);

foreach ($translations as $locale => $translation) {
$this->setTranslation($key, $locale, $translation);
Expand All @@ -145,7 +194,7 @@ public function forgetTranslation($key, $locale)
unset($translations[$locale]);

if ($this->hasSetMutator($key))
$this->attributes[$key] = json_encode($this->mutateTranslations($key, $translations));
$this->attributes[$key] = $this->asJson($translations);
else
$this->setAttribute($key, $translations);

Expand All @@ -161,7 +210,7 @@ public function forgetTranslation($key, $locale)
*/
public function flushTranslations($locale)
{
collect($this->getTranslatableAttributes())->each(function ($attribute) use ($locale) {
collect($this->getTranslatableAttributes())->each(function (string $attribute) use ($locale) {
$this->forgetTranslation($attribute, $locale);
});

Expand All @@ -175,11 +224,26 @@ public function flushTranslations($locale)
*
* @return array
*/
public function getTranslatedLocales($key)
public function getTranslatedLocales($key): array
{
return array_keys($this->getTranslations($key));
}

/**
* Check if has a translation.
*
* @param string $key
* @param string|null $locale
*
* @return bool
*/
public function hasTranslation(string $key, string $locale = null): bool
{
$locale = $locale ?: $this->getLocale();

return isset($this->getTranslations($key)[$locale]);
}

/**
* Check if the attribute is translatable.
*
Expand All @@ -197,21 +261,25 @@ public function isTranslatableAttribute($key)
| -----------------------------------------------------------------
*/

/**
* Get the locale.
*
* @return string
*/
protected function getLocale(): string
{
return config('app.locale');
}

/**
* Guard against untranslatable attribute.
*
* @param string $key
*
* @throws \Arcanedev\Localization\Exceptions\UntranslatableAttributeException
*/
protected function guardAgainstUntranslatableAttribute($key)
protected function guardAgainstNonTranslatableAttribute($key)
{
if ( ! $this->isTranslatableAttribute($key)) {
$translatable = implode(', ', $this->getTranslatableAttributes());

throw new UntranslatableAttributeException(
"The attribute `{$key}` is untranslatable because it's not available in the translatable array: `$translatable`"
);
throw UntranslatableAttributeException::make($key, $this->getTranslatableAttributes());
}
}

Expand All @@ -229,24 +297,7 @@ protected function normalizeLocale($key, $locale, $useFallback)
if (in_array($locale, $this->getTranslatedLocales($key)) || ! $useFallback)
return $locale;

return is_null($fallbackLocale = config('app.fallback_locale')) ? $locale : $fallbackLocale;
}

/**
* Mutate many translations.
*
* @param string $key
* @param array $translations
*
* @return string
*/
protected function mutateTranslations($key, array $translations)
{
$method = 'set'.Str::studly($key).'Attribute';

return array_map(function ($value) use ($method) {
return $this->{$method}($value);
}, $translations);
return config('app.fallback_locale') ?: $locale;
}

/* -----------------------------------------------------------------
Expand All @@ -262,7 +313,8 @@ protected function mutateTranslations($key, array $translations)
public function getCasts()
{
return array_merge(
parent::getCasts(), array_fill_keys($this->getTranslatableAttributes(), 'array')
parent::getCasts(),
array_fill_keys($this->getTranslatableAttributes(), 'array')
);
}

Expand Down Expand Up @@ -294,16 +346,6 @@ abstract protected function mutateAttribute($key, $value);
*/
abstract protected function getAttributeFromArray($key);

/**
* Set a given attribute on the model.
*
* @param string $key
* @param mixed $value
*
* @return self
*/
abstract public function setAttribute($key, $value);

/**
* Determine if a set mutator exists for an attribute.
*
Expand Down
4 changes: 1 addition & 3 deletions tests/Stubs/Models/TranslatableModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,9 @@ public function getNameAttribute($name)
* Set the slug attribute (mutator).
*
* @param string $slug
*
* @return string
*/
public function setSlugAttribute($slug)
{
return Str::slug($slug);
$this->attributes['slug'] = Str::slug($slug);
}
}
Loading

0 comments on commit de77949

Please sign in to comment.