Passed
Push — master ( fc7dfd...a70edc )
by Tibor
02:21
created

PathValidatorObserver::execute()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 14
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 14
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 8
nc 3
nop 1
1
<?php
2
3
namespace Tkotosz\CatalogRouter\Observer;
4
5
use Magento\Backend\Model\UrlInterface;
6
use Magento\Framework\Event\Observer;
7
use Magento\Framework\Event\ObserverInterface;
8
use Magento\Framework\Exception\AlreadyExistsException;
9
use Magento\Framework\Model\AbstractModel;
10
use Magento\Store\Api\Data\StoreInterface;
11
use Magento\Store\Model\StoreManagerInterface;
12
use Tkotosz\CatalogRouter\Api\CatalogUrlPathProviderInterface;
13
use Tkotosz\CatalogRouter\Model\EntityData;
14
use Tkotosz\CatalogRouter\Model\Service\UrlPathUsedCheckerContainer;
15
use Tkotosz\CatalogRouter\Model\UrlPath;
16
17
abstract class PathValidatorObserver implements ObserverInterface
18
{
19
    const ERROR_MESSAGE = 'The "%1" url path already used by a <a href="%2" target="_blank">%3 (id: %4)</a> in the %5 (id: %6) store';
20
21
    /**
22
     * @var UrlPathUsedCheckerContainer
23
     */
24
    protected $urlPathUsedChecker;
25
    
26
    /**
27
     * @var StoreManagerInterface
28
     */
29
    protected $storeManager;
30
    
31
    /**
32
     * @var CatalogUrlPathProviderInterface
33
     */
34
    protected $urlPathProvider;
35
    
36
    /**
37
     * @var UrlInterface
38
     */
39
    protected $urlProvider;
40
    
41
    /**
42
     * @var array
43
     */
44
    protected $entityEditUrls;
45
    
46
    /**
47
     * @param UrlPathUsedCheckerContainer     $urlPathUsedChecker
48
     * @param StoreManagerInterface           $storeManager
49
     * @param CatalogUrlPathProviderInterface $urlPathProvider
50
     * @param UrlInterface                    $urlProvider
51
     * @param array                           $entityEditUrls
52
     */
53
    public function __construct(
54
        UrlPathUsedCheckerContainer $urlPathUsedChecker,
55
        StoreManagerInterface $storeManager,
56
        CatalogUrlPathProviderInterface $urlPathProvider,
57
        UrlInterface $urlProvider,
58
        array $entityEditUrls
59
    ) {
60
        $this->urlPathUsedChecker = $urlPathUsedChecker;
61
        $this->storeManager = $storeManager;
62
        $this->urlPathProvider = $urlPathProvider;
63
        $this->urlProvider = $urlProvider;
64
        $this->entityEditUrls = $entityEditUrls;
65
    }
66
67
    /**
68
     * @param Observer $observer
69
     * @return void
70
     */
71
    public function execute(Observer $observer)
72
    {
73
        $entity = $this->getEntity($observer);
74
75
        foreach ($this->getEntityStoreIds($entity) as $storeId) {
76
            $urlPath = $this->getEntityUrlPath($entity, $storeId);
77
            $resolvedEntities = $this->getOtherEntitiesWithPath($urlPath, $storeId, $entity);
78
79
            if (count($resolvedEntities) > 0) {
80
                $store = $this->storeManager->getStore($storeId);
81
                throw new AlreadyExistsException($this->getErrorMessage($urlPath, $store, $resolvedEntities));
82
            }
83
        }
84
    }
85
86
    protected function getOtherEntitiesWithPath(UrlPath $urlPath, int $storeId, AbstractModel $currentEntity)
87
    {
88
        $resolvedEntities = [];
89
90
        $currentEntityData = new EntityData($this->getCurrentEntityType(), $currentEntity->getId(), $urlPath->getLastPart());
91
92
        foreach ($this->urlPathUsedChecker->check($urlPath, $storeId) as $entity) {
93
            if ($entity->getType() == $currentEntityData->getType() && $entity->getId() == $currentEntityData->getId()) {
94
                continue;
95
            }
96
97
            $resolvedEntities[] = $entity;
98
        }
99
100
        return $resolvedEntities;
101
    }
102
103
    protected function getErrorMessage(UrlPath $urlPath, StoreInterface $store, array $entities)
104
    {
105
        $messages = [];
106
        
107
        foreach ($entities as $entity) {
108
            $messages[] = __(
109
                self::ERROR_MESSAGE,
110
                $urlPath->getFullPath(),
111
                $this->getEntityEditUrl($entity),
112
                $entity->getType(),
113
                $entity->getId(),
114
                $store->getName(),
115
                $store->getId()
116
            );
117
        }
118
119
        return __(join("<br>", $messages));
120
    }
121
122
    protected function getEntityEditUrl(EntityData $entity)
123
    {
124
        $editUrlPath = $this->entityEditUrls[$entity->getType()]['url_path'];
125
        $idParam = $this->entityEditUrls[$entity->getType()]['id_param'];
126
        
127
        return $this->urlProvider->getUrl($editUrlPath, [$idParam => $entity->getId()]);
128
    }
129
130
    abstract protected function getCurrentEntityType();
131
132
    abstract protected function getEntity(Observer $observer);
133
134
    abstract protected function getEntityStoreIds(AbstractModel $entity);
135
136
    abstract protected function getEntityUrlPath(AbstractModel $entity, int $storeId);
137
}
138