Passed
Pull Request — master (#8)
by Maciej
03:39
created

VarnishPurger::purgeAll()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11

Duplication

Lines 11
Ratio 100 %

Importance

Changes 0
Metric Value
dl 11
loc 11
c 0
b 0
f 0
rs 9.9
cc 1
nc 1
nop 0
1
<?php
2
declare(strict_types=1);
3
4
/**
5
 * File:VarnishPurger.php
6
 *
7
 * @author Maciej Sławik <[email protected]>
8
 * @copyright Copyright (C) 2019 Lizard Media (http://lizardmedia.pl)
9
 */
10
11
namespace LizardMedia\VarnishWarmer\Model;
12
13
use LizardMedia\VarnishWarmer\Api\Config\PurgingConfigProviderInterface;
14
use LizardMedia\VarnishWarmer\Api\LockHandler\LockInterface;
15
use LizardMedia\VarnishWarmer\Api\QueueHandler\VarnishUrlPurgerInterface;
16
use LizardMedia\VarnishWarmer\Api\QueueHandler\VarnishUrlRegeneratorInterface;
17
use LizardMedia\VarnishWarmer\Api\UrlProvider\CategoryUrlProviderInterface;
18
use LizardMedia\VarnishWarmer\Api\UrlProvider\ProductUrlProviderInterface;
19
use LizardMedia\VarnishWarmer\Api\VarnishPurgerInterface;
20
use LizardMedia\VarnishWarmer\Model\QueueHandler\VarnishUrlRegeneratorFactory;
21
use LizardMedia\VarnishWarmer\Model\QueueHandler\VarnishUrlPurgerFactory;
22
use Magento\Catalog\Api\Data\ProductInterface;
23
use Magento\Framework\App\Config\ScopeConfigInterface;
24
use Magento\Store\Model\ScopeInterface;
25
use Magento\Store\Model\Store;
26
27
/**
28
 * Class VarnishPurger
29
 * @package LizardMedia\VarnishWarmer\Model
30
 */
31
class VarnishPurger implements VarnishPurgerInterface
32
{
33
    /**
34
     * @var VarnishUrlRegeneratorInterface
35
     */
36
    protected $varnishUrlRegenerator;
37
38
    /**
39
     * @var VarnishUrlPurgerInterface
40
     */
41
    protected $varnishUrlPurger;
42
43
    /**
44
     * @var LockInterface
45
     */
46
    protected $lockHandler;
47
48
    /**
49
     * @var ScopeConfigInterface
50
     */
51
    protected $scopeConfig;
52
53
    /**
54
     * @var ProductUrlProviderInterface
55
     */
56
    protected $productUrlProvider;
57
58
    /**
59
     * @var CategoryUrlProviderInterface
60
     */
61
    protected $categoryUrlProvider;
62
63
    /**
64
     * @var PurgingConfigProviderInterface
65
     */
66
    protected $purgingConfigProvider;
67
68
    /**
69
     * @var array
70
     */
71
    protected $purgeBaseUrls;
72
73
    /**
74
     * @var string
75
     */
76
    protected $regenBaseUrl;
77
78
    /**
79
     * @var int
80
     */
81
    protected $storeViewId;
82
83
    /**
84
     * VarnishPurger constructor.
85
     * @param VarnishUrlRegeneratorFactory $varnishUrlRegeneratorFactory
86
     * @param VarnishUrlPurgerFactory $varnishUrlPurgerFactory
87
     * @param LockInterface $lockHandler
88
     * @param ScopeConfigInterface $scopeConfig
89
     * @param ProductUrlProviderInterface $productUrlProvider
90
     * @param CategoryUrlProviderInterface $categoryUrlProvider
91
     * @param PurgingConfigProviderInterface $purgingConfigProvider
92
     */
93
    public function __construct(
94
        VarnishUrlRegeneratorFactory $varnishUrlRegeneratorFactory,
95
        VarnishUrlPurgerFactory $varnishUrlPurgerFactory,
96
        LockInterface $lockHandler,
97
        ScopeConfigInterface $scopeConfig,
98
        ProductUrlProviderInterface $productUrlProvider,
99
        CategoryUrlProviderInterface $categoryUrlProvider,
100
        PurgingConfigProviderInterface $purgingConfigProvider
101
    ) {
102
        $this->lockHandler = $lockHandler;
103
        $this->scopeConfig = $scopeConfig;
104
        $this->productUrlProvider = $productUrlProvider;
105
        $this->categoryUrlProvider = $categoryUrlProvider;
106
        $this->purgingConfigProvider = $purgingConfigProvider;
107
108
        /** @var VarnishUrlRegeneratorInterface varnishUrlRegenerator */
109
        $this->varnishUrlRegenerator = $varnishUrlRegeneratorFactory->create();
110
        /** @var VarnishUrlPurgerInterface varnishUrlPurger */
111
        $this->varnishUrlPurger = $varnishUrlPurgerFactory->create();
112
    }
113
114
    /**
115
     * Purge *
116
     * Regen homepage, categories, products
117
     * @return void
118
     */
119 View Code Duplication
    public function purgeWildcard(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
120
    {
121
        $this->lock();
122
        $this->addUrlToPurge('*');
123
        $this->addUrlToRegenerate('');
124
        $this->regenerateCategories();
125
        $this->processProductsRegenerate();
126
        $this->varnishUrlPurger->runPurgeQueue();
127
        $this->varnishUrlRegenerator->runRegenerationQueue();
128
        $this->unlock();
129
    }
130
131
    /**
132
     * Purge * without any regeneration
133
     * Pass through lock
134
     * @return void
135
     */
136
    public function purgeWildcardWithoutRegen(): void
137
    {
138
        $this->addUrlToPurge('*');
139
        $this->varnishUrlPurger->runPurgeQueue();
140
    }
141
142
    /**
143
     * Purge homepage, categories, products
144
     * Regen homepage, categories, products
145
     * @return void
146
     */
147 View Code Duplication
    public function purgeAll(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
148
    {
149
        $this->lock();
150
        $this->addUrlToPurge('');
151
        $this->addUrlToRegenerate('');
152
        $this->processCategoriesPurgeAndRegenerate();
153
        $this->processProductsPurgeAndRegenerate();
154
        $this->varnishUrlPurger->runPurgeQueue();
155
        $this->varnishUrlRegenerator->runRegenerationQueue();
156
        $this->unlock();
157
    }
158
159
    /**
160
     * Purge homepage, categories
161
     * Regen homepage, categories
162
     * @return void
163
     */
164 View Code Duplication
    public function purgeGeneral(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
165
    {
166
        $this->lock();
167
        $this->addUrlToPurge('');
168
        $this->addUrlToRegenerate('');
169
        $this->processCategoriesPurgeAndRegenerate();
170
        $this->varnishUrlPurger->runPurgeQueue();
171
        $this->varnishUrlRegenerator->runRegenerationQueue();
172
        $this->unlock();
173
    }
174
175
    /**
176
     * Purge homepage
177
     * Regen homepage
178
     * @return void
179
     */
180 View Code Duplication
    public function purgeHomepage(): void
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
181
    {
182
        $this->lock();
183
        $this->addUrlToPurge('');
184
        $this->addUrlToRegenerate('');
185
        $this->varnishUrlPurger->runPurgeQueue();
186
        $this->varnishUrlRegenerator->runRegenerationQueue();
187
        $this->unlock();
188
    }
189
190
    /**
191
     * @return void
192
     */
193
    public function purgeAndRegenerateProducts(): void
194
    {
195
        $this->lock();
196
        $this->processProductsPurgeAndRegenerate();
197
        $this->varnishUrlPurger->runPurgeQueue();
198
        $this->varnishUrlRegenerator->runRegenerationQueue();
199
        $this->unlock();
200
    }
201
202
    /**
203
     * @param string $url
204
     * @return void
205
     */
206
    public function purgeAndRegenerateUrl(string $url): void
207
    {
208
        $this->addUrlToPurge($url);
209
        $this->addUrlToRegenerate($url);
210
        $this->varnishUrlPurger->runPurgeQueue();
211
        $this->varnishUrlRegenerator->runRegenerationQueue();
212
    }
213
214
    /**
215
     * @param ProductInterface $product
216
     * @return void
217
     */
218
    public function purgeProduct(ProductInterface $product): void
219
    {
220
        $productUrls = $this->getProductUrls($product->getId());
221
        foreach ($productUrls as $url) {
222
            $this->addUrlToPurge($url['request_path'], true);
223
        }
224
        $this->varnishUrlPurger->runPurgeQueue();
225
        $this->varnishUrlRegenerator->runRegenerationQueue();
226
    }
227
228
    /**
229
     * @param int $storeViewId
230
     */
231
    public function setStoreViewId(int $storeViewId)
232
    {
233
        $this->storeViewId = $storeViewId;
234
    }
235
236
    /**
237
     * @return bool
238
     */
239
    public function isLocked(): bool
240
    {
241
        return $this->lockHandler->isLocked();
242
    }
243
244
    /**
245
     * @return string
246
     */
247
    public function getLockMessage(): string
248
    {
249
        return $this->lockHandler->getLockDate();
250
    }
251
252
    /**
253
     * @param $relativeUrl
254
     * @param bool $autoRegenerate
255
     * @return void
256
     */
257
    private function addUrlToPurge($relativeUrl, $autoRegenerate = false): void
258
    {
259
        foreach ($this->getPurgeBaseUrls() as $purgeBaseUrl) {
260
            $url = $purgeBaseUrl . $relativeUrl;
261
            $this->varnishUrlPurger->addUrlToPurge($url);
262
            if ($autoRegenerate) {
263
                $this->addUrlToRegenerate($relativeUrl);
264
            }
265
        }
266
    }
267
268
    /**
269
     * @param $relativeUrl
270
     * @return void
271
     */
272
    private function addUrlToRegenerate($relativeUrl): void
273
    {
274
        $url = $this->getRegenBaseUrl() . $relativeUrl;
275
        $this->varnishUrlRegenerator->addUrlToRegenerate($url);
276
    }
277
278
    /**
279
     * @return void
280
     */
281
    private function regenerateCategories(): void
282
    {
283
        $categories = $this->getCategories();
284
        foreach ($categories as $category) {
285
            $this->addUrlToRegenerate($category['request_path']);
286
        }
287
    }
288
289
    /**
290
     * @return void
291
     */
292
    private function processCategoriesPurgeAndRegenerate(): void
293
    {
294
        $categories = $this->getCategories();
295
        foreach ($categories as $category) {
296
            $this->addUrlToPurge($category['request_path'], true);
297
        }
298
    }
299
300
    /**
301
     * @return void
302
     */
303
    private function processProductsRegenerate(): void
304
    {
305
        $productUrls = $this->getAllProductsUrls();
306
        foreach ($productUrls as $key => $url) {
307
            $this->addUrlToRegenerate($url['request_path']);
308
        }
309
    }
310
311
    /**
312
     * @return void
313
     */
314
    private function processProductsPurgeAndRegenerate(): void
315
    {
316
        $productUrls = $this->getAllProductsUrls();
317
        foreach ($productUrls as $key => $url) {
318
            $this->addUrlToPurge($url['request_path'], true);
319
        }
320
    }
321
322
    /**
323
     * @return array
324
     */
325
    private function getAllProductsUrls(): array
326
    {
327
        return $this->productUrlProvider->getActiveProductsUrls();
328
    }
329
330
    /**
331
     * @param $productId
332
     * @return array
333
     */
334
    private function getProductUrls($productId): array
335
    {
336
        return $this->productUrlProvider->getProductUrls($productId);
337
    }
338
339
    /**
340
     * @return array
341
     */
342
    private function getCategories(): array
343
    {
344
        return $this->categoryUrlProvider->getActiveCategoriesUrls();
345
    }
346
347
    /**
348
     * @return void
349
     */
350
    private function lock(): void
351
    {
352
        $this->lockHandler->lock();
353
    }
354
355
    /**
356
     * @return void
357
     */
358
    private function unlock(): void
359
    {
360
        $this->lockHandler->unlock();
361
    }
362
363
    /**
364
     * @return void
365
     */
366
    private function setPurgeBaseUrls(): void
367
    {
368
        if ($this->purgingConfigProvider->isPurgeCustomHostEnabled()) {
369
            $this->purgeBaseUrls = $this->purgingConfigProvider->getCustomPurgeHosts();
370
        } else {
371
            $baseUrl = $this->scopeConfig->getValue(
372
                Store::XML_PATH_UNSECURE_BASE_URL,
373
                ScopeInterface::SCOPE_STORE,
374
                $this->storeViewId
375
            );
376
            $this->purgeBaseUrls = [$baseUrl];
377
        }
378
379
        foreach ($this->purgeBaseUrls as &$purgeBaseUrl) {
380
            if (substr($purgeBaseUrl, -1) != "/") {
381
                $purgeBaseUrl .= "/";
382
            }
383
        }
384
    }
385
386
    /**
387
     * @return void
388
     */
389
    private function setRegenBaseUrl(): void
390
    {
391
        $this->regenBaseUrl = $this->scopeConfig->getValue(
392
            Store::XML_PATH_UNSECURE_BASE_URL,
393
            ScopeInterface::SCOPE_STORE,
394
            $this->storeViewId
395
        );
396
397
        if (substr($this->regenBaseUrl, -1) != "/") {
398
            $this->regenBaseUrl .= "/";
399
        }
400
    }
401
402
    /**
403
     * @return array
404
     */
405
    private function getPurgeBaseUrls()
406
    {
407
        if (!$this->purgeBaseUrls) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $this->purgeBaseUrls of type array 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...
408
            $this->setPurgeBaseUrls();
409
        }
410
        return $this->purgeBaseUrls;
411
    }
412
413
    /**
414
     * @return string
415
     */
416
    private function getRegenBaseUrl()
417
    {
418
        if (!$this->regenBaseUrl) {
419
            $this->setRegenBaseUrl();
420
        }
421
        return $this->regenBaseUrl;
422
    }
423
}
424