Passed
Push — master ( 9ad278...1bcf8b )
by Dispositif
08:55
created

DbAdapter::deleteArticle()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 8
nc 2
nop 1
dl 0
loc 14
ccs 0
cts 8
cp 0
crap 6
rs 10
c 1
b 0
f 0
1
<?php
2
/**
3
 * This file is part of dispositif/wikibot application
4
 * 2019 : Philippe M. <[email protected]>
5
 * For the full copyright and MIT license information, please view the LICENSE file.
6
 */
7
8
declare(strict_types=1);
9
10
namespace App\Infrastructure;
11
12
use App\Application\QueueInterface;
13
use DateInterval;
14
use DateTime;
15
use Exception;
16
use Simplon\Mysql\Mysql;
17
use Simplon\Mysql\MysqlException;
18
use Simplon\Mysql\PDOConnector;
19
use Throwable;
20
21
/**
22
 * Temporary SQL play. https://github.com/fightbulc/simplon_mysql .
23
 * Class DbAdapter.
24
 */
25
class DbAdapter implements QueueInterface
26
{
27
    const OPTI_VALID_DATE = '2020-04-05 00:00:00'; // v0.77
28
    protected $db;
29
    protected $pdoConn; // v.34 sous-titre sans maj
30
31
    public function __construct()
32
    {
33
        $pdo = new PDOConnector(
34
            getenv('MYSQL_HOST'), getenv('MYSQL_USER'), getenv('MYSQL_PASSWORD'), getenv('MYSQL_DATABASE')
35
        );
36
        $this->pdoConn = $pdo->connect('utf8', ['port' => getenv('MYSQL_PORT')]);
37
        $this->db = new Mysql($this->pdoConn);
38
    }
39
40
    /**
41
     * @param $datas
42
     *
43
     * @return array|bool
44
     * @throws Exception
45
     */
46
    public function insertPageOuvrages(array $datas)
47
    {
48
        // check if article already in db
49
        $page = $datas[0]['page'];
50
        $count = $this->db->fetchRowMany(
51
            'SELECT id from page_ouvrages WHERE page=:page',
52
            ['page' => $page]
53
        );
54
        if (null !== $count) {
55
            return false;
56
        }
57
58
        // add the citations
59
        return $this->db->insertMany('page_ouvrages', $datas);
60
    }
61
62
    /**
63
     * Get one new row (page, raw) to complete.
64
     * Order by isbn (NULL first)
65
     *
66
     * @return array|null
67
     */
68
    public function getNewRaw(): ?array
69
    {
70
        try {
71
            $row = $this->db->fetchRow(
72
                'SELECT page,raw FROM page_ouvrages 
73
                WHERE raw <> "" AND (opti IS NULL OR opti = "" OR optidate IS NULL OR optidate < :validDate ) AND (edited IS NULL)
74
                ORDER BY priority DESC,id
75
                LIMIT 1',
76
                [
77
                    'validDate' => self::OPTI_VALID_DATE,
78
                ]
79
            );
80
        } catch (Throwable $e) {
81
            echo "SQL : No more queue to process \n";
82
        }
83
84
        return $row ?? null;
85
    }
86
87
    /**
88
     * Update DB with completed data from CompleteProcess.
89
     *
90
     * @param array $finalData
91
     *
92
     * @return bool
93
     */
94
    public function sendCompletedData(array $finalData): bool
95
    {
96
        try {
97
            $result = $this->db->update(
98
                'page_ouvrages',
99
                ['raw' => $finalData['raw']], // condition
100
                $finalData
101
            );
102
        } catch (MysqlException $e) {
103
            dump($e);
104
105
            return false;
106
        }
107
108
        return !empty($result);
109
    }
110
111
    //------------------------------------------------------
112
    //          EDIT QUEUE
113
    //------------------------------------------------------
114
115
    /**
116
     * Get batch of citations(template) for edit process.
117
     *
118
     * @param int|null $limit
119
     *
120
     * @return string|null
121
     * @throws Exception
122
     */
123
    public function getAllRowsToEdit(?int $limit = 100): ?string
124
    {
125
        try {
126
            $pageInfo = $this->pdoConn->query(
127
                '
128
                SELECT A.page FROM page_ouvrages A
129
                WHERE A.notcosmetic=1 AND A.opti IS NOT NULL
130
                AND NOT EXISTS
131
                    (SELECT B.* FROM page_ouvrages B
132
                    WHERE (
133
                        B.edited IS NOT NULL 
134
                        OR B.optidate < "'.self::OPTI_VALID_DATE.'" 
135
                        OR B.optidate IS NULL 
136
                        OR B.opti IS NULL
137
                        OR B.opti="" 
138
                        OR B.skip=1
139
                        OR B.raw=""
140
                        )
141
                    AND A.page = B.page
142
                    )
143
                ORDER BY A.priority DESC,A.optidate,RAND()
144
                LIMIT '.$limit.'
145
                '
146
            );
147
148
            // No page to edit
149
            $rows = $pageInfo->fetchAll();
150
            if (empty($rows)) {
151
                return '[]';
152
            }
153
154
            $page = $rows[0]['page'];
155
156
            // Order by optidate for first version in edit commentary ?
157
            $data = $this->db->fetchRowMany(
158
                'SELECT * FROM page_ouvrages WHERE page=:page ORDER BY optidate DESC',
159
                ['page' => $page]
160
            );
161
            $json = json_encode($data);
162
        } catch (Throwable $e) {
163
            throw new Exception('SQL : No more queue to process');
164
        }
165
166
        return $json;
167
    }
168
169
    public function deleteArticle(string $title): bool
170
    {
171
        try {
172
            $result = $this->db->delete(
173
                'page_ouvrages',
174
                ['page' => $title] // condition
175
            );
176
        } catch (MysqlException $e) {
177
            dump($e);
178
179
            return false;
180
        }
181
182
        return !empty($result);
183
    }
184
185
    public function skipArticle(string $title): bool
186
    {
187
        try {
188
            $result = $this->db->update(
189
                'page_ouvrages',
190
                ['page' => $title], // condition
191
                ['skip' => true]
192
            );
193
        } catch (MysqlException $e) {
194
            dump($e);
195
196
            return false;
197
        }
198
199
        return !empty($result);
200
    }
201
202
    public function setLabel(string $title, ?int $val = 0): bool
203
    {
204
        try {
205
            $result = $this->db->update(
206
                'page_ouvrages',
207
                ['page' => $title], // condition
208
                ['label' => $val]
209
            );
210
        } catch (MysqlException $e) {
211
            dump($e);
212
213
            return false;
214
        }
215
216
        return !empty($result);
217
    }
218
219
    public function skipRow(int $id): bool
220
    {
221
        try {
222
            $result = $this->db->update(
223
                'page_ouvrages',
224
                ['id' => $id], // condition
225
                ['skip' => true]
226
            );
227
        } catch (MysqlException $e) {
228
            dump($e);
229
230
            return false;
231
        }
232
233
        return !empty($result);
234
    }
235
236
    /**
237
     * Update DB after wiki edition.
238
     *
239
     * @param array $data
240
     *
241
     * @return bool
242
     */
243
    public function sendEditedData(array $data): bool
244
    {
245
        try {
246
            $result = $this->db->update(
247
                'page_ouvrages',
248
                ['id' => $data['id']], // condition
249
                ['edited' => date('Y-m-d H:i:s')]
250
            );
251
        } catch (MysqlException $e) {
252
            dump($e);
253
254
            return false;
255
        }
256
257
        return !empty($result);
258
    }
259
260
    /**
261
     * Get a row to monitor edits.
262
     */
263
    public function getMonitor(): ?array
264
    {
265
        $data = null;
266
        // 2 hours ago
267
        $beforeTime = (new DateTime())->sub(new DateInterval('PT3H'));
268
269
        try {
270
            $data = $this->db->fetchRowMany(
271
                'SELECT id,page,raw,opti,optidate,edited,verify,skip FROM page_ouvrages WHERE page = (
272
                    SELECT page FROM page_ouvrages
273
                    WHERE edited IS NOT NULL 
274
                    and edited > :afterDate and edited < :beforeDate
275
                    and (verify is null or verify < :nextVerifyDate )
276
             		ORDER BY verify,edited
277
                    LIMIT 1)',
278
                [
279
                    'afterDate' => '2019-11-26 06:00:00',
280
                    'beforeDate' => $beforeTime->format('Y-m-d H:i:s'),
281
                    'nextVerifyDate' => (new DateTime())->sub(new DateInterval('P2D'))->format('Y-m-d H:i:s'),
282
                ]
283
            );
284
        } catch (Throwable $e) {
285
            echo "SQL : No more queue to process \n";
286
        }
287
288
        return $data;
289
    }
290
291
    public function updateMonitor(array $data): bool
292
    {
293
        if (empty($data['page'])) {
294
            throw new Exception('pas de page');
295
        }
296
297
        try {
298
            $result = $this->db->update(
299
                'page_ouvrages',
300
                ['page' => $data['page']], // condition
301
                $data
302
            );
303
        } catch (MysqlException $e) {
304
            dump($e);
305
306
            return false;
307
        }
308
309
        return !empty($result);
310
    }
311
}
312