Completed
Push — pac-264--pdo-exception ( 84742c...6547cc )
by
unknown
09:24
created

UrlKeyUtil::loadUrlKey()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 20

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 20
rs 9.6
c 0
b 0
f 0
cc 2
nc 2
nop 2
1
<?php
2
3
/**
4
 * TechDivision\Import\Utils\UrlKeyUtil
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 2020 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
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Utils;
22
23
use TechDivision\Import\Subjects\UrlKeyAwareSubjectInterface;
24
use TechDivision\Import\Services\UrlKeyAwareProcessorInterface;
25
26
/**
27
 * Utility class that provides functionality to make URL keys unique.
28
 *
29
 * @author    Tim Wagner <[email protected]>
30
 * @copyright 2020 TechDivision GmbH <[email protected]>
31
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
32
 * @link      https://github.com/techdivision/import
33
 * @link      http://www.techdivision.com
34
 */
35
class UrlKeyUtil implements UrlKeyUtilInterface
36
{
37
38
    /**
39
     * The URL key aware processor instance.
40
     *
41
     * \TechDivision\Import\Services\UrlKeyAwareProcessorInterface
42
     */
43
    protected $urlKeyAwareProcessor;
44
45
    /**
46
     * Construct a new instance.
47
     *
48
     * @param \TechDivision\Import\Services\UrlKeyAwareProcessorInterface $urlKeyAwareProcessor The URL key aware processor instance
49
     */
50
    public function __construct(UrlKeyAwareProcessorInterface $urlKeyAwareProcessor)
51
    {
52
        $this->urlKeyAwareProcessor = $urlKeyAwareProcessor;
53
    }
54
55
    /**
56
     * Returns the URL key aware processor instance.
57
     *
58
     * @return \TechDivision\Import\Services\UrlKeyAwareProcessorInterface The processor instance
59
     */
60
    protected function getUrlKeyAwareProcessor()
61
    {
62
        return $this->urlKeyAwareProcessor;
63
    }
64
65
    /**
66
     * Load's and return's the URL rewrite for the given request path and store ID
67
     *
68
     * @param string $requestPath The request path to load the URL rewrite for
69
     * @param int    $storeId     The store ID to load the URL rewrite for
70
     *
71
     * @return string|null The URL rewrite found for the given request path and store ID
72
     */
73
    protected function loadUrlRewriteByRequestPathAndStoreId(string $requestPath, int $storeId)
74
    {
75
        return $this->getUrlKeyAwareProcessor()->loadUrlRewriteByRequestPathAndStoreId($requestPath, $storeId);
76
    }
77
78
    /**
79
     * Make's the passed URL key unique by adding the next number to the end.
80
     *
81
     * @param \TechDivision\Import\Subjects\UrlKeyAwareSubjectInterface $subject The subject to make the URL key unique for
82
     * @param string                                                    $urlKey  The URL key to make unique
83
     * @param string|null                                               $urlPath The URL path to make unique (only used for categories)
84
     *
85
     * @return string The unique URL key
86
     */
87
    public function makeUnique(UrlKeyAwareSubjectInterface $subject, string $urlKey, string $urlPath = null) : string
88
    {
89
90
        // initialize the store view ID, use the default store view if no store view has
91
        // been set, because the default url_key value has been set in default store view
92
        $storeId = $subject->getRowStoreId();
93
94
        // initialize the counter
95
        $counter = 0;
96
97
        // initialize the counters
98
        $matchingCounters = array();
99
        $notMatchingCounters = array();
100
101
        // pre-initialze the URL by concatenating path and/or key to query for
102
        $url = $urlPath ? sprintf('%s/%s', $urlPath, $urlKey) : $urlKey;
103
104
        do {
105
            // try to load the attribute
106
            $urlRewrite = $this->loadUrlRewriteByRequestPathAndStoreId($url, $storeId);
107
108
            // try to load the entity's URL key
109
            if ($urlRewrite) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $urlRewrite 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...
110
                // this IS the URL key of the passed entity
111
                if ($subject->isUrlKeyOf($urlRewrite)) {
112
                    $matchingCounters[] = $counter;
113
                } else {
114
                    $notMatchingCounters[] = $counter;
115
                }
116
117
                // prepare the next URL key to query for
118
                $url = sprintf('%s-%d', $urlKey, ++$counter);
119
            }
120
        } while ($urlRewrite);
0 ignored issues
show
Bug Best Practice introduced by
The expression $urlRewrite 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...
121
122
        // sort the array ascending according to the counter
123
        asort($matchingCounters);
124
        asort($notMatchingCounters);
125
126
        // this IS the URL key of the passed entity => we've an UPDATE
127
        if (sizeof($matchingCounters) > 0) {
128
            // load highest counter
129
            $counter = end($matchingCounters);
130
            // if the counter is > 0, we've to append it to the new URL key
131
            if ($counter > 0) {
132
                $urlKey = sprintf('%s-%d', $urlKey, $counter);
133
            }
134
        } elseif (sizeof($notMatchingCounters) > 0) {
135
            // create a new URL key by raising the counter
136
            $newCounter = end($notMatchingCounters);
137
            $urlKey = sprintf('%s-%d', $urlKey, ++$newCounter);
138
        }
139
140
        // return the passed URL key, if NOT
141
        return $urlKey;
142
    }
143
144
    /**
145
     * Load the url_key if exists
146
     *
147
     * @param \TechDivision\Import\Subjects\UrlKeyAwareSubjectInterface $subject      The subject to make the URL key unique for
148
     * @param int                                                       $primaryKeyId The ID from category or product
149
     *
150
     * @return string|null The URL key
151
     */
152
    public function loadUrlKey(UrlKeyAwareSubjectInterface $subject, $primaryKeyId)
153
    {
154
        // initialize the entity type ID
155
        $entityType = $subject->getEntityType();
156
        $entityTypeId = (integer) $entityType[MemberNames::ENTITY_TYPE_ID];
157
158
        // initialize the store view ID, use the admin store view if no store view has
159
        // been set, because the default url_key value has been set in admin store view
160
        $storeId = $subject->getRowStoreId(StoreViewCodes::ADMIN);
161
162
        // try to load the attribute
163
        $attribute = $this->getUrlKeyAwareProcessor()
164
            ->loadVarcharAttributeByAttributeCodeAndEntityTypeIdAndStoreIdAndPrimaryKey(
165
                MemberNames::URL_KEY,
166
                $entityTypeId,
167
                $storeId,
168
                $primaryKeyId
169
            );
170
        return $attribute ? $attribute['value'] : null;
171
    }
172
}
173