Skip to content

Commit

Permalink
handle plugin objects within i18n fallback value (#398)
Browse files Browse the repository at this point in the history
* handle plugin objects within i18n fallback value

* add since, update changelog

* newline...

* run in seperate process

* fix test
  • Loading branch information
nadar committed Dec 19, 2019
1 parent b982b26 commit fe787c6
Show file tree
Hide file tree
Showing 4 changed files with 125 additions and 2 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ In order to read more about upgrading and BC breaks have a look at the [UPGRADE

## 2.3.0

+ [#397](https://github.com/luyadev/luya-module-admin/issues/397) i18nAttributeFallbackValue() require to run the onFind() context of the given attribute plugin in order to ensure plugin specific options like `markdown`.
+ [#389](https://github.com/luyadev/luya-module-admin/issues/389) Do not throw an exception by default when pool identifier does not exists in the list of pools.

## 2.2.2 (23. October 2019)
Expand Down
21 changes: 21 additions & 0 deletions src/ngrest/base/NgRestEventBehavior.php
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,9 @@ class NgRestEventBehavior extends Behavior
{
public $plugins = [];

/**
* @var \luya\admin\ngrest\base\Plugin[] An array which holds all the plugin objects which are loaded after the active record has been initiliazed.
*/
private static $_pluginInstances = [];

/**
Expand All @@ -45,6 +48,24 @@ public function bindPluginEvents(Event $event)
}
}
}

/**
* Get the Plugin object based on the Attribute Name.
*
* As Behaviors works like trait its possible to access the Plugin object from Model scope:
*
* ```php
* $plugin = $this->getPluginObject('attributeName');
* ```
*
* @param string $attribute
* @return \luya\admin\ngrest\base\Plugin
* @since 2.3.0
*/
public function getPluginObject($attribute)
{
return self::$_pluginInstances[$this->owner->tableName()][$attribute];
}

/**
* Singleton Container for Plugin Objects.
Expand Down
36 changes: 34 additions & 2 deletions src/ngrest/base/NgRestModel.php
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
use luya\admin\ngrest\Config;
use luya\admin\ngrest\ConfigBuilder;
use luya\admin\base\RestActiveController;
use yii\base\Event;

/**
* NgRest Model.
Expand Down Expand Up @@ -170,19 +171,50 @@ public function i18nAttributeFallbackValue($attributeName, $preferredLanguage =
$array = I18n::decode($this->getOldAttribute($attributeName));

if ($preferredLanguage && isset($array[$preferredLanguage]) && !empty($array[$preferredLanguage])) {
return $array[$preferredLanguage];
return $this->runI18nContextOnFindPlugin($attributeName, $array[$preferredLanguage]);
}

foreach ($array as $value) {
if (!empty($value)) {
return $value;
return $this->runI18nContextOnFindPlugin($attributeName, $value);
}
}
}

return $value;
}

/**
* Run an attribute plugin in i18n context in order to ensure plugin functions.
*
* This method will return the plugin of the given attribute with the context of the
* new value. This allows you to re-run plugin options like `markdown` on a given attribute.
*
* This is mainly used when the {{i18nAttributeFallbackValue()}} method finds an i18n value
* and needs to re-run the configured plugin options like nl2br, markdown, conver to link object.
*
* @param string $attributeName
* @param mixed $value
* @return mixed
* @since 2.3.0
*/
protected function runI18nContextOnFindPlugin($attributeName, $value)
{
// create the plugin without i18n context as the plugin can handle whether its i18n or not
$plugin = clone $this->getPluginObject($attributeName);
$plugin->i18n = false;
// prepare the context for the event with the current model.
$senderContext = clone $this;
$senderContext->{$attributeName} = $value;
$plugin->onFind(new Event(['sender' => $senderContext]));
// as the plugin as run the onFind event the sender context will have the new value
$convertedValue = $senderContext->{$attributeName};
// clear variables to help with memory issues
unset($plugin, $senderContext);

return $convertedValue;
}

/**
* Checks whether given attribute is in the list of i18n fields, if so
* the field value will be decoded and the value for the current active
Expand Down
69 changes: 69 additions & 0 deletions tests/admin/ngrest/base/NgRestModelAdminModelTestCaseTest.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
use luya\admin\models\Tag;
use luya\testsuite\fixtures\NgRestModelFixture;
use luya\admin\models\Lang;
use luya\admin\models\User;
use luya\web\Composition;

class NgRestModelAdminModelTestCaseTest extends AdminModelTestCase
Expand Down Expand Up @@ -84,5 +85,73 @@ public function testI18nAttributeFallbackValue()
$this->assertEmpty($model->translation);
$this->assertSame('Deutsch', $model->i18nAttributeFallbackValue('translation'));
$this->assertSame('Francais', $model->i18nAttributeFallbackValue('translation', 'fr'));

$lang->cleanup();
$fixture->cleanup();
}

public function testI18nAttributeFallbackValueWithMarkdownTextConverter()
{

$lang = new NgRestModelFixture([
'modelClass' => Lang::class,
'fixtureData' => [
'id1' => [
'id' => 1,
'name' => 'English',
'short_code' => 'en',
'is_default' => 0,
'is_deleted' => 0,
],
'id2' => [
'id' => 2,
'name' => 'French',
'short_code' => 'fr',
'is_default' => 1,
'is_deleted' => 0,
]
]
]);

$fixture = new NgRestModelFixture([
'modelClass' => I18nMarkdownTagTest::class,
'fixtureData' => [
'id1' => [
'id' => 1,
'email' => 'foobar@test.com',
'firstname' => 'name',
'lastname' => '{"de":"Deutsch *foo*", "en": "", "fr": "Francais *foo*"}',
'is_deleted' => 0,
]
]
]);

$this->assertSameTrimmed('', $fixture->getModel('id1')->lastname); // <p>Francais <em>foo</em></p>
$this->assertSameTrimmed('<p>Francais <em>foo</em></p>', $fixture->getModel('id1')->i18nAttributeFallbackValue('lastname', 'fr')); // <p>Francais <em>foo</em></p>
$this->assertSameTrimmed('', $fixture->getModel('id1')->lastname); // <p>Francais <em>foo</em></p>

$fixture->cleanup();
$lang->cleanup();

}
}

class I18nMarkdownTagTest extends User
{
public $i18n = ['lastname', 'firstname'];

public static function tableName()
{
return 'user_copy';
}

public function ngRestAttributeTypes()
{

$at = parent::ngRestAttributeTypes();
$at['firstname'] = ['textarea', 'markdown' => true];
$at['lastname'] = ['textarea', 'markdown' => true];

return $at;
}
}

0 comments on commit fe787c6

Please sign in to comment.