Completed
Pull Request — master (#1)
by
unknown
12:05
created

Images   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 250
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 4

Importance

Changes 6
Bugs 0 Features 0
Metric Value
c 6
b 0
f 0
dl 0
loc 250
rs 10
wmc 21
lcom 1
cbo 4

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 21 1
C execute() 0 35 8
B getNotProcessedEans() 0 28 2
A getProductEan() 0 12 2
B saveImageForProduct() 0 45 5
A getMediaDirTmpDir() 0 4 1
A getImagesEans() 0 4 1
A saveImagesEans() 0 4 1
1
<?php
2
3
namespace Stockbase\Integration\Cron;
4
5
use Magento\Framework\ObjectManagerInterface;
6
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollection;
7
use Magento\Catalog\Model\Product as ProductModel;
8
use Magento\Framework\Url as UrlHelper;
9
use Magento\Framework\App\Filesystem\DirectoryList;
10
use Magento\Framework\Filesystem\Io\File;
11
use Psr\Log\LoggerInterface;
12
use Stockbase\Integration\StockbaseApi\Client\StockbaseClientFactory;
13
use Stockbase\Integration\Model\Config\StockbaseConfiguration;
14
use Stockbase\Integration\Model\ResourceModel\StockItem as StockItemResource;
15
16
/**
17
 * Stockbase images synchronization cron job.
18
 */
19
class Images
20
{
21
22
    /**
23
     * @var LoggerInterface
24
     */
25
    private $logger;
26
    /**
27
     * @var StockbaseClientFactory
28
     */
29
    private $stockbaseClientFactory;
30
    /**
31
     * @var ObjectManagerInterface
32
     */
33
    private $objectManager;
34
    /**
35
     * @var StockbaseConfiguration
36
     */
37
    private $config;
38
    /**
39
     * @var ProductCollection
40
     */
41
    private $productCollection;
42
    /**
43
     * @var ProductModel
44
     */
45
    private $product;
46
    /**
47
     * @var UrlHelper
48
     */
49
    private $urlHelper;
50
    /**
51
     * Directory List
52
     *
53
     * @var DirectoryList
54
     */
55
    private $directoryList;
56
    /**
57
     * File interface
58
     *
59
     * @var File
60
     */
61
    private $file;
62
    /**
63
     * @var array
64
     */
65
    private $eans = array();
66
    
67
    /**
68
     * Images constructor.
69
     * @param LoggerInterface $logger
70
     * @param ObjectManagerInterface $objectManager
71
     * @param StockbaseClientFactory $stockbaseClientFactory
72
     * @param StockbaseConfiguration $config
73
     * @param ProductCollection $productCollection
74
     * @param ProductModel $product
75
     * @param UrlHelper $urlHelper
76
     * @param DirectoryList $directoryList
77
     * @param File $file
78
     */
79
    public function __construct(
80
        LoggerInterface $logger,
81
        ObjectManagerInterface $objectManager,
82
        StockbaseClientFactory $stockbaseClientFactory,
83
        StockbaseConfiguration $config,
84
        ProductCollection $productCollection,
85
        ProductModel $product,
86
        UrlHelper $urlHelper,
87
        DirectoryList $directoryList,
88
        File $file
89
    ) {
90
        $this->logger = $logger;
91
        $this->stockbaseClientFactory = $stockbaseClientFactory;
92
        $this->objectManager = $objectManager;
93
        $this->config = $config;
94
        $this->productCollection = $productCollection;
95
        $this->product = $product;
96
        $this->urlHelper = $urlHelper;
97
        $this->directoryList = $directoryList;
98
        $this->file = $file;
99
    }
100
101
    /**
102
     * Executes the job.
103
     */
104
    public function execute()
105
    {
106
        // validate configuration:
107
        if (!$this->config->isModuleEnabled() || !$this->config->isImagesSyncEnabled()) {
108
            return;
109
        }
110
        // start process:
111
        $this->logger->info('Synchronizing Stockbase images...');
112
        // get processed eans:
113
        $processedEans = json_decode($this->getImagesEans()) ? : array();
114
        // get all the eans:
115
        $eans = $this->getNotProcessedEans($processedEans);
116
        $this->logger->info('EANs to be processed: '.count($eans));
117
        try {
118
            // if still need to process eans:
119
            if(count($eans) > 0) {
120
                $client = $this->stockbaseClientFactory->create();
121
                $images = $client->getImages($eans);
122
                // validate returned images:
123
                if(is_array($images->{'Items'}) && count($images->{'Items'}) > 0) {
124
                    // download and save the images locally:
125
                    $this->saveImageForProduct($images->{'Items'});
126
                    // update the processed images configuration:
127
                    $processedEans = array_merge($processedEans, $eans);
128
                    $encodedEans = json_encode($processedEans);
129
                    $this->saveImagesEans($encodedEans);
130
                    $this->logger->info('New images synchronized.');
131
                }
132
            }
133
        } catch (Exception $e) {
0 ignored issues
show
Bug introduced by
The class Stockbase\Integration\Cron\Exception does not exist. Did you forget a USE statement, or did you not list all dependencies?

Scrutinizer analyzes your composer.json/composer.lock file if available to determine the classes, and functions that are defined by your dependencies.

It seems like the listed class was neither found in your dependencies, nor was it found in the analyzed files in your repository. If you are using some other form of dependency management, you might want to disable this analysis.

Loading history...
134
            $this->logger->info('Cron runImageImport error: '.$e->getMessage());
135
            return false;
136
        }
137
        $this->logger->info('Stockbase images synchronization complete.');
138
    }
139
140
    /**
141
     * @return array
142
     */
143
    private function getNotProcessedEans($processedEans)
144
    {
145
        // clean eans list:
146
        $this->eans = array();
147
        // start process:
148
        $this->logger->info('Get All EANs process');
149
        // get ean attribute:
150
        $attribute = $this->config->getEanFieldName();
151
        // validate attribute:
152
        if($attribute) {
153
            // create collection and apply filters:
154
            $collection = $this->productCollection->create()
155
                ->addAttributeToSelect($attribute)
156
                ->addAttributeToSelect('stockbase_product')
157
                ->addAttributeToFilter('stockbase_product', array('eq' => '1')) // stockbase product
158
                ->addAttributeToFilter($attribute, array('notnull' => true, 'neq' => '')) // not null and not empty
159
                ->addAttributeToFilter($attribute, array('nin' => $processedEans)) // not processed eans
160
                ;
161
            // walk collection and save eans in the object:
162
            $collection->walk(array($this, 'getProductEan'));
163
            // log eans count:
164
            $this->logger->info('Found EANs: '.count($this->eans));
165
        } else {
166
            // missing ean attribute:
167
            $this->logger->info('Please setup the EAN attribute.');
168
        }
169
        return $this->eans;
170
    }
171
172
    /**
173
     * @param $product
174
     */
175
    public function getProductEan($product)
176
    {
177
        // get ean attribute:
178
        $attribute = $this->config->getEanFieldName();
179
        // get ean:
180
        $ean = $product->getData($attribute);
181
        // if the ean is not empty:
182
        if ($ean) {
183
            // add the ean if this product has one:
184
            $this->eans[] = $ean;
185
        }
186
    }
187
188
    /**
189
     * Saves images array from stockbase for given $ean
190
     *
191
     * @param array $images
192
     *
193
     * @return bool
194
     */
195
    private function saveImageForProduct($images)
196
    {
197
        $this->logger->info('Save images process:');
198
        // get product model:
199
        $productModel = $this->product;
200
        // get ean attribute:
201
        $eanField = $this->config->getEanFieldName();
202
        // loop images:
203
        foreach ($images as $image) {
204
            $this->logger->info('Image URL: '.$image->{'Url'});
205
            // load product by ean:
206
            $product = $productModel->loadByAttribute($eanField, $image->EAN);
207
            // continue looping if we do not have product:
208
            if (!$product) {
209
                continue;
210
            }
211
            // get image from stockbase:
212
            $stockbaseImage = (string)$image->{'Url'};
213
            // create temporal folder if it is not exists:
214
            $tmpDir = $this->getMediaDirTmpDir();
215
            $this->file->checkAndCreateFolder($tmpDir);
216
            // get new file path:
217
            $newFileName = $tmpDir . baseName($image->{'Url'});
218
            // read file from URL and copy it to the new destination:
219
            $result = $this->file->read($stockbaseImage, $newFileName);
220
            if ($result) {
221
                if ($product->getMediaGallery() == null) {
222
                    $product->setMediaGallery(array('images' => array(), 'values' => array()));
223
                }
224
                // add saved file to the $product gallery:
225
                $product->addImageToMediaGallery(
226
                    $newFileName,
227
                    array('image', 'small_image', 'thumbnail'),
228
                    false,
229
                    false
230
                );
231
                // save product:
232
                $product->save();
233
                $this->logger->info('Product saved.');
234
            } else {
235
                $this->logger->info('Can not read the image: '.$stockbaseImage);
236
            }
237
        }
238
        return true;
239
    }
240
241
    /**
242
     * Media directory name for the temporary file storage
243
     * pub/media/tmp
244
     *
245
     * @return string
246
     */
247
    private function getMediaDirTmpDir()
248
    {
249
        return $this->directoryList->getPath(DirectoryList::MEDIA) . DIRECTORY_SEPARATOR . 'tmp';
250
    }
251
252
    /**
253
     * @return mixed
254
     */
255
    private function getImagesEans()
256
    {
257
        return $this->config->getImagesEans();
258
    }
259
260
    /**
261
     * @param $eans
262
     */
263
    private function saveImagesEans($eans)
264
    {
265
        $this->config->saveImagesEans($eans);
266
    }
267
268
}
269