Completed
Push — master ( 477d2b...3ad691 )
by Tim
02:42 queued 01:09
created

UrlRewriteUpdateObserver::getExistingUrlRewrite()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 6

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 6
rs 10
c 0
b 0
f 0
cc 2
nc 2
nop 1
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 2019 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 2019 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 $existingUrlRewrite) {
93
            // query whether or not 301 redirects have to be created, so don't
94
            // create redirects if the the rewrite history has been deactivated
95
            if ($this->getSubject()->getCoreConfigData(CoreConfigDataKeys::CATALOG_SEO_SAVE_REWRITES_HISTORY, true)) {
96
                // load target path
97
                $targetPath = $this->prepareRequestPath();
98
99
                // skip update of URL rewrite, if nothing to change
100
                if ($targetPath === $existingUrlRewrite[MemberNames::TARGET_PATH] &&
101
                    301 === (int)$existingUrlRewrite[MemberNames::REDIRECT_TYPE]) {
102
                    // stop processing the URL rewrite
103
                    continue;
104
                }
105
106
                // override data with the 301 configuration
107
                $attr = array(
108
                    MemberNames::REDIRECT_TYPE    => 301,
109
                    MemberNames::TARGET_PATH      => $targetPath,
110
                    MemberNames::IS_AUTOGENERATED => 0
111
                );
112
113
                // merge and return the prepared URL rewrite
114
                $existingUrlRewrite = $this->mergeEntity($existingUrlRewrite, $attr);
115
116
                // create the URL rewrite
117
                $this->persistUrlRewrite($existingUrlRewrite);
118
            } else {
119
                // query whether or not the URL rewrite has to be removed
120
                if ($this->getSubject()->getConfiguration()->hasParam(ConfigurationKeys::CLEAN_UP_URL_REWRITES) &&
121
                    $this->getSubject()->getConfiguration()->getParam(ConfigurationKeys::CLEAN_UP_URL_REWRITES)
122
                ) {
123
                    // delete the existing URL rewrite
124
                    $this->deleteUrlRewrite($existingUrlRewrite);
125
126
                    // log a message, that old URL rewrites have been cleaned-up
127
                    $this->getSubject()
128
                         ->getSystemLogger()
129
                         ->warning(
130
                             sprintf(
131
                                 'Cleaned-up %d URL rewrite "%s" for category with path "%s"',
132
                                 $existingUrlRewrite[MemberNames::REQUEST_PATH],
133
                                 $this->getValue(ColumnKeys::PATH)
134
                             )
135
                         );
136
                }
137
            }
138
        }
139
    }
140
141
    /**
142
     * Prepare's the URL rewrites that has to be created/updated.
143
     *
144
     * @return void
145
     */
146
    protected function prepareUrlRewrites()
147
    {
148
149
        // call the parent method
150
        parent::prepareUrlRewrites();
151
152
        // (re-)initialize the array for the existing URL rewrites
153
        $this->existingUrlRewrites = array();
154
155
        // load primary key and entity type
156
        $pk = $this->getPrimaryKey();
157
        $entityType = UrlRewriteObserver::ENTITY_TYPE;
158
159
        // load the store ID to use
160
        $storeId = $this->getSubject()->getRowStoreId();
0 ignored issues
show
Bug introduced by
The method getRowStoreId() does not exist on TechDivision\Import\Subjects\SubjectInterface. Did you maybe mean getRow()?

This check marks calls to methods that do not seem to exist on an object.

This is most likely the result of a method being renamed without all references to it being renamed likewise.

Loading history...
161
162
        // load the existing URL rewrites of the actual entity
163
        $existingUrlRewrites = $this->loadUrlRewritesByEntityTypeAndEntityIdAndStoreId($entityType, $pk, $storeId);
164
165
        // prepare the existing URL rewrites to improve searching them by store ID/request path
166
        foreach ($existingUrlRewrites as $existingUrlRewrite) {
167
            // load the request path from the existing URL rewrite
168
            $requestPath = $existingUrlRewrite[MemberNames::REQUEST_PATH];
169
170
            // append the URL rewrite with its store ID/request path
171
            $this->existingUrlRewrites[$requestPath] = $existingUrlRewrite;
172
        }
173
    }
174
175
    /**
176
     * Initialize the URL rewrite with the passed attributes and returns an instance.
177
     *
178
     * @param array $attr The URL rewrite attributes
179
     *
180
     * @return array The initialized URL rewrite
181
     */
182
    protected function initializeUrlRewrite(array $attr)
183
    {
184
185
        // load store ID and request path
186
        $categoryId = $attr[MemberNames::ENTITY_ID];
187
        $requestPath = $attr[MemberNames::REQUEST_PATH];
188
189
        // iterate over the available URL rewrites to find the one that matches the category ID
190
        foreach ($this->existingUrlRewrites as $urlRewrite) {
191
            // compare the category IDs AND the request path
192
            if ($categoryId === $urlRewrite[MemberNames::ENTITY_ID] &&
193
                $requestPath === $urlRewrite[MemberNames::REQUEST_PATH]
194
            ) {
195
                // if a URL rewrite has been found, do NOT create a redirect
196
                $this->removeExistingUrlRewrite($urlRewrite);
197
198
                // if the found URL rewrite has been autogenerated, then update it
199
                return $this->mergeEntity($urlRewrite, $attr);
200
            }
201
        }
202
203
        // simple return the attributes
204
        return $attr;
205
    }
206
207
    /**
208
     * Return's the URL rewrites for the passed URL entity type and ID.
209
     *
210
     * @param string  $entityType The entity type to load the URL rewrites for
211
     * @param integer $entityId   The entity ID to load the URL rewrites for
212
     * @param integer $storeId    The store ID to load the URL rewrites for
213
     *
214
     * @return array The URL rewrites
215
     */
216
    protected function loadUrlRewritesByEntityTypeAndEntityIdAndStoreId($entityType, $entityId, $storeId)
217
    {
218
        return $this->getCategoryUrlRewriteProcessor()->loadUrlRewritesByEntityTypeAndEntityIdAndStoreId($entityType, $entityId, $storeId);
219
    }
220
221
    /**
222
     * Delete's the URL rewrite with the passed attributes.
223
     *
224
     * @param array       $row  The attributes of the entity to delete
225
     * @param string|null $name The name of the prepared statement that has to be executed
226
     *
227
     * @return void
228
     */
229
    protected function deleteUrlRewrite($row, $name = null)
230
    {
231
        $this->getCategoryUrlRewriteProcessor()->deleteUrlRewrite($row, $name);
232
    }
233
}
234