Completed
Push — master ( 3fd2dd...aba624 )
by Grégoire
04:19
created

DataTransformer/ModelToIdPropertyTransformer.php (1 issue)

Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of the Sonata Project package.
7
 *
8
 * (c) Thomas Rabaix <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Sonata\AdminBundle\Form\DataTransformer;
15
16
use Doctrine\Common\Util\ClassUtils;
17
use Sonata\AdminBundle\Model\ModelManagerInterface;
18
use Symfony\Component\Form\DataTransformerInterface;
19
20
/**
21
 * Transform object to ID and property label.
22
 *
23
 * @author Andrej Hudec <[email protected]>
24
 */
25
class ModelToIdPropertyTransformer implements DataTransformerInterface
26
{
27
    /**
28
     * @var ModelManagerInterface
29
     */
30
    protected $modelManager;
31
32
    /**
33
     * @var string
34
     */
35
    protected $className;
36
37
    /**
38
     * @var string
39
     */
40
    protected $property;
41
42
    /**
43
     * @var bool
44
     */
45
    protected $multiple;
46
47
    /**
48
     * @var callable|null
49
     */
50
    protected $toStringCallback;
51
52
    /**
53
     * @param string        $className
54
     * @param string        $property
55
     * @param bool          $multiple
56
     * @param callable|null $toStringCallback
57
     */
58
    public function __construct(
59
        ModelManagerInterface $modelManager,
60
        $className,
61
        $property,
62
        $multiple = false,
63
        $toStringCallback = null
64
    ) {
65
        $this->modelManager = $modelManager;
66
        $this->className = $className;
67
        $this->property = $property;
68
        $this->multiple = $multiple;
69
        $this->toStringCallback = $toStringCallback;
70
    }
71
72
    public function reverseTransform($value)
73
    {
74
        $collection = $this->modelManager->getModelCollectionInstance($this->className);
75
76
        if (empty($value)) {
77
            if ($this->multiple) {
78
                return $collection;
79
            }
80
81
            return;
82
        }
83
84
        if (!$this->multiple) {
85
            return $this->modelManager->find($this->className, $value);
86
        }
87
88
        if (!\is_array($value)) {
89
            throw new \UnexpectedValueException(sprintf('Value should be array, %s given.', \gettype($value)));
90
        }
91
92
        foreach ($value as $key => $id) {
93
            if ('_labels' === $key) {
94
                continue;
95
            }
96
97
            $collection[] = $this->modelManager->find($this->className, $id);
98
        }
99
100
        return $collection;
101
    }
102
103
    public function transform($entityOrCollection)
104
    {
105
        $result = [];
106
107
        if (!$entityOrCollection) {
108
            return $result;
109
        }
110
111
        if ($this->multiple) {
112
            $isArray = \is_array($entityOrCollection);
113
            if (!$isArray && substr(\get_class($entityOrCollection), -1 * \strlen($this->className)) === $this->className) {
114
                throw new \InvalidArgumentException('A multiple selection must be passed a collection not a single value. Make sure that form option "multiple=false" is set for many-to-one relation and "multiple=true" is set for many-to-many or one-to-many relations.');
115
            } elseif ($isArray || ($entityOrCollection instanceof \ArrayAccess)) {
116
                $collection = $entityOrCollection;
117
            } else {
118
                throw new \InvalidArgumentException('A multiple selection must be passed a collection not a single value. Make sure that form option "multiple=false" is set for many-to-one relation and "multiple=true" is set for many-to-many or one-to-many relations.');
119
            }
120
        } else {
121
            if (substr(\get_class($entityOrCollection), -1 * \strlen($this->className)) === $this->className) {
122
                $collection = [$entityOrCollection];
123
            } elseif ($entityOrCollection instanceof \ArrayAccess) {
124
                throw new \InvalidArgumentException('A single selection must be passed a single value not a collection. Make sure that form option "multiple=false" is set for many-to-one relation and "multiple=true" is set for many-to-many or one-to-many relations.');
125
            } else {
126
                $collection = [$entityOrCollection];
127
            }
128
        }
129
130
        if (empty($this->property)) {
131
            throw new \RuntimeException('Please define "property" parameter.');
132
        }
133
134
        foreach ($collection as $entity) {
135
            $id = current($this->modelManager->getIdentifierValues($entity));
136
137
            if (null !== $this->toStringCallback) {
138
                if (!\is_callable($this->toStringCallback)) {
139
                    throw new \RuntimeException('Callback in "to_string_callback" option doesn`t contain callable function.');
140
                }
141
142
                $label = \call_user_func($this->toStringCallback, $entity, $this->property);
143
            } else {
144
                try {
145
                    $label = (string) $entity;
146
                } catch (\Exception $e) {
0 ignored issues
show
catch (\Exception $e) { ...ss($entity)), 0, $e); } does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
147
                    throw new \RuntimeException(sprintf("Unable to convert the entity %s to String, entity must have a '__toString()' method defined", ClassUtils::getClass($entity)), 0, $e);
148
                }
149
            }
150
151
            $result[] = $id;
152
            $result['_labels'][] = $label;
153
        }
154
155
        return $result;
156
    }
157
}
158