Support from Acquia helps fund testing for Drupal Acquia logo

Comments

EclipseGc’s picture

Title: Create a Language check condition plugin » Create a Language check Condition
larowlan’s picture

Assigned: EclipseGc » larowlan

Snagging this after clearing with EclipseGc on irc

larowlan’s picture

Status: Active » Needs review
FileSize
7.83 KB

First cut, needs more tests - will tackle those tomorrow.

larowlan’s picture

So this adds more unit tests and is ready for a serious look

podarok’s picture

+++ b/core/modules/language/lib/Drupal/language/Plugin/Core/Condition/Language.phpundefined
@@ -0,0 +1,140 @@
+        '#default_value' => !empty($this->configuration['langcodes']) ? $this->configuration['langcodes'] : array(),
+        '#options' => $langcodes_options,
...

$langcodes_options looks like not previously defined
possibly we should...

/**
 * description...
 */
private $langcodes_options;

all other looks good for me
+1RTBC

podarok’s picture

Status: Needs review » Needs work

looking at the test

+++ b/core/modules/language/lib/Drupal/language/Tests/Condition/LanguageConditionTest.phpundefined
@@ -0,0 +1,131 @@
+    // Setup English.
+    $default_language = language_save(language_default());

$default_language never used here
Looks like it should be removed or used in tests )

larowlan’s picture

langcode_options is defined here

