Completed
Push — 1.8 ( 110b8e...31bb9f )
by
unknown
90:40 queued 42:52
created

ChannelRepository::getExistingSyncJobsCount()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 8
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
dl 0
loc 8
rs 9.4286
c 1
b 0
f 0
cc 1
eloc 5
nc 1
nop 2
1
<?php
2
3
namespace Oro\Bundle\IntegrationBundle\Entity\Repository;
4
5
use Doctrine\Common\Collections\Criteria;
6
use Doctrine\ORM\EntityRepository;
7
use Doctrine\ORM\QueryBuilder;
8
9
use JMS\JobQueueBundle\Entity\Job;
10
11
use Oro\Bundle\BatchBundle\ORM\Query\BufferedQueryResultIterator;
12
use Oro\Bundle\IntegrationBundle\Entity\Channel as Integration;
13
use Oro\Bundle\IntegrationBundle\Entity\Status;
14
15
class ChannelRepository extends EntityRepository
16
{
17
    const BUFFER_SIZE = 100;
18
19
    /**
20
     * @info Check if task is running
21
     *
22
     * @param string   $commandName
23
     * @param int|null $integrationId
24
     *
25
     * @return int
26
     */
27
    public function getRunningSyncJobsCount($commandName, $integrationId = null)
28
    {
29
        $qb = $this->getSyncJobsCountQueryBuilder($commandName, $integrationId);
30
        $qb->andWhere('j.state=:stateName');
31
        $qb->setParameter('stateName', Job::STATE_RUNNING);
32
33
        return (int)$qb->getQuery()->getSingleScalarResult();
34
    }
35
36
    /**
37
     * @info Check if task is pending or running
38
     *
39
     * @param string   $commandName
40
     * @param int|null $integrationId
41
     *
42
     * @return int
43
     */
44
    public function getExistingSyncJobsCount($commandName, $integrationId = null)
45
    {
46
        $qb = $this->getSyncJobsCountQueryBuilder($commandName, $integrationId);
47
        $qb->andWhere($qb->expr()->in('j.state', ':states'));
48
        $qb->setParameter('states', [Job::STATE_RUNNING, Job::STATE_PENDING, Job::STATE_NEW]);
49
50
        return (int)$qb->getQuery()->getSingleScalarResult();
51
    }
52
53
    /**
54
     * @param string   $commandName
55
     * @param int|null $integrationId
56
     *
57
     * @return QueryBuilder
58
     */
59
    protected function getSyncJobsCountQueryBuilder($commandName, $integrationId = null)
60
    {
61
        /** @var QueryBuilder $qb */
62
        $qb = $this->getEntityManager()
63
            ->getRepository('JMSJobQueueBundle:Job')
64
            ->createQueryBuilder('j')
65
            ->select('count(j.id)')
66
            ->andWhere('j.command=:commandName')
67
            ->setParameter('commandName', $commandName);
68
69
        if ($integrationId) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $integrationId of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
70
            $qb->andWhere(
71
                $qb->expr()->orX(
72
                    $qb->expr()->like('cast(j.args as text)', ':integrationIdType1'),
73
                    $qb->expr()->like('cast(j.args as text)', ':integrationIdType2'),
74
                    $qb->expr()->andX(
75
                        $qb->expr()->notLike('cast(j.args as text)', ':noIntegrationIdType1'),
76
                        $qb->expr()->notLike('cast(j.args as text)', ':noIntegrationIdType2')
77
                    )
78
                )
79
            )
80
                ->setParameter('integrationIdType1', '%--integration-id=' . $integrationId . '%')
81
                ->setParameter('noIntegrationIdType1', '%--integration-id=%')
82
                ->setParameter('integrationIdType2', '%-i=' . $integrationId . '%')
83
                ->setParameter('noIntegrationIdType2', '%-i=%');
84
        }
85
86
        return $qb;
87
    }
88
89
    /**
90
     * @param string[]|string      $commandName
91
     * @param string[]|string|null $arguments
92
     * @param string[]|string|null $states
93
     *
94
     * @return QueryBuilder
95
     */
96
    protected function getQBSyncJobs($commandName, $arguments = null, $states = null)
97
    {
98
        /** @var QueryBuilder $qb */
99
        $qb = $this->getEntityManager()
100
            ->getRepository('JMSJobQueueBundle:Job')
101
            ->createQueryBuilder('j');
102
103
        if (is_array($commandName)) {
104
            $qb->andWhere('j.command in (:commandName)');
105
        } else {
106
            $qb->andWhere('j.command=:commandName');
107
        }
108
109
        if (!empty($states)) {
110
            if (is_array($states)) {
111
                $qb->andWhere('j.state in (:stateName)');
112
            } else {
113
                $qb->andWhere('j.state=:stateName');
114
            }
115
        }
116
117
        $qb->setParameter('stateName', $states)
118
            ->setParameter('commandName', $commandName);
119
120
        if (!empty($arguments)) {
121
            if (is_array($arguments)) {
122
                $orX = $qb->expr()->orX();
123
                foreach ($arguments as $key => $argument) {
124
                    $orX->add($qb->expr()->like('cast(j.args as text)', ':args_' . $key));
125
                    $qb->setParameter('args_' . $key, '%' . $argument . '%');
126
                }
127
128
                $qb->andWhere($orX);
129
            } else {
130
                $qb->andWhere($qb->expr()->like('cast(j.args as text)', ':args'))
131
                    ->setParameter('args', '%' . $arguments . '%');
132
            }
133
        }
134
135
        return $qb;
136
    }
