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

Images::execute()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 29
Code Lines 18

Duplication

Lines 0
Ratio 0 %

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 18
c 1
b 0
f 0
nc 7
nop 0
dl 0
loc 29
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
     * @var LoggerInterface
23
     */
24
    private $logger;
25
    /**
26
     * @var StockbaseClientFactory
27
     */
28
    private $stockbaseClientFactory;
29
    /**
30
     * @var ObjectManagerInterface
31
     */
32
    private $objectManager;
33
    /**
34
     * @var StockbaseConfiguration
35
     */
36
    private $config;
37
    /**
38
     * @var ProductCollection
39
     */
40
    private $productCollection;
41
    /**
42
     * @var ProductModel
43
     */
44
    private $product;
45
    /**
46
     * @var UrlHelper
47
     */
48
    private $urlHelper;
49
    /**
50
     * Directory List
51
     *
52
     * @var DirectoryList
53
     */
54
    private $directoryList;
55
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
        // apply filters and paginate by 100:
139
        $collection = $this->productCollection->create()
140
            ->addAttributeToSelect($attribute)
141
            ->addAttributeToFilter($attribute, array('notnull' => true, 'neq' => '')) // not null and not empty.
142
            ->setPageSize(100);
143
        // iterate over the pages:
144
        $eans = array();
145
        $currentPage = 0;
146
        $lastPage = $collection->getLastPageNumber();
147
        while ($currentPage < $lastPage) {
148
            // load the data of this page in a single query:
149
            $collection->setCurPage(++$currentPage);
150
            $collection->load();
151
            // iterate over the products:
152
            foreach ($collection as $product) {
153
                if ($ean = $product->{$attribute}) {
154
                    // add the ean if this product has one:
155
                    $eans[] = $ean;
156
                }
157
            }
158
        }
159
        $this->logger->info('Found EANs: '.count($eans));
160
        return $eans;
161
    }
162
163
    /**
164
     * Saves images array from stockbase for given $ean
165
     *
166
     * @param array $images
167
     *
168
     * @return bool
169
     */
170
    private function saveImageForProduct($images)
171
    {
172
        $this->logger->info('Save images process: ');
173
        // get product model:
174
        $productModel = $this->product;
175
        // get ean attribute:
176
        $eanField = $this->config->getEanFieldName();
177
        // get client:
178
        $client = $this->stockbaseClientFactory->create();
179
        // loop images:
180
        foreach ($images as $image) {
181
            $this->logger->info($image->{'Url'});
182
            // load product by ean:
183
            $product = $productModel->loadByAttribute($eanField, $image->EAN);
184
            // continue looping if we do not have product:
185
            if (!$product) {
186
                continue;
187
            }
188
            // get image from stockbase:
189
            $protectedImage = $client->getImageFile($image->{'Url'});
190
            // create temporal folder if it is not exists:
191
            $tmpDir = $this->getMediaDirTmpDir();
192
            $this->file->checkAndCreateFolder($tmpDir);
193
            // get new file path:
194
            $newFileName = $tmpDir . baseName($image->{'Url'});
195
            // read file from URL and copy it to the new destination:
196
            $result = $this->file->read($protectedImage, $newFileName);
197
            if ($result) {
198
                if ($product->getMediaGallery() == null) {
199
                    $product->setMediaGallery(array('images' => array(), 'values' => array()));
200
                }
201
                // add saved file to the $product gallery:
202
                $product->addImageToMediaGallery(
203
                    $newFileName,
204
                    array('image', 'small_image', 'thumbnail'),
205
                    false,
206
                    false
207
                );
208
                // save product:
209
                $product->{'save'}();
210
                $this->logger->info('Saved.');
211
            }
212
        }
213
        return true;
214
    }
215
216
    /**
217
     * Media directory name for the temporary file storage
218
     * pub/media/tmp
219
     *
220
     * @return string
221
     */
222
    private function getMediaDirTmpDir()
223
    {
224
        return $this->directoryList->getPath(DirectoryList::MEDIA) . DIRECTORY_SEPARATOR . 'tmp';
225
    }
226
227
    /**
228
     * @return mixed
229
     */
230
    private function getImagesEans()
231
    {
232
        return $this->config->getImagesEans();
233
    }
234
235
    /**
236
     * @param $eans
237
     */
238
    private function saveImagesEans($eans)
239
    {
240
        $this->config->saveImagesEans($eans);
241
    }
242
243
}
244