Buy

Configuration Parameters

New challenge: what if we need to turn off the key value store stuff while we're developing, but keep it for production? Maybe you're thinking "just comment it out temporarily!". That might work for you, but eventually, I'm going to forget to uncomment it and deploy this to production with caching off. Then, traffic will run-over the site and nobody will get any roars. I think we can do better.

Injecting Configuration

Solution? Make RoarGenerator configurable. That means, add a new argument to __construct: $useCache. Hit option+enter to create the property and set it:

37 lines modules/dino_roar/src/Jurassic/RoarGenerator.php
... lines 1 - 6
class RoarGenerator
{
... line 9
private $useCache;
public function __construct(KeyValueFactoryInterface $keyValueFactory, $useCache)
{
... line 14
$this->useCache = $useCache;
}
... lines 17 - 35
}

This will be a boolean that controls whether or not we should cache.

Down below, update the if statement: if $this->useCache and the store has it, then return it. Below, add another if statement that says we should only store this in the cache if $this->useCache is true:

37 lines modules/dino_roar/src/Jurassic/RoarGenerator.php
... lines 1 - 17
public function getRoar($length)
{
... lines 20 - 22
if ($this->useCache && $store->has($key)) {
return $store->get($key);
}
... lines 26 - 28
$string = 'R'.str_repeat('O', $length).'AR!';
if ($this->useCache) {
$store->set($key, $string);
}
... lines 33 - 34
}
... lines 36 - 37

The RoarGenerator is now perfect: whoever creates it can control this behavior. Because we added a second constructor argument, we need to update the service configuration. Add another line with a - and set the second argument to true... for now:

7 lines modules/dino_roar/dino_roar.services.yml
services:
dino_roar.roar_generator:
class: Drupal\dino_roar\Jurassic\RoarGenerator
arguments:
- '@keyvalue'
- true

Time to test: rebuild the cache:

drupal cache:rebuild

Refresh! The cache is activated... and everything is still really, really fast. If you try 51, that's not cached yet, but it's fast on the second load.

Introducing: Parameters

But this didn't solve our problem, it just moved the code we need to change from RoarGenerator into the service file.

In addition to the services key - that can hold many services - these files are allowed to have one other root key: parameters. The parameter system is a key-value configuration system. This means... I lied to you! The service container isn't just an array-like object that holds services. It also holds a key-value configuration system called parameters.

Add a new parameter called dyno.roar.use_key_value_cache and set it to true:

10 lines modules/dino_roar/dino_roar.services.yml
parameters:
dino.roar.use_key_value_cache: true
... lines 3 - 10

To use this, I gotta tell you about the one other magic syntax in these files. That is, use % - the name of the parameter - then %:

10 lines modules/dino_roar/dino_roar.services.yml
... lines 1 - 3
services:
dino_roar.roar_generator:
... line 6
arguments:
... line 8
- '%dino.roar.use_key_value_cache%'

When you surround something with percent signs, the container finds a parameter by this name and passes that.

And there's a bonus: these parameters can be accessed in any of these service files. That means that if we define parameter A in one module, you can use it - or even change it - somewhere else. This ends up being critical to how you can control the core of Drupal. And yes, we'll talk about that soon!

But first, rebuild the cache real quick for a sanity check:

drupal cache:rebuild

Refresh! Everyone is still happy! We're awesome now with parameters... but we still haven't quite solved our problem.

Leave a comment!

  • 2016-05-07 weaverryan

    You're right - how fast the world moves :). You now need to put quotes around the parameters. But, not quoting them will still be allowed until Symfony 4 (so you have a few years to change them).

    Cheers!

  • 2016-05-06 Evlad

    Not quoting a scalar starting with the “%” indicator character is deprecated since Symfony 3.1