Completed
Push — 1.10 ( 3bcec0...1a0641 )
by
unknown
08:47
created

InitialSyncProcessor::updateSyncedTo()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 1
eloc 7
nc 1
nop 3
1
<?php
2
3
namespace OroCRM\Bundle\MagentoBundle\Provider;
4
5
use Oro\Bundle\IntegrationBundle\Entity\Channel as Integration;
6
use Oro\Bundle\IntegrationBundle\Entity\Status;
7
use Oro\Bundle\IntegrationBundle\Provider\SyncProcessor;
8
9
class InitialSyncProcessor extends AbstractInitialProcessor
10
{
11
    const INITIAL_CONNECTOR_SUFFIX = '_initial';
12
13
    /** @var SyncProcessor[] */
14
    protected $postProcessors = [];
15
16
    /** @var bool */
17
    protected $dictionaryDataLoaded = false;
18
19
    /**
20
     * @param string $connectorType
21
     * @param SyncProcessor $processor
22
     * @return InitialSyncProcessor
23
     */
24
    public function addPostProcessor($connectorType, SyncProcessor $processor)
25
    {
26
        $this->postProcessors[$connectorType] = $processor;
27
28
        return $this;
29
    }
30
31
    /**
32
     * {@inheritdoc}
33
     */
34
    protected function processDictionaryConnectors(Integration $integration)
35
    {
36
        if (!$this->dictionaryDataLoaded) {
37
            parent::processDictionaryConnectors($integration);
38
39
            $this->dictionaryDataLoaded = true;
40
        }
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46
    protected function processConnectors(Integration $integration, array $parameters = [], callable $callback = null)
47
    {
48
        if (empty($parameters['skip-dictionary'])) {
49
            $this->processDictionaryConnectors($integration);
50
        }
51
52
        // Set start date for initial connectors
53
        $startSyncDate = $integration->getTransport()->getSettingsBag()->get(self::START_SYNC_DATE);
54
        $parameters[self::START_SYNC_DATE] = $startSyncDate;
55
56
        // Pass interval to connectors for further filters creation
57
        $interval = $this->getSyncInterval();
58
        $parameters[self::INTERVAL] = $interval;
59
60
        // Collect initial connectors
61
        $postProcessConnectorTypes = array_keys($this->postProcessors);
62
        $connectors = $this->getTypesOfConnectorsToProcess($integration, $this->getConnectorsFilterFunction($callback));
63
        $postProcessConnectors = array_intersect($connectors, $postProcessConnectorTypes);
64
        $connectors = array_diff($connectors, $postProcessConnectorTypes);
65
66
        /** @var \DateTime[] $connectorsSyncedTo */
67
        $connectorsSyncedTo = [];
68
        foreach ($connectors as $connector) {
69
            $connectorsSyncedTo[$connector] = $this->getConnectorSyncedTo($integration, $connector);
70
        }
71
72
        // Process all initial connectors by date interval while there are connectors to process
73
        $isSuccess = true;
74
        do {
75
            $syncedConnectors = 0;
76
            foreach ($connectors as $connector) {
77
                if ($connectorsSyncedTo[$connector] > $startSyncDate) {
78
                    $syncedConnectors++;
79
80
                    $this->logger->info(
81
                        sprintf(
82
                            'Syncing connector %s starting %s interval %s',
83
                            $connector,
84
                            $connectorsSyncedTo[$connector]->format('Y-m-d H:i:s'),
85
                            $interval->format('%d days')
86
                        )
87
                    );
88
89
                    try {
90
                        // Pass synced to for further filters creation
91
                        $parameters = array_merge(
92
                            $parameters,
93
                            [self::SYNCED_TO => clone $connectorsSyncedTo[$connector]]
94
                        );
95
96
                        $realConnector = $this->getRealConnector($integration, $connector);
97
                        $status = $this->processIntegrationConnector(
98
                            $integration,
99
                            $realConnector,
100
                            $parameters
101
                        );
102
                        // Move sync date into past by interval value
103
                        $connectorsSyncedTo[$connector]->sub($interval);
104
105
                        $isSuccess = $isSuccess && $this->isIntegrationConnectorProcessSuccess($status);
106
107
                        if ($isSuccess) {
108
                            // Save synced to date for connector
109
                            $syncedTo = $connectorsSyncedTo[$connector];
110
                            if ($syncedTo < $startSyncDate) {
111
                                $syncedTo = $startSyncDate;
112
                            }
113
                            $this->updateSyncedTo($integration, $connector, $syncedTo);
114
                        } else {
115
                            break 2;
116
                        }
117
                    } catch (\Exception $e) {
118
                        $isSuccess = false;
119
120
                        $this->logger->critical($e->getMessage());
121
                        break 2;
122
                    }
123
                }
124
            }
125
        } while ($syncedConnectors > 0);
126
127
        if ($isSuccess && $postProcessConnectors) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $postProcessConnectors of type string[] is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
128
            $isSuccess = $this->executePostProcessConnectors(
129
                $integration,
130
                $parameters,
131
                $postProcessConnectors,
132
                $startSyncDate
133
            );
134
        }
135
136
        return $isSuccess;
137
    }
138
139
    /**
140
     * @param callable|null $callback
141
     * @return \Closure
142
     */
143
    protected function getConnectorsFilterFunction(callable $callback = null)
144
    {
145
        return function ($connector) use ($callback) {
146
            if (is_callable($callback) && !call_user_func($callback, $connector)) {
147
                return false;
148
            }
149
150
            return strpos($connector, self::INITIAL_CONNECTOR_SUFFIX) !== false;
151
        };
152
    }
153
154
    /**
155
     * @param Integration $integration
156
     * @param array $parameters
157
     * @param array $postProcessConnectors
158
     * @param \DateTime $startSyncDate
159
     * @return bool
160
     */
161
    protected function executePostProcessConnectors(
162
        Integration $integration,
163
        array $parameters,
164
        array $postProcessConnectors,
165
        \DateTime $startSyncDate
166
    ) {
167
        $isSuccess = true;
168
        foreach ($postProcessConnectors as $connectorType) {
169
            // Do not sync already synced connectors
170
            if ($this->getLastStatusForConnector($integration, $connectorType, Status::STATUS_COMPLETED)) {
171
                continue;
172
            }
173
174
            $processor = $this->postProcessors[$connectorType];
175
            $isSuccess = $isSuccess && $processor->process($integration, $connectorType, $parameters);
176
            if ($isSuccess) {
177
                $this->updateSyncedTo($integration, $connectorType, $startSyncDate);
178
            }
179
        }
180
181
        return $isSuccess;
182
    }
183
}
184