Completed
Push — master ( d9d1c9...d9076e )
by Dominik
02:29
created

AbstractDoctrineRepository::update()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 9
Code Lines 5

Duplication

Lines 9
Ratio 100 %

Importance

Changes 0
Metric Value
dl 9
loc 9
rs 9.6666
c 0
b 0
f 0
cc 1
eloc 5
nc 1
nop 1
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Chubbyphp\Model;
6
7
use Doctrine\DBAL\Connection;
8
use Doctrine\DBAL\Query\QueryBuilder;
9
use Psr\Log\LoggerInterface;
10
use Psr\Log\NullLogger;
11
12
abstract class AbstractDoctrineRepository implements RepositoryInterface
13
{
14
    /**
15
     * @var Connection
16
     */
17
    private $connection;
18
19
    /**
20
     * @var LoggerInterface
21
     */
22
    private $logger;
23
24
    /**
25
     * @param Connection $connection
26
     */
27
    public function __construct(Connection $connection, LoggerInterface $logger = null)
28
    {
29
        $this->connection = $connection;
30
        $this->logger = $logger ?? new NullLogger();
31
    }
32
33
    /**
34
     * @param string $id
35
     *
36
     * @return ModelInterface|null
37
     */
38
    public function find(string $id)
39
    {
40
        /** @var ModelInterface $modelClass */
41
        $modelClass = $this->getModelClass();
42
43
        $this->logger->info('Find model {model} with id {id}', ['model' => $modelClass, 'id' => $id]);
44
45
        $qb = $this->connection->createQueryBuilder();
46
        $qb->select('*')->from($this->getTable())->where($qb->expr()->eq('id', ':id'))->setParameter('id', $id);
47
48
        $row = $qb->execute()->fetch(\PDO::FETCH_ASSOC);
49
        if (false === $row) {
50
            $this->logger->warning('Model {model} with id {id} not found', ['model' => $modelClass, 'id' => $id]);
51
52
            return null;
53
        }
54
55
        return $modelClass::fromRow($row);
56
    }
57
58
    /**
59
     * @param array $criteria
60
     *
61
     * @return null|ModelInterface
62
     */
63
    public function findOneBy(array $criteria = [])
64
    {
65
        /** @var ModelInterface $modelClass */
66
        $modelClass = $this->getModelClass();
67
68
        $this->logger->info(
69
            'Find model {model} by criteria {criteria}',
70
            ['model' => $modelClass, 'criteria' => $criteria]
71
        );
72
73
        $qb = $this->getFindByQueryBuilder($criteria)->setMaxResults(1);
74
75
        $row = $qb->execute()->fetch(\PDO::FETCH_ASSOC);
76
        if (false === $row) {
77
            $this->logger->warning(
78
                'Model {model} by criteria {criteria} not found',
79
                ['model' => $modelClass, 'criteria' => $criteria]
80
            );
81
82
            return null;
83
        }
84
85
        return $modelClass::fromRow($row);
86
    }
87
88
    /**
89
     * @param array $criteria
90
     *
91
     * @return ModelInterface[]|array
92
     */
93
    public function findBy(array $criteria = []): array
94
    {
95
        /** @var ModelInterface $modelClass */
96
        $modelClass = $this->getModelClass();
97
98
        $this->logger->info(
99
            'Find model {model} by criteria {criteria}',
100
            ['model' => $modelClass, 'criteria' => $criteria]
101
        );
102
103
        $rows = $this->getFindByQueryBuilder($criteria)->execute()->fetchAll(\PDO::FETCH_ASSOC);
104
105
        if ([] === $rows) {
106
            return [];
107
        }
108
109
        $models = [];
110
        foreach ($rows as $row) {
111
            $models[] = $modelClass::fromRow($row);
112
        }
113
114
        return $models;
115
    }
116
117
    /**
118
     * @param array $criteria
119
     *
120
     * @return QueryBuilder
121
     */
122
    private function getFindByQueryBuilder(array $criteria = []): QueryBuilder
123
    {
124
        $qb = $this->connection->createQueryBuilder();
125
        $qb->select('*')->from($this->getTable());
126
127
        foreach ($criteria as $field => $value) {
128
            $qb->andWhere($qb->expr()->eq($field, ':'.$field));
129
            $qb->setParameter($field, $value);
130
        }
131
132
        return $qb;
133
    }
134
135
    /**
136
     * @param ModelInterface $model
137
     */
138 View Code Duplication
    public function insert(ModelInterface $model)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
139
    {
140
        $this->logger->info(
141
            'Insert model {model} with id {id}',
142
            ['model' => get_class($model), 'id' => $model->getId()]
143
        );
144
145
        $this->connection->insert($this->getTable(), $model->toRow());
146
    }
147
148
    /**
149
     * @param ModelInterface $model
150
     */
151 View Code Duplication
    public function update(ModelInterface $model)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
152
    {
153
        $this->logger->info(
154
            'Update model {model} with id {id}',
155
            ['model' => get_class($model), 'id' => $model->getId()]
156
        );
157
158
        $this->connection->update($this->getTable(), $model->toRow(), ['id' => $model->getId()]);
159
    }
160
161
    /**
162
     * @param ModelInterface $model
163
     */
164 View Code Duplication
    public function delete(ModelInterface $model)
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
165
    {
166
        $this->logger->info(
167
            'Delete model {model} with id {id}',
168
            ['model' => get_class($model), 'id' => $model->getId()]
169
        );
170
171
        $this->connection->delete($this->getTable(), ['id' => $model->getId()]);
172
    }
173
174
    /**
175
     * @return string
176
     */
177
    abstract protected function getTable(): string;
178
}
179