137
138
    /**
139
     * @param string[]|string      $commandName
140
     * @param string[]|string|null $arguments
141
     * @param string[]|string|null $states
142
     *
143
     * @return QueryBuilder
144
     */
145 View Code Duplication
    protected function getQBSyncJobsCount($commandName, $arguments = null, $states = null)
146
    {
147
        $qb = $this->getQBSyncJobs($commandName, $arguments, $states);
148
        $qb->select('count(j.id)');
149
150
        return $qb;
151
    }
152
153
    /**
154
     * @param string               $commandName
155
     * @param string[]|string|null $arguments
156
     * @param string[]|string|null $states
157
     *
158
     * @return int
159
     */
160 View Code Duplication
    public function getSyncJobsCount($commandName, $states = null, $arguments = null)
161
    {
162
        /** @var QueryBuilder $qb */
163
        $qb = $this->getQBSyncJobsCount($commandName, $arguments, $states);
164
165
        return (int)$qb->getQuery()->getSingleScalarResult();
166
    }
167
168
    /**
169
     * Returns latest status for integration's connector and code if it exists.
170
     *
171
     * @param Integration $integration
172
     * @param string      $connector
173
     * @param int|null    $code
174
     *
175
     * @return Status|null
176
     */
177
    public function getLastStatusForConnector(Integration $integration, $connector, $code = null)
178
    {
179
        $queryBuilder = $this->getConnectorStatusesQueryBuilder($integration, $connector, $code);
180
        $queryBuilder
181
            ->setFirstResult(0)
182
            ->setMaxResults(1);
183
184
        return $queryBuilder->getQuery()->getOneOrNullResult();
185
    }
186
187
    /**
188
     * @param Integration $integration
189
     * @param string      $connector
190
     * @param int|null    $code
191
     *
192
     * @return Status[]|\Iterator
193
     */
194
    public function getConnectorStatuses(Integration $integration, $connector, $code = null)
195
    {
196
        $iterator = new BufferedQueryResultIterator(
197
            $this->getConnectorStatusesQueryBuilder($integration, $connector, $code)
198
        );
199
        $iterator->setBufferSize(self::BUFFER_SIZE);
200
201
        return $iterator;
202
    }
203
204
    /**
205
     * @param Integration $integration
206
     * @param string      $connector
207
     * @param int|null    $code
208
     *
209
     * @return QueryBuilder
210
     */
211
    public function getConnectorStatusesQueryBuilder(Integration $integration, $connector, $code = null)
212
    {
213
        $queryBuilder = $this->getEntityManager()->createQueryBuilder()
214
            ->select('status')
215
            ->from('OroIntegrationBundle:Status', 'status')
216
            ->where('status.channel = :integration')
217
            ->andWhere('status.connector = :connector')
218
            ->setParameters(['integration' => $integration, 'connector' => (string)$connector])
219
            ->orderBy('status.date', Criteria::DESC);
220
221
        if ($code) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $code of type integer|null is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
222
            $queryBuilder->andWhere('status.code = :code')
223
                ->setParameter('code', (string)$code);
224
        };
225
226
        return $queryBuilder;
227
    }
228
229
    /**
230
     * Returns channels that have configured transports
231
     * Assume that they are ready for sync
232
     *
233
     * @param null|string $type
234
     * @param boolean     $isReadOnly
235
     *
236
     * @return array
237
     */
238
    public function getConfiguredChannelsForSync($type = null, $isReadOnly = false)
239
    {
240
        $qb = $this->createQueryBuilder('c')
241
            ->where('c.transport is NOT NULL')
242
            ->andWhere('c.enabled = :isEnabled')
243
            ->setParameter('isEnabled', true);
244
245
        if (null !== $type) {
246
            $qb->andWhere('c.type = :type')
247
                ->setParameter('type', $type);
248
        }
249
250
        $integrations = $qb->getQuery()->getResult();
251
252
        if ($isReadOnly) {
253
            $unitOfWork = $this->getEntityManager()->getUnitOfWork();
254
255
            foreach ($integrations as $integration) {
256
                $unitOfWork->markReadOnly($integration);
257
            }
258
        }
259
260
        return $integrations;
261
    }
262
263
    /**
264
     * Load instance once and precache it in property
265
     *
266
     * @param int $id
267
     *
268
     * @return Integration|bool
269
     */
270
    public function getOrLoadById($id)
271
    {
272
        $unitOfWork  = $this->getEntityManager()->getUnitOfWork();
273
        $integration = $this->getEntityManager()->find('OroIntegrationBundle:Channel', $id);
274
        if ($integration === null) {
275
            return false;
276
        }
277
278
        $unitOfWork->markReadOnly($integration);
279
280
        return $integration;
281
    }
282
283
    /**
284
     * Adds status to integration, manual persist of newly created statuses and do flush.
285
     *
286
     * @deprecated 1.9.0:1.11.0 Use $this->addStatusAndFlush() instead
287
     *
288
     * @param Integration $integration
289
     * @param Status      $status
290
     */
291
    public function addStatus(Integration $integration, Status $status)
292
    {
293
        $this->addStatusAndFlush($integration, $status);
294
    }
295
296
    /**
297
     * Adds status to integration, manual persist of newly created statuses and do flush.
298
     *
299
     * @param Integration $integration
300
     * @param Status      $status
301
     */
302
    public function addStatusAndFlush(Integration $integration, Status $status)
303
    {
304
        if ($this->getEntityManager()->isOpen()) {
305
            $integration = $this->getOrLoadById($integration->getId());
306
307
            $this->getEntityManager()->persist($status);
308
            $integration->addStatus($status);
309
310
            $this->getEntityManager()->flush();
311
        }
312
    }
313
}
314