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

Images::saveImageForProduct()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 45
Code Lines 26

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 26
c 1
b 0
f 0
nc 5
nop 1
dl 0
loc 45
rs 8.439
1
<?php
2
3
namespace Stockbase\Integration\Cron;
4
5
use Magento\Framework\ObjectManagerInterface;
6
use Psr\Log\LoggerInterface;
7
use Stockbase\Integration\StockbaseApi\Client\StockbaseClientFactory;
8
use Stockbase\Integration\Model\Config\StockbaseConfiguration;
9
use Stockbase\Integration\Model\ResourceModel\StockItem as StockItemResource;
10
use Magento\Catalog\Model\ResourceModel\Product\CollectionFactory as ProductCollection;
11
use Magento\Catalog\Model\Product as ProductModel;
12
use Magento\Framework\Url as UrlHelper;
13
use Magento\Framework\App\Filesystem\DirectoryList;
14
use Magento\Framework\Filesystem\Io\File;
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
    /**
64
     * Images constructor.
65
     * @param LoggerInterface $logger
66
     * @param ObjectManagerInterface $objectManager
67
     * @param StockbaseClientFactory $stockbaseClientFactory
68
     * @param StockbaseConfiguration $config
69
     * @param ProductCollection $productCollection
70
     * @param ProductModel $product
71
     * @param UrlHelper $urlHelper
72
     * @param DirectoryList $directoryList
73
     * @param File $file
74
     */
75
    public function __construct(
76
        LoggerInterface $logger,
77
        ObjectManagerInterface $objectManager,
78
        StockbaseClientFactory $stockbaseClientFactory,
79
        StockbaseConfiguration $config,
80
        ProductCollection $productCollection,
81
        ProductModel $product,
82
        UrlHelper $urlHelper,
83
        DirectoryList $directoryList,
84
        File $file
85
    ) {
86
        $this->logger = $logger;
87
        $this->stockbaseClientFactory = $stockbaseClientFactory;
88
        $this->objectManager = $objectManager;
89
        $this->config = $config;
90
        $this->productCollection = $productCollection;
91
        $this->product = $product;
92
        $this->urlHelper = $urlHelper;
93
        $this->directoryList = $directoryList;
94
        $this->file = $file;
95
    }
96
97
    /**
98
     * Executes the job.
99
     */
100
    public function execute()
101
    {
102
        // validate configuration:
103
        if (!$this->config->isModuleEnabled() || !$this->config->isImagesSyncEnabled()) {
104
            return;
105
        }
106
        // start process:
107
        $this->logger->info('Synchronizing Stockbase images...');
108
        // get all the eans:
109
        $allEans = $this->getAllEans();
110
        // get processed eans:
111
        $processedEans = json_decode($this->getImagesEans()) ?: array();
112
        // process 100 unprocessed eans at a time:
113
        $eans = array_slice(array_diff($allEans, $processedEans), 0, 100);
114
        try {
115
            $client = $this->stockbaseClientFactory->create();
116
            $images = $client->getImages($eans);
117
        } 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...
118
            $this->logger->info('Cron runImageImport error: '.$e->getMessage());
119
            return false;
120
        }
121
        // download and save the images locally:
122
        $this->saveImageForProduct($images);
0 ignored issues
show
Documentation introduced by
$images is of type object, but the function expects a array.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
123
        // update the processed images configuration:
124
        $processedEans = array_merge($processedEans, $eans);
125
        $encodedEans = json_encode($processedEans);
126
        $this->saveImagesEans($encodedEans);
127
        $this->logger->info('Stockbase images synchronization complete.');
128
    }
129
130
    /**
131
     * @return array
132
     */
133
    private function getAllEans()
134
    {
135
        $this->logger->info('Get All EANs process');
136
        // get ean attribute:
137
        $attribute = $this->config->getEanFieldName();
138
        if($attribute) {
139
            // apply filters and paginate by 100:
140
            $collection = $this->productCollection->create()
141
                ->addAttributeToSelect($attribute)
142
                ->addAttributeToFilter($attribute, array('notnull' => true, 'neq' => '')) // not null and not empty.
143
                ->setPageSize(100);
144
            // iterate over the pages:
145
            $eans = array();
146
            $currentPage = 0;
147
            $lastPage = $collection->getLastPageNumber();
148
            while ($currentPage < $lastPage) {
149
                // load the data of this page in a single query:
150
                $collection->setCurPage(++$currentPage);
151
                $collection->load();
152
                // iterate over the products:
153
                foreach ($collection as $product) {
154
                    $ean = $product->getData($attribute);
155
                    $this->logger->info('Product EAN: '.$ean);
156
                    if ($ean) {
157
                        // add the ean if this product has one:
158
                        $eans[] = $ean;
159
                    }
160
                }
161
            }
162
            $this->logger->info('Found EANs: '.count($eans));
163
            return $eans;
164
        } else {
165
            $this->logger->info('Please setup the EAN attribute.');
166
        }
167
    }
168
169
    /**
170
     * Saves images array from stockbase for given $ean
171
     *
172
     * @param array $images
173
     *
174
     * @return bool
175
     */
176
    private function saveImageForProduct($images)
177
    {
178
        $this->logger->info('Save images process: ');
179
        // get product model:
180
        $productModel = $this->product;
181
        // get ean attribute:
182
        $eanField = $this->config->getEanFieldName();
183
        // get client:
184
        $client = $this->stockbaseClientFactory->create();
185
        // loop images:
186
        foreach ($images as $image) {
187
            $this->logger->info($image->{'Url'});
188
            // load product by ean:
189
            $product = $productModel->loadByAttribute($eanField, $image->EAN);
190
            // continue looping if we do not have product:
191
            if (!$product) {
192
                continue;
193
            }
194
            // get image from stockbase:
195
            $protectedImage = $client->getImageFile($image->{'Url'});
196
            // create temporal folder if it is not exists:
197
            $tmpDir = $this->getMediaDirTmpDir();
198
            $this->file->checkAndCreateFolder($tmpDir);
199
            // get new file path:
200
            $newFileName = $tmpDir . baseName($image->{'Url'});
201
            // read file from URL and copy it to the new destination:
202
            $result = $this->file->read($protectedImage, $newFileName);
203
            if ($result) {
204
                if ($product->getMediaGallery() == null) {
205
                    $product->setMediaGallery(array('images' => array(), 'values' => array()));
206
                }
207
                // add saved file to the $product gallery:
208
                $product->addImageToMediaGallery(
209
                    $newFileName,
210
                    array('image', 'small_image', 'thumbnail'),
211
                    false,
212
                    false
213
                );
214
                // save product:
215
                $product->{'save'}();
216
                $this->logger->info('Saved.');
217
            }
218
        }
219
        return true;
220
    }
221
222
    /**
223
     * Media directory name for the temporary file storage
224
     * pub/media/tmp
225
     *
226
     * @return string
227
     */
228
    private function getMediaDirTmpDir()
229
    {
230
        return $this->directoryList->getPath(DirectoryList::MEDIA) . DIRECTORY_SEPARATOR . 'tmp';
231
    }
232
233
    /**
234
     * @return mixed
235
     */
236
    private function getImagesEans()
237
    {
238
        return $this->config->getImagesEans();
239
    }
240
241
    /**
242
     * @param $eans
243
     */
244
    private function saveImagesEans($eans)
245
    {
246
        $this->config->saveImagesEans($eans);
247
    }
248
249
}
250