1

I need to add some properties to the ConfigurableLanguage. I need to have them editable when editing or adding a language and when getting language object from language manager service.

I can handle altering forms, but what about storing those properties and having them available with Language objects?

I was tempted to extend ConfigurableLangue and use hook_entity_type_build() to replace ConfigurableLangue class with my own implementation. However I'm not sure if works for config entities too (I've used this method with content entities). Nevertheless I've noticed scattered around core few calls to static ConfigurableLanguage::createFromLangcode() which returns instance of ConfigurableLanguage class. So extending ConfigurableLangue won't solve my problems.

1 Answer 1

2

Even if it might be late for the OP, here is the way to achieve this.

As language is stored as ConfigEntity, you can use ThirdPartySettingInterface.

Here is an example entity types are not correctly define in the link. which I based my own implementation on.

Steps to follow to achieve adding properties on language entity are a set of pretty common drupal development actions :

// Step 1 : Altering the configuration form ( language_admin_edit_form ) in this case.

/**
 * Implements hook_form_FORM_ID_alter().
 * @param $form
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 * @param $form_id
 */
function {our_module_name}_form_language_admin_edit_form_alter(
    &$form,
    \Drupal\Core\Form\FormStateInterface $form_state,
    $form_id) {

  //Step 2. We can retrieve the ConfigEntity the form is working on

  /** @var {\Drupal\language\Entity\ConfigurableLanguage} $language */
  $language = $form_state->getFormObject()->getEntity();

  //Step 3. Add our custom property(ies)
  $form['{name_of_our_property_1}'] = array(
    '#type' => 'checkbox',
    '#title' => t('Our custom property 1'),

    //Ok this is already a step ahead but, for the default_value
    //we can get the stored value in thirdPartySetting property of the ConfigEntity
    '#default_value' => $language->getThirdPartySetting('{our_module_name}', '{name_of_our_property_1}'),
  );

  //Step 4. We will need to hook before the entity is saved as config, 
  //in order to retrieve the property values on form, 
  //and adding thoses in the ConfigEntity thirdPartySetting property.
  $form['#entity_builders'][] = '{our_module_language_entity_builder_function_name}';
}

This will add form input with previously saved values on thirdPartySetting and add our custom entity builder. So lets define our custom entity builder :

/**
 * Our custom entity builder
 * @param $entity_type
 * @param \Drupal\language\Entity\ConfigurableLanguage $language
 * @param $form
 * @param \Drupal\Core\Form\FormStateInterface $form_state
 */
function {our_module_language_entity_builder_function_name}(
    $entity_type,
    \Drupal\language\Entity\ConfigurableLanguage $language, 
    &$form,
    \Drupal\Core\Form\FormStateInterface $form_state){

    //If our property can be found from form_state values
    if ($form_state->getValue('{name_of_our_property_1}')) {
        //We can update the linked property on thirdPartySetting
        $language->setThirdPartySetting(
            '{our_module_name}',
            '{name_of_our_property_1}', 
            $form_state->getValue('{name_of_our_property_1}')
        );
    }else{
        //User surely wanted to remove the previous value,
        //so remove it from thirdPartySetting property too
        $language->unsetThirdPartySetting('{our_module_name}', '{name_of_our_property_1}');
    }
}

Ok, now the edit form shows our property, our custom entity builder save it. Last step ahead, using our custom value somewhere else of the language edit form.

//So we have a language, it doesn't matter how you get it.
//Here is from the currentLanguage property

/** @var {\Drupal\Core\Language\LanguageInterface} $language */
$language = \Drupal::languageManager()->getCurrentLanguage();

//The language itself doesn't own the thirdPartySetting,
//So we need to use its matching ConfigEntity

//Getting the ConfigurableLanguageManager
/** {\Drupal\language\ConfigurableLanguageManager} $configManager */
$configManager = \Drupal::entityTypeManager()->getStorage('configurable_language');

//now load the matching ConfigEntity of Language
/** @var ConfigurableLanguage $config */
$languageConfigEntity= $configManager->load($language->getId());


//Do what you want of your property
$ourPropertyValue = $languageConfigEntity->getThirdPartySetting('{our_module_name}', '{name_of_our_property_1}');

//Alternatively we could get an array of all our module thirdPartySetting properties
$allOurProps = $languageConfigEntity->getThirdPartySettings('{our_module_name}');

//And it's done.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.