Editortable::processRowEditing()   A
last analyzed

Complexity

Conditions 6
Paths 7

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 6
eloc 10
nc 7
nop 2
dl 0
loc 18
rs 9.2222
c 2
b 0
f 0
1
<?php
2
3
namespace DoctrineDatatable;
4
5
use Doctrine\ORM\QueryBuilder;
6
use DoctrineDatatable\Exception\MissingData;
7
8
/**
9
 * Class Editortable.
10
 */
11
class Editortable extends Datatable
12
{
13
    /**
14
     * @var string
15
     */
16
    private $rootClass;
17
18
    /**
19
     * @var string[]
20
     */
21
    private $parameters;
22
23
    /**
24
     * Editortable constructor.
25
     *
26
     * @author Mathieu Petrini <[email protected]>
27
     *
28
     * @param QueryBuilder $query
29
     * @param string       $identifier
30
     * @param Column[]     $columns
31
     * @param string[]     $parameters
32
     *
33
     * @throws Exception\MinimumColumn
34
     */
35
    public function __construct(QueryBuilder $query, string $identifier, array $columns, array $parameters = array())
36
    {
37
        parent::__construct($query, $identifier, $columns);
38
        $this->rootClass = $query->getRootEntities()[0];
39
        $this->parameters = $parameters;
40
    }
41
42
    /**
43
     * PRIVATE METHODS.
44
     */
45
46
    /**
47
     * @author Mathieu Petrini <[email protected]>
48
     *
49
     * @param object $entity
50
     * @param string $field
51
     * @param mixed  $value
52
     *
53
     * @return string[]
54
     */
55
    private function processValue(object $entity, string $field, $value): array
56
    {
57
        $ccField = self::toUpperCamelCase($field);
58
59
        $field = property_exists($entity, $ccField) ? $ccField : $field;
60
        if (property_exists($entity, $field)) {
61
            $associations = $this->query->getEntityManager()->getClassMetadata($this->rootClass)->associationMappings;
62
            if (isset($associations[$field])) {
63
                $value = $this->query->getEntityManager()->getRepository(
64
                    $associations[$field]['targetEntity']
65
                )->find($value);
66
            }
67
        }
68
69
        return array(
0 ignored issues
show
Bug Best Practice introduced by
The expression return array('field' => ...eld, 'value' => $value) returns an array which contains values of type object which are incompatible with the documented value type string.
Loading history...
70
            'field' => $field,
71
            'setter' => 'set'.$ccField,
72
            'value' => $value,
73
        );
74
    }
75
76
    /**
77
     * @author Mathieu Petrini <[email protected]>
78
     *
79
     * @param object  $entity
80
     * @param mixed[] $data
81
     *
82
     * @return object[]
83
     */
84
    private function processRowEditing(object $entity, array $data): array
85
    {
86
        $entities = array();
87
        foreach ($data as $field => $value) {
88
            $property = $this->processValue($entity, $field, $value);
89
90
            if (isset($entity->{$property['field']})) {
91
                $result = $entity->{$property['field']} = $property['value'];
92
            } elseif (method_exists($entity, $property['setter'])) {
93
                $result = $entity->{$property['setter']}($property['value']);
94
            }
95
96
            if (isset($result) && \is_object($result)) {
97
                $entities[] = $result;
98
            }
99
        }
100
101
        return $entities;
102
    }
103
104
    /**
105
     * @author Mathieu Petrini <[email protected]>
106
     *
107
     * @param mixed[] $params
108
     *
109
     * @return object[]
110
     */
111
    private function processEditing(array $params): array
112
    {
113
        $entities = array();
114
        $repository = $this->query->getEntityManager()->getRepository($this->rootClass);
115
        foreach ($params['data'] as $id => $row) {
116
            $entity = $repository->find($id);
117
            if (\is_object($entity)) {
118
                $entities = array_merge(
119
                    $entities,
120
                    $this->processRowEditing($entity, $row)
121
                );
122
            }
123
        }
124
125
        return $entities;
126
    }
127
128
    /**
129
     * @author Mathieu Petrini <[email protected]>
130
     *
131
     * @param object[] $entities
132
     *
133
     * @return mixed[]
134
     *
135
     * @throws \Doctrine\ORM\ORMException
136
     * @throws \Doctrine\ORM\OptimisticLockException
137
     */
138
    private function getResultsAfterEdit(array $entities): array
139
    {
140
        if (empty($entities)) {
141
            return array();
142
        }
143
144
        $this->query->getEntityManager()->getUnitOfWork()->computeChangeSets();
145
        $this->query->getEntityManager()->flush($entities);
146
147
        return $this->createQueryResult()
148
            ->where($this->query->getRootAliases()[0].' IN (:entities)')
149
            ->setParameters(array_merge(
150
                $this->parameters,
151
                array(
152
                    'entities' => $entities,
153
                )
154
            ))
155
            ->getQuery()
156
            ->getResult();
157
    }
158
159
    /**
160
     * PUBLIC METHODS.
161
     */
162
163
    /**
164
     * @author Mathieu Petrini <[email protected]>
165
     *
166
     * @param mixed[] $params
167
     *
168
     * @return mixed[]
169
     *
170
     * @throws MissingData
171
     * @throws \Doctrine\ORM\ORMException
172
     * @throws \Doctrine\ORM\OptimisticLockException
173
     */
174
    public function edit(array $params): array
175
    {
176
        if (!isset($params['data'])) {
177
            throw new MissingData();
178
        }
179
180
        return $this->getResultsAfterEdit(
181
            $this->processEditing($params)
182
        );
183
    }
184
185
    /**
186
     * @param string $field
187
     *
188
     * @return string
189
     */
190
    public static function toUpperCamelCase(string $field): string
191
    {
192
        return preg_replace_callback(
193
            '/_(.?)/',
194
            /**
195
             * @param string[] $matches
196
             *
197
             * @return string
198
             */
199
            function (array $matches): string {
200
                return strtoupper($matches[1]);
201
            },
202
            ucfirst($field)
203
        );
204
    }
205
}
206