Completed
Push — master ( fc1bf9...6b91a0 )
by Keith
06:58
created

DoctrineProvider::getById()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
ccs 0
cts 4
cp 0
cc 1
eloc 2
nc 1
nop 1
crap 2
1
<?php
2
3
/**
4
 * Copyright Talisman Innovations Ltd. (2016). All rights reserved
5
 *
6
 * Licensed under the Apache License, Version 2.0 (the "License");
7
 * you may not use this file except in compliance with the License.
8
 * You may obtain a copy of the License at
9
 *
10
 *     http://www.apache.org/licenses/LICENSE-2.0
11
 *
12
 * Unless required by applicable law or agreed to in writing, software
13
 * distributed under the License is distributed on an "AS IS" BASIS,
14
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15
 * See the License for the specific language governing permissions and
16
 * limitations under the License.
17
 *
18
 * @package     qpush-bundle
19
 * @copyright   Talisman Innovations Ltd. (2016)
20
 * @license     Apache License, Version 2.0
21
 */
22
23
namespace Uecode\Bundle\QPushBundle\Provider;
24
25
use Doctrine\Common\Cache\Cache;
26
use Monolog\Logger;
27
use Uecode\Bundle\QPushBundle\Message\Message;
28
use Uecode\Bundle\QPushBundle\Entity\DoctrineMessage;
29
30
class DoctrineProvider extends AbstractProvider
31
{
32
33
    const DEFAULT_PERIOD = 300;
34
35
    protected $em;
36
    protected $repository;
37
    protected static $entityName = 'Uecode\Bundle\QPushBundle\Entity\DoctrineMessage';
38
39
    /**
40
     * Constructor for Provider classes
41
     *
42
     * @param string $name    Name of the Queue the provider is for
43
     * @param array  $options An array of configuration options for the Queue
44
     * @param mixed  $client  A Queue Client for the provider
45
     * @param Cache  $cache   An instance of Doctrine\Common\Cache\Cache
46
     * @param Logger $logger  An instance of Symfony\Bridge\Mongolog\Logger
47
     */
48
    public function __construct($name, array $options, $client, Cache $cache, Logger $logger)
49
    {
50
        $this->name = $name;
51
        $this->options = $options;
52
        $this->cache = $cache;
53
        $this->logger = $logger;
54
        $this->em = $client;
55
        $this->repository = $this->em->getRepository(self::$entityName);
56
    }
57
58
    /**
59
     * Returns the name of the Queue that this Provider is for
60
     *
61
     * @return string
62
     */
63
    public function getName()
64
    {
65
        return $this->name;
66
    }
67
68
    /**
69
     * Returns the Queue Provider name
70
     *
71
     * @return string
72
     */
73
    public function getProvider()
74
    {
75
        return 'Doctrine';
76
    }
77
78
    /**
79
     * Returns the Provider's Configuration Options
80
     *
81
     * @return array
82
     */
83
    public function getOptions()
84
    {
85
        return $this->options;
86
    }
87
88
    /**
89
     * Returns the Cache service
90
     *
91
     * @return Cache
92
     */
93
    public function getCache()
94
    {
95
        return $this->cache;
96
    }
97
98
    /**
99
     * Returns the Logger service
100
     *
101
     * @return Logger
102
     */
103
    public function getLogger()
104
    {
105
        return $this->logger;
106
    }
107
108
    /**
109
     * Get repository
110
     * 
111
     * @return array
112
     */
113
    public function getRepository()
114
    {
115
        if (!$this->repository) {
116
            return;
117
        }
118
119
        return $this->repository;
120
    }
121
122
    /**
123
     * Creates the Queue
124
     * Checks to see if the underlying table has been created or not
125
     * 
126
     * @return bool
127
     */
128
    public function create()
129
    {
130
        $sm = $this->em->getConnection()->getSchemaManager();
131
        $table = $this->em->getClassMetadata(self::$entityName)->getTableName();
132
133
        return $sm->tablesExist(array($table));
134
    }
135
136
    /**
137
     * Publishes a message to the Queue
138
     *
139
     * This method should return a string MessageId or Response
140
     *
141
     * @param array $message The message to queue
142
     * @param array $options An array of options that override the queue defaults
143
     *
144
     * @return string
145
     */
146
    public function publish(array $message, array $options = [])
147
    {
148
        if (!$this->em) {
149
            return '';
150
        }
151
152
        $doctrineMessage = new DoctrineMessage();
153
        $doctrineMessage->setQueue($this->name)
154
                ->setDelivered(false)
155
                ->setMessage($message)
156
                ->setLength(strlen(serialize($message)));
157
158
        $this->em->persist($doctrineMessage);
159
        $this->em->flush();
160
161
        return (string) $doctrineMessage->getId();
162
    }
163
164
    /**
165
     * Polls the Queue for Messages
166
     *
167
     * Depending on the Provider, this method may keep the connection open for
168
     * a configurable amount of time, to allow for long polling.  In most cases,
169
     * this method is not meant to be used to long poll indefinitely, but should
170
     * return in reasonable amount of time
171
     *
172
     * @param  array $options An array of options that override the queue defaults
173
     *
174
     * @return array
175
     */
176
    public function receive(array $options = [])
177
    {
178
        if (!$this->em) {
179
            return [];
180
        }
181
182
        $doctrineMessages = $this->repository->findBy(
183
                array('delivered' => false, 'queue' => $this->name), array('id' => 'ASC')
184
        );
185
186
        $messages = [];
187
        foreach ($doctrineMessages as $doctrineMessage) {
188
            $messages[] = new Message($doctrineMessage->getId(), $doctrineMessage->getMessage(), []);
189
            $doctrineMessage->setDelivered(true);
190
        }
191
        $this->em->flush();
192
193
        return $messages;
194
    }
195
196
    /**
197
     * Deletes the Queue Message
198
     *
199
     * @param mixed $id A message identifier or resource
200
     */
201
    public function delete($id)
202
    {
203
        $doctrineMessage = $this->repository->findById($id);
204
        $doctrineMessage->setDelivered(true);
205
        $this->em->flush();
206
207
        return true;
208
    }
209
210
    /**
211
     * Destroys a Queue and clears any Queue related Cache
212
     *
213
     * @return bool
214
     */
215
    public function destroy()
216
    {
217
        $qb = $this->repository->createQueryBuilder('dm');
218
        $qb->delete();
219
        $qb->where('dm.queue = :queue');
220
        $qb->setParameter('queue', $this->name);
221
        $qb->getQuery()->execute();
222
223
        return true;
224
    }
225
226
    /**
227
     * Returns a specific message
228
     * 
229
     * @param integer $id
230
     * 
231
     * @return Message
232
     */
233
    public function getById($id)
234
    {
235
        return $this->repository->find($id);
236
    }
237
238
    /**
239
     * Returns a query of the message queue
240
     * 
241
     * @param array $data ['field'=>'id', 'search'=>'text', 'to'=>date, from=>date]
242
     * @return Query
243
     * 
244
     */
245
    public function findBy($data)
246
    {
247
        $qb = $this->repository->createQueryBuilder('p');
248
        $qb->select('p');
249
        $qb->where('p.queue = :queue');
250
        $qb->setParameter('queue', $this->name);
251
252
        $field = (isset($data['field'])) ? $data['field'] : 'message';
253
254
        if (isset($data['search']) && $data['search'] !== null) {
255
            $qb->andWhere('p.' . $field . ' LIKE :contains');
256
            $qb->setParameter('contains', '%' . $data['search'] . '%');
257
        }
258
259
        if (isset($data['from']) && $data['from'] !== null && isset($data['to']) && $data['to'] !== null) {
260
            $qb->andWhere('p.created BETWEEN :from AND :to');
261
            $qb->setParameter('from', $data['from']);
262
            $qb->setParameter('to', $data['to']);
263
        } 
264
265
        return $qb->getQuery();
266
    }
267
268
    /*
269
     * Returns an array of times and messgae counts
270
     * @praram $data ['from' => date, 'to' => date, 'period' => seconds
271
     * @return ['time', 'count']
272
     */
0 ignored issues
show
Documentation introduced by
The doc-type 'time',">['time', could not be parsed: Unknown type name "[" at position 0. [(view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
273
274
    public function counts($data=null)
275
    {
276
        if (isset($data['period']) && $data['period'] !== null) {
277
            $period = $data['period'];
278
        } else {
279
            $period = self::DEFAULT_PERIOD;
280
        }
281
        $sql = 'SELECT from_unixtime(floor(unix_timestamp(created)/'
282
                . $period . ') * ' . $period . ') as time, 
283
            count(*) as count 
284
            FROM uecode_qpush_message
285
            where queue = "' . $this->name . '"';
286 View Code Duplication
        if (isset($data['from']) && $data['from'] !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
287
            $sql = $sql . ' and created >= "' . $data['from'] . '"';
288
        }
289 View Code Duplication
        if (isset($data['to']) && $data['to'] !== null) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
290
            $sql = $sql . ' and created <= "' . $data['to'] . '"';
291
        }
292
        $sql = $sql . ' group by floor(unix_timestamp(created)/' . $period . ')';
293
        $sql = $sql . ' order by floor(unix_timestamp(created)/' . $period . ') ASC';
294
        $statement = $this->em->getConnection()->prepare($sql);
295
        $statement->execute();
296
        $results = $statement->fetchAll();
297
        
298
        return $results;
299
    }
300
301
}
302