+++ b/core/modules/language/lib/Drupal/language/Plugin/Core/Condition/Language.phpundefined
@@ -0,0 +1,140 @@
+      foreach ($languages as $language) {
+        // @todo $language->name is not wrapped with t(), it should be replaced
+        //   by CMI translation implementation.
+        $langcodes_options[$language->langcode] = $language->name;
larowlan’s picture

Status: Needs work » Needs review
larowlan’s picture

bump

EclipseGc’s picture

#7: condition-language-1921550.7.patch queued for re-testing.

Status: Needs review » Needs work

The last submitted patch, condition-language-1921550.7.patch, failed testing.

EclipseGc’s picture

Status: Needs work » Needs review
FileSize
8.79 KB

ok, I didn't provide an interdiff on this just because of my workflow and I didn't think I'd need one. if that makes reviewing it easier, then I can do that, but I removed the language type stuff from the plugin because the plugin doesn't dictate what type of language it is, it just validates whether the language passed to it matches the configuration. So now there's a language context, and the implementation will have to inject the language that's relevant to the use case.

Eclipse

twistor’s picture

+++ b/core/modules/language/lib/Drupal/language/Plugin/Core/Condition/Language.phpundefined
@@ -0,0 +1,125 @@
+    if (language_multilingual()) {
...
+    else {
+      $form['language']['langcodes'] = array(
+        '#type' => 'value',
+        '#value' => !empty($this->configuration['langcodes']) ? $this->configuration['langcodes'] : array()
+      );

Could this be handled cleaner with '#access' => language_multilingual()?

+++ b/core/modules/language/lib/Drupal/language/Plugin/Core/Condition/Language.phpundefined
@@ -0,0 +1,125 @@
+    $language_list = language_list(LANGUAGE_ALL);
+    $selected = $this->configuration['langcodes'];
+    // Reduce the language list to an array of language names.
+    $language_names = array_reduce($language_list, function(&$result, $item) use ($selected) {
+      if (!empty($selected[$item->langcode])) {
+        $result[$item->langcode] = $item->name;
+      }
+      return $result;
+    }, array());
+
+    // Collate language type names.
+    $language_types = language_types_info();
+    $language_type_options = array();
+    foreach ($language_types as $type_key => $info) {
+      if (!empty($info['name'])) {
+        $language_type_options[$type_key] = $info['name'];
+      }

Why is building an options list done 2 different ways here? I love me some closures, but a foreach would be simpler.

+++ b/core/modules/language/lib/Drupal/language/Plugin/Core/Condition/Language.phpundefined
@@ -0,0 +1,125 @@
+    $language = $this->getContextValue('language');
+    // Language visibility settings.
+    if (!empty($this->configuration['langcodes'])) {
+      if (empty($this->configuration['langcodes'][$language->langcode])) {
+        return FALSE;
+      }

I have to look at the condition implementation, but this seems to suggest that this plugin will always evaluate, even if it was never configured. Is that correct?

+++ b/core/modules/language/lib/Drupal/language/Tests/Condition/LanguageConditionTest.phpundefined
@@ -0,0 +1,131 @@
+    $this->assertTRUE($condition->execute(), 'Language condition passes as expected.');

This should have been the name :)

EclipseGc’s picture

FileSize
5.66 KB
8.26 KB

Could this be handled cleaner with '#access' => language_multilingual()?

There's enough stuff happening in the if statement that tests that that I'd prefer to not mess with that stuff outside the if in favor of an #access property. I typically prefer the #access property as well since we'd actually have the form elements there. Still you wouldn't want these form elements if you didn't have a multi-lingual site, so this is one of the few edge cases where I don't mind an if statement around my form elements.

Why is building an options list done 2 different ways here? I love me some closures, but a foreach would be simpler.

Actually I deleted all the language type stuff and just missed this. Thanks for catching it.

I have to look at the condition implementation, but this seems to suggest that this plugin will always evaluate, even if it was never configured. Is that correct?

Yes if you add this plugin and don't specify a limitation of a particular language(s) then we aren't going to deny access. You can of course deny access by negating the return.

This should have been the name :)

Not sure what you were saying here unless you were calling out the capitalized TRUE, in which case, I fixed it in this patch.

Thanks for the review!

Eclipse

Status: Needs review » Needs work

The last submitted patch, 1921550-interdiff.patch, failed testing.

EclipseGc’s picture

Status: Needs work » Needs review

misnamed the interdiff so it failed.

Gábor Hojtsy’s picture

Status: Needs review » Needs work
+++ b/core/modules/language/lib/Drupal/language/Plugin/Core/Condition/Language.phpundefined
@@ -0,0 +1,109 @@
+      $form['langcodes'] = array(
+        '#type' => 'checkboxes',
+        '#title' => t('Show this block only for specific languages'),
+        '#default_value' => !empty($this->configuration['langcodes']) ? $this->configuration['langcodes'] : array(),
+        '#options' => $langcodes_options,
+        '#description' => t('Show this block only for the selected language(s). If you select no languages, the block will be visibile in all languages.'),
+      );
+    }

Is this only going to be used for blocks?

+++ b/core/modules/language/lib/Drupal/language/Plugin/Core/Condition/Language.phpundefined
@@ -0,0 +1,109 @@
+    // Reduce the language list to an array of language names.
+    $language_names = array_reduce($language_list, function(&$result, $item) use ($selected) {
+      if (!empty($selected[$item->langcode])) {
+        $result[$item->langcode] = $item->name;
+      }
+      return $result;
+    }, array());

Is it commonplace / accepted now to use inline functions like this? I have not seen this much in Drupal core :)

+++ b/core/modules/language/lib/Drupal/language/Plugin/Core/Condition/Language.phpundefined
@@ -0,0 +1,109 @@
+    if (!empty($this->configuration['negate'])) {
+      return t('The language is not @languages.', array('@languages' => $languages,));
+    }
+    return t('The language is @languages.', array('@languages' => $languages,));

The commas at the ends do not fit our code style AFAIS, we don't include them if the array is all in one line.

+++ b/core/modules/language/lib/Drupal/language/Tests/Condition/LanguageConditionTest.phpundefined
@@ -0,0 +1,129 @@
+    variable_set('language_default', array(
+      'langcode' => 'it',
+      'name' => 'Italian',
+      'direction' => 0,
+      'weight' => 0,
+      'locked' => 0,
+    ));

You can/should language_load('it') instead to avoid repeating properties from above.

+++ b/core/modules/language/lib/Drupal/language/Tests/Condition/LanguageConditionTest.phpundefined
@@ -0,0 +1,129 @@
+    // Use the language interface now.
+    $condition = $this->manager->createInstance('language')
+      ->setConfig('langcodes', array('en' => 'en', 'it' => 'it'))
+      ->setContextValue('language', language(LANGUAGE_TYPE_INTERFACE));
+

interface language (vs language interface :D)

Also I don't see how is this different from checking the content language, since they are negotiated for the same value in this test. Merely changing the default language and reiniting the language manager will change both. So this is not really testing what happens if the interface language and the content language are different. That would need separate setup for them in the test instead of changing the default language and re-initing the manager.

EclipseGc’s picture

Status: Needs work » Needs review
FileSize
3.75 KB
7.88 KB

OK, changed everything asked for in #17 except the anonymous function. That is getting to be pretty common in a number of places in D8. Unless we really feel that it's detracting from this plugin, I'd prefer to just leave it since it works very nicely.

Eclipse

Gábor Hojtsy’s picture

Looks good. Only one note then.

+++ b/core/modules/language/lib/Drupal/language/Plugin/Core/Condition/Language.phpundefined
@@ -0,0 +1,109 @@
+        '#description' => t('Return TRUE only for the selected language(s). If no language is selected, this will return TRUE.'),

Is this not shown to regular users on the UI? "Returns TRUE" sounds like the least useful text if this ever ends up on a front facing UI.

EclipseGc’s picture

FileSize
926 bytes
7.86 KB

ok, trying to fix that too, how's this? (thanks tim.plunkett for the text, I was drawing a blank.)

Gábor Hojtsy’s picture

Looks good to me now. I cannot vouch for the correctness of the condition API use, but the language stuff looks good.

tim.plunkett’s picture

Status: Needs review » Needs work
+++ b/core/modules/language/lib/Drupal/language/Plugin/Core/Condition/Language.phpundefined
@@ -0,0 +1,109 @@
+   * Overrides \Drupal\Core\Condition\ConditionPluginBase::buildForm().
...
+   * Overrides \Drupal\Core\Condition\ConditionPluginBase::submitForm().
...
+   * Implements \Drupal\Core\Executable\ExecutableInterface::summary().
...
+   * Implements \Drupal\condition\ConditionInterface::evaluate().

Should be {@inheritdoc} now

+++ b/core/modules/language/lib/Drupal/language/Plugin/Core/Condition/Language.phpundefined
@@ -0,0 +1,109 @@
+    // Reduce the language list to an array of language names.
+    $language_names = array_reduce($language_list, function(&$result, $item) use ($selected) {
+      if (!empty($selected[$item->langcode])) {
+        $result[$item->langcode] = $item->name;
+      }
+      return $result;
+    }, array());
+
+    if (count($this->configuration['langcodes']) > 1) {
+      $languages = implode(', ', $language_names);
+    }
+    else {
+      $languages = array_pop($language_names);

I think this could use some more inline docs. The internal part of array_reduce, and both the if and else.

+++ b/core/modules/language/lib/Drupal/language/Plugin/Core/Condition/Language.phpundefined
@@ -0,0 +1,109 @@
+    if (!empty($this->configuration['langcodes'])) {
+      if (empty($this->configuration['langcodes'][$language->langcode])) {
+        return FALSE;
+      }
+    }
+    return TRUE;

I'm pretty sure this is redundant, since both are wrapped in empty, you only need one.
Could just be:
return !empty($this->configuration['langcodes'][$language->langcode]);

EclipseGc’s picture

Status: Needs work » Needs review
FileSize
2.65 KB
7.9 KB

Fair enough!

Eclipse

tim.plunkett’s picture

Status: Needs review » Reviewed & tested by the community

Those comments really help, thanks!

alexpott’s picture

Title: Create a Language check Condition » Change notice: Create a Language check Condition
Priority: Normal » Critical
Status: Reviewed & tested by the community » Active
Issue tags: +Needs change record

Committed 4e833c9 and pushed to 8.x. Thanks!

I think the conditions change notice might need an update...

larowlan’s picture

Priority: Critical » Normal
Status: Active » Fixed

Updated change notice here http://drupal.org/node/1961370.

larowlan’s picture

Assigned: larowlan » Unassigned
larowlan’s picture

Title: Change notice: Create a Language check Condition » Create a Language check Condition
jibran’s picture

Issue tags: -Needs change record

Removing tag.

Status: Fixed » Closed (fixed)

Automatically closed -- issue fixed for 2 weeks with no activity.