Test Failed
Push — master ( f5025a...9fb271 )
by Mathieu
04:42
created

Editortable::getResultsAfterEdit()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 12
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 7
dl 0
loc 12
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
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
     * {@inheritdoc}
20
     */
21
    public function __construct(QueryBuilder $query, string $identifier, array $columns, ?int $resultPerPage = self::RESULT_PER_PAGE)
22
    {
23
        parent::__construct($query, $identifier, $columns, $resultPerPage);
24
        $this->rootClass = $query->getRootEntities()[0];
25
    }
26
27
    /**
28
     * PRIVATE METHODS.
29
     */
30
31
    /**
32
     * @author Mathieu Petrini <[email protected]>
33
     *
34
     * @param object $entity
35
     * @param string $field
36
     * @param mixed  $value
37
     *
38
     * @return array
39
     */
40
    private function processValue(object $entity, string $field, $value): array
41
    {
42
        $ccField = self::toUpperCamelCase($field);
43
44
        $field = property_exists($entity, $ccField) ? $ccField : $field;
45
        if (property_exists($entity, $field)) {
46
            $associations = $this->query->getEntityManager()->getClassMetadata($this->rootClass)->associationMappings;
47
            if (isset($associations[$field])) {
48
                $value = $this->query->getEntityManager()->getRepository(
49
                    $associations[$field]['targetEntity']
50
                )->find($value);
51
            }
52
        }
53
54
        return array(
55
            'field' => $field,
56
            'setter' => 'set'.$ccField,
57
            'value' => $value,
58
        );
59
    }
60
61
    /**
62
     * @author Mathieu Petrini <[email protected]>
63
     *
64
     * @param object $entity
65
     * @param array  $data
66
     */
67
    private function processRowEditing(object $entity, array $data): void
68
    {
69
        foreach ($data as $field => $value) {
70
            $property = $this->processValue($entity, $field, $value);
71
72
            if (isset($entity->{$property['field']})) {
73
                $entity->{$property['field']} = $property['value'];
74
            } elseif (method_exists($entity, $property['setter'])) {
75
                $entity->{$property['setter']}($property['value']);
76
            }
77
        }
78
    }
79
80
    /**
81
     * @author Mathieu Petrini <[email protected]>
82
     *
83
     * @param array $params
84
     *
85
     * @return array
86
     */
87
    private function processEditing(array $params): array
88
    {
89
        $entities = array();
90
        $repository = $this->query->getEntityManager()->getRepository($this->rootClass);
91
        foreach ($params['data'] as $id => $row) {
92
            $entity = $repository->find($id);
93
            if (\is_object($entity)) {
94
                $this->processRowEditing($entity, $row);
95
                $entities[] = $entity;
96
            }
97
        }
98
99
        return $entities;
100
    }
101
102
    /**
103
     * @author Mathieu Petrini <[email protected]>
104
     *
105
     * @param object[] $entities
106
     *
107
     * @return array
108
     */
109
    private function getResultsAfterEdit(array $entities): array
110
    {
111
        if (empty($entities)) {
112
            return array();
113
        }
114
115
        return (clone $this->query)->where(
116
            $this->query->getRootAliases()[0].' IN (:entities)'
117
        )
118
            ->setParameter('entities', $entities)
119
            ->getQuery()
120
            ->getResult();
121
    }
122
123
    /**
124
     * PUBLIC METHODS.
125
     */
126
127
    /**
128
     * @author Mathieu Petrini <[email protected]>
129
     *
130
     * @param array $params
131
     *
132
     * @return array
133
     *
134
     * @throws MissingData
135
     */
136
    public function edit(array $params): array
137
    {
138
        if (!isset($params['data'])) {
139
            throw new MissingData();
140
        }
141
142
        return $this->getResultsAfterEdit(
143
            $this->processEditing($params)
144
        );
145
    }
146
147
    /**
148
     * @param string $field
149
     *
150
     * @return string
151
     */
152
    public static function toUpperCamelCase(string $field): string
153
    {
154
        return preg_replace_callback(
155
            '/_(.?)/',
156
            function (array $matches): string {
157
                return strtoupper($matches[1]);
158
            },
159
            ucfirst($field)
160
        );
161
    }
162
}
163