1
|
|
|
<?php |
2
|
|
|
|
3
|
|
|
/** |
4
|
|
|
* TechDivision\Import\Category\Observers\UrlRewriteUpdateObserver |
5
|
|
|
* |
6
|
|
|
* NOTICE OF LICENSE |
7
|
|
|
* |
8
|
|
|
* This source file is subject to the Open Software License (OSL 3.0) |
9
|
|
|
* that is available through the world-wide-web at this URL: |
10
|
|
|
* http://opensource.org/licenses/osl-3.0.php |
11
|
|
|
* |
12
|
|
|
* PHP version 5 |
13
|
|
|
* |
14
|
|
|
* @author Tim Wagner <[email protected]> |
15
|
|
|
* @copyright 2016 TechDivision GmbH <[email protected]> |
16
|
|
|
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) |
17
|
|
|
* @link https://github.com/techdivision/import-category |
18
|
|
|
* @link http://www.techdivision.com |
19
|
|
|
*/ |
20
|
|
|
|
21
|
|
|
namespace TechDivision\Import\Category\Observers; |
22
|
|
|
|
23
|
|
|
use TechDivision\Import\Category\Utils\MemberNames; |
24
|
|
|
use TechDivision\Import\Category\Utils\CoreConfigDataKeys; |
25
|
|
|
use TechDivision\Import\Category\Utils\ColumnKeys; |
26
|
|
|
use TechDivision\Import\Category\Utils\ConfigurationKeys; |
27
|
|
|
|
28
|
|
|
/** |
29
|
|
|
* Observer that creates/updates the category's URL rewrites. |
30
|
|
|
* |
31
|
|
|
* @author Tim Wagner <[email protected]> |
32
|
|
|
* @copyright 2016 TechDivision GmbH <[email protected]> |
33
|
|
|
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0) |
34
|
|
|
* @link https://github.com/techdivision/import-category |
35
|
|
|
* @link http://www.techdivision.com |
36
|
|
|
*/ |
37
|
|
|
class UrlRewriteUpdateObserver extends UrlRewriteObserver |
38
|
|
|
{ |
39
|
|
|
|
40
|
|
|
/** |
41
|
|
|
* Array with the existing URL rewrites of the actual category. |
42
|
|
|
* |
43
|
|
|
* @var array |
44
|
|
|
*/ |
45
|
|
|
protected $existingUrlRewrites = array(); |
46
|
|
|
|
47
|
|
|
/** |
48
|
|
|
* Return's the URL rewrite for the passed request path. |
49
|
|
|
* |
50
|
|
|
* @param string $requestPath The request path to return the URL rewrite for |
51
|
|
|
* |
52
|
|
|
* @return array|null The URL rewrite |
53
|
|
|
*/ |
54
|
|
|
protected function getExistingUrlRewrite($requestPath) |
55
|
|
|
{ |
56
|
|
|
if (isset($this->existingUrlRewrites[$requestPath])) { |
57
|
|
|
return $this->existingUrlRewrites[$requestPath]; |
58
|
|
|
} |
59
|
|
|
} |
60
|
|
|
|
61
|
|
|
/** |
62
|
|
|
* Remove's the passed URL rewrite from the existing one's. |
63
|
|
|
* |
64
|
|
|
* @param array $urlRewrite The URL rewrite to remove |
65
|
|
|
* |
66
|
|
|
* @return void |
67
|
|
|
*/ |
68
|
|
|
protected function removeExistingUrlRewrite(array $urlRewrite) |
69
|
|
|
{ |
70
|
|
|
|
71
|
|
|
// load store ID and request path |
72
|
|
|
$requestPath = $urlRewrite[MemberNames::REQUEST_PATH]; |
73
|
|
|
|
74
|
|
|
// query whether or not the URL rewrite exists and remove it, if available |
75
|
|
|
if (isset($this->existingUrlRewrites[$requestPath])) { |
76
|
|
|
unset($this->existingUrlRewrites[$requestPath]); |
77
|
|
|
} |
78
|
|
|
} |
79
|
|
|
|
80
|
|
|
/** |
81
|
|
|
* Process the observer's business logic. |
82
|
|
|
* |
83
|
|
|
* @return void |
84
|
|
|
*/ |
85
|
|
|
protected function process() |
86
|
|
|
{ |
87
|
|
|
|
88
|
|
|
// process the new URL rewrites first |
89
|
|
|
parent::process(); |
90
|
|
|
|
91
|
|
|
// create redirect URL rewrites for the existing URL rewrites |
92
|
|
|
foreach ($this->existingUrlRewrites as $existingUrlRewrites) { |
93
|
|
|
foreach ($existingUrlRewrites as $existingUrlRewrite) { |
94
|
|
|
// if the URL rewrite has been created manually |
95
|
|
|
if ((integer) $existingUrlRewrite[MemberNames::IS_AUTOGENERATED] === 0) { |
96
|
|
|
// do NOT create another redirect |
97
|
|
|
continue; |
98
|
|
|
} |
99
|
|
|
|
100
|
|
|
// query whether or not 301 redirects have to be created, so don't |
101
|
|
|
// create redirects if the the rewrite history has been deactivated |
102
|
|
|
if ($this->getSubject()->getCoreConfigData(CoreConfigDataKeys::CATALOG_SEO_CATEGORY_URL_SUFFIX, true)) { |
103
|
|
|
// if the URL rewrite already IS a redirect |
104
|
|
|
if ((integer) $existingUrlRewrite[MemberNames::REDIRECT_TYPE] !== 0) { |
105
|
|
|
// do NOT create another redirect |
106
|
|
|
continue; |
107
|
|
|
} |
108
|
|
|
|
109
|
|
|
// if yes, load the category of the original one |
110
|
|
|
$category = $this->getCategory($existingUrlRewrite[MemberNames::ENTITY_ID]); |
111
|
|
|
|
112
|
|
|
// load target path/metadata for the actual category |
113
|
|
|
$targetPath = $this->prepareRequestPath($category); |
|
|
|
|
114
|
|
|
|
115
|
|
|
// override data with the 301 configuration |
116
|
|
|
$attr = array( |
117
|
|
|
MemberNames::REDIRECT_TYPE => 301, |
118
|
|
|
MemberNames::TARGET_PATH => $targetPath, |
119
|
|
|
); |
120
|
|
|
|
121
|
|
|
// merge and return the prepared URL rewrite |
122
|
|
|
$existingUrlRewrite = $this->mergeEntity($existingUrlRewrite, $attr); |
123
|
|
|
|
124
|
|
|
// create the URL rewrite |
125
|
|
|
$this->persistUrlRewrite($existingUrlRewrite); |
126
|
|
|
|
127
|
|
|
} else { |
128
|
|
|
// query whether or not the URL rewrite has to be removed |
129
|
|
|
if ($this->getSubject()->getConfiguration()->hasParam(ConfigurationKeys::CLEAN_UP_URL_REWRITES) && |
130
|
|
|
$this->getSubject()->getConfiguration()->getParam(ConfigurationKeys::CLEAN_UP_URL_REWRITES) |
131
|
|
|
) { |
132
|
|
|
// delete the existing URL rewrite |
133
|
|
|
$this->deleteUrlRewrite($existingUrlRewrite); |
134
|
|
|
|
135
|
|
|
// log a message, that old URL rewrites have been cleaned-up |
136
|
|
|
$this->getSubject() |
137
|
|
|
->getSystemLogger() |
138
|
|
|
->warning( |
139
|
|
|
sprintf( |
140
|
|
|
'Cleaned-up %d URL rewrite "%s" for category with path "%s"', |
141
|
|
|
$existingUrlRewrite[MemberNames::REQUEST_PATH], |
142
|
|
|
$this->getValue(ColumnKeys::PATH) |
143
|
|
|
) |
144
|
|
|
); |
145
|
|
|
} |
146
|
|
|
} |
147
|
|
|
} |
148
|
|
|
} |
149
|
|
|
} |
150
|
|
|
|
151
|
|
|
/** |
152
|
|
|
* Prepare's the URL rewrites that has to be created/updated. |
153
|
|
|
* |
154
|
|
|
* @return void |
155
|
|
|
*/ |
156
|
|
|
protected function prepareUrlRewrites() |
157
|
|
|
{ |
158
|
|
|
|
159
|
|
|
// call the parent method |
160
|
|
|
parent::prepareUrlRewrites(); |
161
|
|
|
|
162
|
|
|
// (re-)initialize the array for the existing URL rewrites |
163
|
|
|
$this->existingUrlRewrites = array(); |
164
|
|
|
|
165
|
|
|
// load primary key and entity type |
166
|
|
|
$pk = $this->getPrimaryKey(); |
167
|
|
|
$entityType = UrlRewriteObserver::ENTITY_TYPE; |
168
|
|
|
|
169
|
|
|
// load the store ID to use |
170
|
|
|
$storeId = $this->getSubject()->getRowStoreId(); |
|
|
|
|
171
|
|
|
|
172
|
|
|
// load the existing URL rewrites of the actual entity |
173
|
|
|
$existingUrlRewrites = $this->getUrlRewritesByEntityTypeAndEntityIdAndStoreId($entityType, $pk, $storeId); |
174
|
|
|
|
175
|
|
|
// prepare the existing URL rewrites to improve searching them by store ID/request path |
176
|
|
|
foreach ($existingUrlRewrites as $existingUrlRewrite) { |
177
|
|
|
// load the request path from the existing URL rewrite |
178
|
|
|
$requestPath = $existingUrlRewrite[MemberNames::REQUEST_PATH]; |
179
|
|
|
|
180
|
|
|
// append the URL rewrite with its store ID/request path |
181
|
|
|
$this->existingUrlRewrites[$requestPath] = $existingUrlRewrite; |
182
|
|
|
} |
183
|
|
|
} |
184
|
|
|
|
185
|
|
|
/** |
186
|
|
|
* Initialize the URL rewrite with the passed attributes and returns an instance. |
187
|
|
|
* |
188
|
|
|
* @param array $attr The URL rewrite attributes |
189
|
|
|
* |
190
|
|
|
* @return array The initialized URL rewrite |
191
|
|
|
*/ |
192
|
|
|
protected function initializeUrlRewrite(array $attr) |
193
|
|
|
{ |
194
|
|
|
|
195
|
|
|
// load store ID and request path |
196
|
|
|
$categoryId = $attr[MemberNames::ENTITY_ID]; |
197
|
|
|
$requestPath = $attr[MemberNames::REQUEST_PATH]; |
198
|
|
|
|
199
|
|
|
// iterate over the available URL rewrites to find the one that matches the category ID |
200
|
|
|
foreach ($this->existingUrlRewrites as $urlRewrite) { |
201
|
|
|
// compare the category IDs AND the request path |
202
|
|
|
if ($categoryId === $urlRewrite[MemberNames::ENTITY_ID] && |
203
|
|
|
$requestPath === $urlRewrite[MemberNames::REQUEST_PATH] |
204
|
|
|
) { |
205
|
|
|
// if a URL rewrite has been found, do NOT create a redirect |
206
|
|
|
$this->removeExistingUrlRewrite($urlRewrite); |
207
|
|
|
|
208
|
|
|
// if the found URL rewrite has been created manually |
209
|
|
|
if ((integer) $urlRewrite[MemberNames::IS_AUTOGENERATED] === 0) { |
210
|
|
|
// do NOT update it nor create a another redirect |
211
|
|
|
return false; |
|
|
|
|
212
|
|
|
} |
213
|
|
|
|
214
|
|
|
// if the found URL rewrite has been autogenerated, then update it |
215
|
|
|
return $this->mergeEntity($urlRewrite, $attr); |
216
|
|
|
} |
217
|
|
|
} |
218
|
|
|
|
219
|
|
|
// simple return the attributes |
220
|
|
|
return $attr; |
221
|
|
|
} |
222
|
|
|
|
223
|
|
|
/** |
224
|
|
|
* Return's the category with the passed ID. |
225
|
|
|
* |
226
|
|
|
* @param integer $categoryId The ID of the category to return |
227
|
|
|
* |
228
|
|
|
* @return array The category data |
229
|
|
|
* @throws \Exception Is thrown, if the category is not available |
230
|
|
|
*/ |
231
|
|
|
protected function getCategory($categoryId) |
232
|
|
|
{ |
233
|
|
|
return $this->getSubject()->getCategory($categoryId); |
|
|
|
|
234
|
|
|
} |
235
|
|
|
|
236
|
|
|
/** |
237
|
|
|
* Return's the URL rewrites for the passed URL entity type and ID. |
238
|
|
|
* |
239
|
|
|
* @param string $entityType The entity type to load the URL rewrites for |
240
|
|
|
* @param integer $entityId The entity ID to load the URL rewrites for |
241
|
|
|
* @param integer $storeId The store ID to load the URL rewrites for |
242
|
|
|
* |
243
|
|
|
* @return array The URL rewrites |
244
|
|
|
*/ |
245
|
|
|
protected function getUrlRewritesByEntityTypeAndEntityIdAndStoreId($entityType, $entityId, $storeId) |
246
|
|
|
{ |
247
|
|
|
return $this->getCategoryBunchProcessor()->getUrlRewritesByEntityTypeAndEntityIdAndStoreId($entityType, $entityId, $storeId); |
248
|
|
|
} |
249
|
|
|
|
250
|
|
|
/** |
251
|
|
|
* Delete's the URL rewrite with the passed attributes. |
252
|
|
|
* |
253
|
|
|
* @param array $row The attributes of the entity to delete |
254
|
|
|
* @param string|null $name The name of the prepared statement that has to be executed |
255
|
|
|
* |
256
|
|
|
* @return void |
257
|
|
|
*/ |
258
|
|
|
protected function deleteUrlRewrite($row, $name = null) |
259
|
|
|
{ |
260
|
|
|
$this->getCategoryBunchProcessor()->removeUrlRewrite($row, $name); |
|
|
|
|
261
|
|
|
} |
262
|
|
|
} |
263
|
|
|
|
This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.
If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress.
In this case you can add the
@ignore
PhpDoc annotation to the duplicate definition and it will be ignored.