3

I have a module configuration.

modulename.config.yml

modulename:
  core_address: 107.101.xx.yy
  core_port: 153759
  core_user: superuser
  core_pass: superpass

I have a service.

modulename.service.yml

services:
    modulename.my_service:
        class: Drupal\modulename\group\MyService

MyService.php

/**
 * @file
 * Contains \Drupal\modulename\group\MyService.
 */
 
namespace Drupal\modulename\group;
 
/**
 * MyService.
 */
class MyService{

  public function __construct() { }
  
  public function getDemoValue() {
    $config =  \Drupal::config('modulename.my_service');
    $core_port = $config->get('modulename.core_port');
    return $core_port . 'asdf';
  }

}

$core_port is always empty.

How can I access a module configuration from a service it implements?

I am not sure this is relevant, but getDemoValue() is called from different a module.

/**
 * @file
 * Contains \Drupal\anothermodulename\Controller\MyForm.
 */
 
namespace Drupal\anothermodulename\Controller;
 
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Component\Utility\UrlHelper;
use Symfony\Component\DependencyInjection\ContainerInterface;

/**
 * MyForm.
 */
class MyForm extends FormBase {

  protected $demoService;
  
  /**
   * Class constructor.
   */
  public function __construct($demoService) {
    $this->demoService = $demoService;
  }
  
  /**
   * {@inheritdoc}
   */
  public static function create(ContainerInterface $container) {
    return new static(
      $container->get('modulename.my_service')
    );
  }

  /**
   * {@inheritdoc}
   */
  public function getFormId() { /** nothing interesting here **/ }

  /**
   * {@inheritdoc}
   */
  public function buildForm(array $form, FormStateInterface $form_state) {
    /** nothing interesting here **/
    return $form;
  }

  /**
   * {@inheritdoc}
   */
  public function validateForm(array &$form, FormStateInterface $form_state){ /** nothing interesting here **/ }

  /**
   * {@inheritdoc}
   */
  public function submitForm(array &$form, FormStateInterface $form_state) {
    // Display result.
    foreach ($form_state->getValues() as $key => $value) {
      drupal_set_message($key . ': ' . $value . '  ' . $this->demoService->getDemoValue()); // i try to print here but didn't happend
    }
  }

}
4
  • Your config file seems strange to me. The schema name is 'module.config' and that is what you should use in calls to $config->get(). You probably do not need or want 'modulename' in the config schema file content. Look at language.negotiation.yml language.schema.yml and language_negotiation_url_prefixes_update() or a full example.
    – mona lisa
    Commented Jun 2, 2016 at 17:55
  • @cilefen i dont have schema - only modulename.service.yml and modulename.config - do i need to have schema?
    – AnD
    Commented Jun 4, 2016 at 4:32
  • modulename.service.yml is not involved with this issue really. The problem is how you have named modulename.config.yml and the keys within it. A schema is necessary in order to have any tests and integration with the configuration system.
    – mona lisa
    Commented Jun 4, 2016 at 13:30
  • $config = \Drupal::configFactory()->getEditable('modulename.config') loads the entire configuration, then ->get() retrieves individual values. Read over my answer and the suggestions and example I referenced. Also see a module I work on: cgit.drupalcode.org/mathjax/tree
    – mona lisa
    Commented Jun 4, 2016 at 13:37

3 Answers 3

5

Use $config = \Drupal::configFactory()->getEditable('modulename.config').

And so on...

$core_port = $config->get('core_port');
$config->set('core_port', 8888)->save();

modulename.config.yml should be more like:

core_address: 107.101.xx.yy
core_port: 153759
core_user: superuser
core_pass: superpass
6
  • do you mind to explain to me why i should put: arguments: ['@config.factory']?
    – AnD
    Commented Jun 2, 2016 at 15:40
  • and it throw me error: "Service::__construct() must implement interface Drupal\Core\Config\ConfigFactoryInterface, none given,"
    – AnD
    Commented Jun 2, 2016 at 15:51
  • edited the answer...
    – mona lisa
    Commented Jun 2, 2016 at 16:00
  • See also drupal.stackexchange.com/questions/164713/…
    – mona lisa
    Commented Jun 2, 2016 at 16:05
  • i did return $config->get('modulename.core_port'); and it return nothing
    – AnD
    Commented Jun 2, 2016 at 16:10
3

To read the variables (configs) you'd do this:

$config = \Drupal::config('modulename.my_service');

$core_port = $config->get('modulename.core_port');

To write to the variables (configs) you'd do this:

// Set and save new message value.

$config = \Drupal::service('config.factory')->getEditable('modulename.my_service');
$config->set('modulename.core_port', 153760)->save();

There's an example you can look at in the core module aggregator.

It has a settings form at /core/modules/aggregator/src/Form/SettingsForm.php

and then it adds a route to access the settings form:

aggregator.admin_settings:
  path: '/admin/config/services/aggregator/settings'
  defaults:
    _form: '\Drupal\aggregator\Form\SettingsForm'
    _title: 'Feed aggregator settings'
  requirements:
    _permission: 'administer news feeds'

You could pretty much copy the form into your module and change the variables to match your config.

Generally you'll want to add the config in your service constructor.

namespace Drupal\modulename;

/**
 * Example Service with config.
 */
class MyService {


  /**
   * Drupal's settings manager.
   */
  protected $settings;

  /**
   * Constructor.
   */
  public function __construct() {
    $this->settings = \Drupal::config('modulename.my_service');
  }

}

Then you'd access the variables like this:

$this->settings->get('modulename.core_port');
7
  • I am not sure that config will be editable.
    – mona lisa
    Commented Jun 2, 2016 at 15:38
  • $this->settings->get('modulename.core_port'); return nothing
    – AnD
    Commented Jun 2, 2016 at 16:11
  • did you try this? $config = \Drupal::config('modulename.my_service'); $core_port = $config->get('modulename.core_port');
    – oknate
    Commented Jun 2, 2016 at 16:12
  • Also, keep in mind, you may need to reinstall your module with the config. You cannot add it after the fact.
    – oknate
    Commented Jun 2, 2016 at 16:12
  • yes just try reinstall the module and still return empty but no error
    – AnD
    Commented Jun 2, 2016 at 16:18
1

Given the code shown in the question, there are two errors in MyService::getDemoValue().

  • Since the configuration filename is modulename.config.yml, the configuration object should be created with \Drupal::config('modulename.config'), not \Drupal::config('modulename.my_service') which would instead work when the configuration filename is modulename.my_service.yml
  • Since none of the configuration values has a name that starts with modulename., the configuration values should be read with (for example) $config->get('core_port'), not $config->get('modulename.core_port')

That is the code to read a configuration object. To alter the configuration values and save them, \Drupal::configFactory()->getEditable('modulename.config') should be used instead of \Drupal::config('modulename.config'). In this case, setting core_port to 888 would be achieved using code similar to the following one.

$config = \Drupal::configFactory()->getEditable('modulename.config');
$config->set('core_port', 8888)
  ->save();

As a side note, Drupal services should use the dependency injection container instead of requiring any Drupal service to the \Drupal class. That is described in Services and Dependency Injection Container.

Your Answer

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

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