/DictionaryBundle

Are you often tired to repeat static choices like gender or civility in your apps ?

Primary LanguagePHPMIT LicenseMIT

DictionaryBundle

This fork is nearly identical to https://github.com/KnpLabs/DictionaryBundle, but allows for Symfony 6.3 and adds some return types to avoid deprecation warnings.

It also bumps the minimum requirements to php8, since php 7.4 is past EOL.

CircleCI Scrutinizer Code Quality

Are you often tired to repeat static choices like gender or civility in your apps ?

Requirements

  • PHP >= 7.4
  • Symfony 5.4 or >= 6.0

Installation

Run the following command:

composer require knplabs/dictionary-bundle

Register the bundle in app/AppKernel.php

$bundles = array(
    // ...
    new Knp\DictionaryBundle\KnpDictionaryBundle(),
);

Maintainers

You can ping us if need some reviews/comments/help:

Basic usage

Define dictionaries in your config.yml file:

knp_dictionary:
  dictionaries:
    my_dictionary: # your dictionary name
      - Foo        # your dictionary content
      - Bar
      - Baz

You will be able to retreive it by injecting the Collection service and accessing the dictionary by its key

    private Dictionary $myDictionary;
    public function __construct(
        \Knp\DictionaryBundle\Dictionary\Collection $dictionaries)
    {
        $this->myDictionary = $dictionaries['my_dictionary'];
    }

Dictionary form type

Now, use them in your forms:

use Knp\DictionaryBundle\Form\Type\DictionaryType;

public function buildForm(FormBuilderInterface $builder, array $options)
{
    $builder
        ->add('civility', DictionaryType::class, array(
            'name' => 'my_dictionary'
        ))
    ;
}

The dictionary form type extends the symfony's choice type and its options.

Validation constraint

You can also use the constraint for validation. The value has to be set.

use Knp\DictionaryBundle\Validator\Constraints\Dictionary;

class User
{
    /**
     * @ORM\Column
     * @Dictionary(name="my_dictionary")
     */
    private $civility;
}

Advanced usage

You can specify the indexation mode of each dictionary

knp_dictionary:
  dictionaries:
    my_dictionary:      # your dictionary name
      type: 'key_value' # your dictionary type
      content:          # your dictionary content
        "foo": "foo_value"
        "bar": "bar_value"
        "baz": "baz_value"

Available types

  • value (default) : Natural indexation
  • value_as_key: Keys are defined from their value
  • key_value: Define your own keys
  • callable: Build a dictionary from a callable

Callable dictionary

You can create a callable dictionary:

knp_dictionary:
  dictionaries:
    my_callable_dictionary:     # your dictionary name
      type: 'callable'          # your dictionary type
      service: 'app.service.id' # a valid service from your application
      method: 'getSomething'    # the method name to execute

Callable dictionaries are loaded with a lazy strategy. It means that the callable will not be called if you do not use the dictionary.

Iterator based dictionary

You can create a dictionary from an iterator:

knp_dictionary:
  dictionaries:
    my_iterator_dictionary:     # your dictionary name
      type: 'iterator'          # your dictionary type
      service: 'app.service.id' # a valid service from your application

Iterator based dictionaries are loaded with a lazy strategy. It means that the iterator will not be fetched if you do not use the dictionary.

Combined dictionary

You can combine multiple dictionaries into a single one:

knp_dictionary:
  dictionaries:
    payment_mode:
      type: key_value
      content:
        card: "credit card"
        none: "none"

    extra_payment_mode:
      type: key_value
      content:
        bank_transfer: "Bank transfer"
        other: "Other"

    combined_payment_mode:
      type: combined
      dictionaries:
        - payment_mode
        - extra_payment_mode

Now you have 3 dictionaries, payment_mode and extra_payment_mode contain their own values but combined_payment_mode contains all the values of the previous ones.

Extended dictionary

You can create an extended dictionary:

knp_dictionary:
  dictionaries:
    europe:
      type: 'key_value'
      content:
        fr: France
        de: Germany

    world:
      type: 'key_value'
      extends: europe
      content:
        us: USA
        ca: Canada

The dictionary world will now contain its own values in addition to the europe values.

Note: You must define the initial dictionary BEFORE the extended one.

Transformers

For now, this bundle is only able to resolve your class constants:

my_dictionary:
  - MyClass::MY_CONSTANT
  - Foo
  - Bar

You want to add other kinds of transformations for your dictionary values ? Feel free to create your own transformer !

Add your own transformers

Create your class that implements TransformerInterface. Load your transformer and tag it as knp_dictionary.value_transformer.

services:
  App\My\Transformer:
    tags:
      - knp_dictionary.value_transformer

Use your dictionary in twig

You can also use your dictionary in your Twig templates via calling dictionary function (or filter).

{% for example in dictionary('examples') %}
    {{ example }}
{% endfor %}

But you can also access directly to a value by using the same function (or filter)

{{ 'my_key'|dictionary('dictionary_name') }}

Faker provider

The KnpDictionaryBundle comes with a faker provider that can be used to provide a random entry from a dictionary.

Alice

To register the provider in nelmio/alice, you can follow the official documentation

App\Entity\User:
  john_doe:
    firstname: John
    latnale: Doe
    city: <dictionary('cities')>

Create your own dictionary implementation

Dictionary

Your dictionary implementation must implements the interface Dictionary.

It is automaticaly registered with the autoconfigure: true DIC feature.

Else you can register it by your self:

services:
  App\Dictionary\MyCustomDictionary:
    tags:
      - knp_dictionary.dictionary

Dictionary Factory

You must create a dictionary factory that will be responsible to instanciate your dictionary.

It is automaticaly registered with the autoconfigure: true DIC feature.

Else you can register it by your self:

services:
  App\Dictionary\Factory\MyCustomFactory:
    tags:
      - knp_dictionary.factory

Tests

phpspec

composer install
vendor/bin/phpspec run

php-cs-fixer

composer install
vendor/bin/php-cs-fixer fix

phpstan

First install phive.

Then...

phive install
tools/phpstan process

rector (optional)

rector process --set php70 --set php71 --set php72 --set code-quality --set coding-style --set symfony34 --set twig240 --set psr-4 --set solid src/ spec/