Passed
Push — master ( 336aa4...192c12 )
by Fran
02:09
created

NOSQLActiveRecord::prepareInsertDtos()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 15
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
eloc 11
dl 0
loc 15
rs 9.9
c 0
b 0
f 0
cc 2
nc 2
nop 2
1
<?php
2
namespace NOSQL\Models;
3
4
use MongoDB\BSON\ObjectId;
5
use MongoDB\Database;
6
use NOSQL\Dto\Model\NOSQLModelDto;
7
use NOSQL\Models\base\NOSQLModelTrait;
8
use NOSQL\Models\base\NOSQLParserTrait;
9
use NOSQL\Services\ParserService;
10
use PSFS\base\Logger;
11
use PSFS\base\types\traits\SingletonTrait;
12
13
/**
14
 * Class NOSQLActiveRecord
15
 * @package NOSQL\Models
16
 */
17
abstract class NOSQLActiveRecord {
18
    use NOSQLModelTrait;
19
    use NOSQLParserTrait;
20
    use SingletonTrait;
21
22
    /**
23
     * NOSQLActiveRecord constructor.
24
     * @throws \NOSQL\Exceptions\NOSQLParserException
25
     * @throws \PSFS\base\exception\GeneratorException
26
     */
27
    public function __construct()
28
    {
29
        $this->hydrate();
30
    }
31
32
    /**
33
     * @return array
34
     */
35
    public function toArray() {
36
        return $this->dto->toArray();
37
    }
38
39
    /**
40
     * @param bool $cleanPk
41
     * @return \NOSQL\Dto\Model\NOSQLModelDto
42
     */
43
    public function getDtoCopy($cleanPk = false) {
44
        $copy = clone $this->dto;
45
        if($cleanPk) {
46
            $this->dto->resetPk();
47
        }
48
        return $copy;
49
    }
50
51
    /**
52
     * @param Database|null $con
53
     * @return bool
54
     */
55
    public function save(Database $con = null) {
56
        $saved = false;
57
        if(null === $con) {
58
            $con = ParserService::getInstance()->createConnection($this->getDomain());
59
        }
60
        $collection = $con->selectCollection($this->getSchema()->name);
61
        try {
62
            $isInsert = $isUpdate = false;
63
            $this->dto->setLastUpdate(new \DateTime());
64
            if($this->isNew()) {
65
                $this->preInsert($con);
66
                $isInsert = true;
67
            } elseif ($this->isModified()) {
68
                $this->preUpdate($con);
69
                $isUpdate = true;
70
            }
71
            $result = $collection->insertOne($this->toArray());
72
            if($result->getInsertedCount() > 0) {
73
                $id = $result->getInsertedId();
74
                $this->dto->setPk($id->jsonSerialize()['$oid']);
75
                if($isInsert) {
76
                    $this->postInsert($con);
77
                } elseif($isUpdate) {
78
                    $this->postUpdate($con);
79
                }
80
                $saved = true;
81
            }
82
        } catch(\Exception $exception) {
83
            Logger::log($exception, LOG_CRIT, $this->toArray());
84
        }
85
        return $saved;
86
    }
87
88
    /**
89
     * @param Database|null $con
90
     * @return bool
91
     */
92
    public function update(Database $con = null) {
93
        $updated = false;
94
        if(null === $con) {
95
            $con = ParserService::getInstance()->createConnection($this->getDomain());
96
        }
97
        $collection = $con->selectCollection($this->getSchema()->name);
98
        try {
99
            $this->dto->setLastUpdate(new \DateTime());
100
            $this->preUpdate($con);
101
            $data = $this->toArray();
102
            unset($data['_id']);
103
            $collection->findOneAndReplace(['_id' => new ObjectId($this->dto->getPk())], $data);
104
            $this->postUpdate($con);
105
            $updated = true;
106
        } catch(\Exception $exception) {
107
            Logger::log($exception, LOG_CRIT, $this->toArray());
108
        }
109
        return $updated;
110
    }
111
112
    /**
113
     * @param array $data
114
     * @param Database|null $con
115
     * @return int
116
     */
117
    public function bulkInsert(array $data, Database $con = null) {
118
        $inserts = 0;
119
        if(null === $con) {
120
            $con = ParserService::getInstance()->createConnection($this->getDomain());
121
        }
122
        $collection = $con->selectCollection($this->getSchema()->name);
123
        try {
124
            $dtos = $this->prepareInsertDtos($data, $con);
125
            $result = $collection->insertMany($data);
126
            $ids = $result->getInsertedIds();
127
            $inserts = $this->parseInsertedDtos($con, $ids, $dtos);
128
        } catch(\Exception $exception) {
129
            Logger::log($exception, LOG_CRIT, $this->toArray());
130
        }
131
        return $inserts;
132
    }
133
134
    /**
135
     * @param Database|null $con
136
     * @return bool
137
     */
138
    public function delete(Database $con = null) {
139
        $deleted = false;
140
        if(null === $con) {
141
            $con = ParserService::getInstance()->createConnection($this->getDomain());
142
        }
143
        $collection = $con->selectCollection($this->getSchema()->name);
144
        try {
145
            $this->preDelete($con);
146
            $collection->deleteOne(['_id' => new ObjectId($this->dto->getPk())]);
147
            $this->postDelete($con);
148
            $deleted = true;
149
            $this->dto = null;
150
        } catch(\Exception $exception) {
151
            Logger::log($exception, LOG_CRIT, $this->toArray());
152
        }
153
        return $deleted;
154
    }
155
156
    /**
157
     * @param array $data
158
     * @param Database $con
159
     * @return array
160
     * @throws \NOSQL\Exceptions\NOSQLValidationException
161
     */
162
    private function prepareInsertDtos(array $data, Database $con)
163
    {
164
        $dtos = [];
165
        /** @var NOSQLModelDto $dto */
166
        $now = new \DateTime();
167
        foreach ($data as $insertData) {
168
            $dto = $this->getDtoCopy(true);
169
            $dto->fromArray($insertData);
170
            $dto->setLastUpdate($now);
171
            $dtos[] = $dto;
172
            self::invokeHook($this, $dto, 'preInsert', $con);
173
            self::invokeHook($this, $dto, 'preSave', $con);
174
        }
175
        unset($dto);
176
        return $dtos;
177
    }
178
179
    /**
180
     * @param Database $con
181
     * @param ObjectId[] $ids
182
     * @param NOSQLModelDto[] $dtos
183
     * @return int
184
     * @throws \NOSQL\Exceptions\NOSQLValidationException
185
     */
186
    private function parseInsertedDtos(Database $con, $ids, $dtos)
187
    {
188
        $inserts = 0;
189
        foreach ($ids as $index => $insertedId) {
190
            $id = $insertedId->jsonSerialize();
0 ignored issues
show
Bug introduced by
The method jsonSerialize() does not exist on MongoDB\BSON\ObjectId. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

190
            /** @scrutinizer ignore-call */ 
191
            $id = $insertedId->jsonSerialize();

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
191
            $dtos[$index]->setPk($id['$oid']);
192
            self::invokeHook($this, $dtos[$index], 'postInsert', $con);
193
            self::invokeHook($this, $dtos[$index], 'postSave', $con);
194
            $inserts++;
195
        }
196
        return $inserts;
197
    }
198
}