Completed
Pull Request — v2 (#7)
by Guillaume
01:25
created

AbstractEntityService::setPropertiesToEntity()   B

Complexity

Conditions 7
Paths 7

Size

Total Lines 36

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 36
c 0
b 0
f 0
rs 8.4106
cc 7
nc 7
nop 3
1
<?php
2
3
namespace ETNA\Doctrine\Entity;
4
5
use Doctrine\ORM\EntityManagerInterface;
6
use Symfony\Component\Validator\Validator\ValidatorInterface;
7
8
abstract class AbstractEntityService
9
{
10
    /** @var EntityManagerInterface L'entity manager */
11
    protected $em;
12
13
    /** @var ValidatorInterface Le service pour la validation des data */
14
    protected $validator;
15
16
    protected function __construct(EntityManagerInterface $em, ValidatorInterface $validator)
17
    {
18
        $this->em        = $em;
19
        $this->validator = $validator;
20
    }
21
22
    /**
23
     * Filtre les champs directs (pas les jointures) de $datas, en fonction des groupes de validation
24
     * Et rempli l'entité avec les données filtrées, et éventuellement re-typées.
25
26
     * Permet de scénariser les modifications d'entités grace aux groupes de validation.
27
     *
28
     * @see https://symfony.com/doc/current/validation/groups.html
29
     *
30
     * @param array          $datas
31
     * @param array          $validation_groups
32
     * @param AbstractEntity $entity
33
     *
34
     * @return array
0 ignored issues
show
Documentation introduced by
Should the return type not be array|null? Also, consider making the array more specific, something like array<String>, or String[].

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

If the return type contains the type array, this check recommends the use of a more specific type like String[] or array<String>.

Loading history...
35
     */
36
    protected function setPropertiesToEntity(array $datas, array $validation_groups, AbstractEntity $entity)
37
    {
38
        $filtered_datas            = [];
39
        $validation_field_metadata = $this->validator->getMetadataFor($entity)->members;
0 ignored issues
show
Bug introduced by
Accessing members on the interface Symfony\Component\Valida...pping\MetadataInterface suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
40
        $doctrine_field_metadata   = $this->em->getClassMetadata(get_class($entity))->fieldMappings;
0 ignored issues
show
Bug introduced by
Accessing fieldMappings on the interface Doctrine\Common\Persistence\Mapping\ClassMetadata suggest that you code against a concrete implementation. How about adding an instanceof check?

If you access a property on an interface, you most likely code against a concrete implementation of the interface.

Available Fixes

  1. Adding an additional type check:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeInterface $object) {
        if ($object instanceof SomeClass) {
            $a = $object->a;
        }
    }
    
  2. Changing the type hint:

    interface SomeInterface { }
    class SomeClass implements SomeInterface {
        public $a;
    }
    
    function someFunction(SomeClass $object) {
        $a = $object->a;
    }
    
Loading history...
41
        $all_fields                = array_keys($doctrine_field_metadata);
42
43
        foreach ($datas as $field_name => $data_value) {
44
            $is_field_concerned = false;
45
46
            if (isset($validation_field_metadata[$field_name])) {
47
                $constraints             = array_shift($validation_field_metadata[$field_name]);
48
                $field_validation_groups = array_keys($constraints->constraintsByGroup);
49
                $is_field_concerned      = !empty(array_intersect($validation_groups, $field_validation_groups));
50
            }
51
52
            switch (true) {
53
                // Si la data concerne un champ qui ne fait pas parti de l'entité, on passe
54
                case !in_array($field_name, $all_fields) || !$is_field_concerned:
55
                    break;
56
                // Si la data concerne un champ date ou assimilé, et que c'est une string, on sette un DateTime
57
                case 1 === preg_match(
58
                    "#^(date|datetime|time)[a-z_]*$#",
59
                    $doctrine_field_metadata[$field_name]["type"]
60
                ) && is_string($data_value):
61
                    $filtered_datas[$field_name] = new \DateTime($data_value);
62
                    break;
63
                // Sinon on sette tel quel
64
                default:
65
                    $filtered_datas[$field_name] = $data_value;
66
                    break;
67
            }
68
        }
69
70
        $entity->setProperties($filtered_datas);
71
    }
72
}
73