Toolkit::handleSubstituteReplacement()   A
last analyzed

Complexity

Conditions 4
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 4
eloc 7
nc 3
nop 3
dl 0
loc 11
rs 10
c 0
b 0
f 0
1
<?php
2
3
/**
4
 * PAYONE Magento 2 Connector is free software: you can redistribute it and/or modify
5
 * it under the terms of the GNU Lesser General Public License as published by
6
 * the Free Software Foundation, either version 3 of the License, or
7
 * (at your option) any later version.
8
 *
9
 * PAYONE Magento 2 Connector is distributed in the hope that it will be useful,
10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
12
 * GNU Lesser General Public License for more details.
13
 *
14
 * You should have received a copy of the GNU Lesser General Public License
15
 * along with PAYONE Magento 2 Connector. If not, see <http://www.gnu.org/licenses/>.
16
 *
17
 * PHP version 5
18
 *
19
 * @category  Payone
20
 * @package   Payone_Magento2_Plugin
21
 * @author    FATCHIP GmbH <[email protected]>
22
 * @copyright 2003 - 2016 Payone GmbH
23
 * @license   <http://www.gnu.org/licenses/> GNU Lesser General Public License
24
 * @link      http://www.payone.de
25
 */
26
27
namespace Payone\Core\Helper;
28
29
use Magento\Framework\DataObject;
0 ignored issues
show
Bug introduced by
The type Magento\Framework\DataObject was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
30
use Magento\Sales\Model\Order as SalesOrder;
0 ignored issues
show
Bug introduced by
The type Magento\Sales\Model\Order was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
31
use Magento\Store\Model\Store;
0 ignored issues
show
Bug introduced by
The type Magento\Store\Model\Store was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
32
use Payone\Core\Model\Methods\PayoneMethod;
33
use Magento\Framework\Exception\LocalizedException;
0 ignored issues
show
Bug introduced by
The type Magento\Framework\Exception\LocalizedException was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
34
35
/**
36
 * Toolkit class for methods that dont fit in a certain drawer
37
 */
38
class Toolkit extends \Payone\Core\Helper\Base
39
{
40
    /**
41
     * PAYONE payment helper
42
     *
43
     * @var \Payone\Core\Helper\Payment
44
     */
45
    protected $paymentHelper;
46
47
    /**
48
     * Constructor
49
     *
50
     * @param \Magento\Framework\App\Helper\Context      $context
51
     * @param \Magento\Store\Model\StoreManagerInterface $storeManager
52
     * @param \Payone\Core\Helper\Payment                $paymentHelper
53
     * @param \Payone\Core\Helper\Shop                   $shopHelper
54
     * @param \Magento\Framework\App\State               $state
55
     */
56
    public function __construct(
57
        \Magento\Framework\App\Helper\Context $context,
0 ignored issues
show
Bug introduced by
The type Magento\Framework\App\Helper\Context was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
58
        \Magento\Store\Model\StoreManagerInterface $storeManager,
0 ignored issues
show
Bug introduced by
The type Magento\Store\Model\StoreManagerInterface was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
59
        \Payone\Core\Helper\Payment $paymentHelper,
60
        \Payone\Core\Helper\Shop $shopHelper,
61
        \Magento\Framework\App\State $state
0 ignored issues
show
Bug introduced by
The type Magento\Framework\App\State was not found. Maybe you did not declare it correctly or list all dependencies?

The issue could also be caused by a filter entry in the build configuration. If the path has been excluded in your configuration, e.g. excluded_paths: ["lib/*"], you can move it to the dependency path list as follows:

filter:
    dependency_paths: ["lib/*"]

For further information see https://scrutinizer-ci.com/docs/tools/php/php-scrutinizer/#list-dependency-paths

Loading history...
62
    ) {
63
        parent::__construct($context, $storeManager, $shopHelper, $state);
64
        $this->paymentHelper = $paymentHelper;
65
    }
66
67
    /**
68
     * Get security keys for all payment types for the given store code
69
     *
70
     * @param  string $sStoreCode
71
     * @return array
72
     */
73
    protected function getAllPayoneSecurityKeysByStoreCode($sStoreCode)
74
    {
75
        $aKeys = [];
76
        foreach ($this->paymentHelper->getAvailablePaymentTypes() as $sPaymentCode) {
77
            $iUseGlobal = $this->getConfigParam('use_global', $sPaymentCode, 'payone_payment', $sStoreCode);
78
            if ($iUseGlobal == '0') {
79
                $aKeys[] = $this->getConfigParam('key', $sPaymentCode, 'payone_payment', $sStoreCode);
80
            }
81
        }
82
        return $aKeys;
83
    }
84
85
    /**
86
     * Get the configured security keys for all available stores
87
     * and payment types - since every payment-type can have its own
88
     *
89
     * @return array
90
     */
91
    public function getAllPayoneSecurityKeys()
92
    {
93
        $aKeys = $this->getConfigParamAllStores('key');
94
        $aShopIds = $this->storeManager->getStores(false, true);
95
        foreach ($aShopIds as $sStoreCode => $oStore) {
96
            $aKeys = array_merge($aKeys, $this->getAllPayoneSecurityKeysByStoreCode($sStoreCode));
97
        }
98
        return array_unique($aKeys);
99
    }
100
101
    /**
102
     * Check wheither the given key is configured in the shop and thus valid
103
     *
104
     * @param  string $sKey
105
     * @return bool
106
     */
107
    public function isKeyValid($sKey)
108
    {
109
        $aKeyValues = $this->getAllPayoneSecurityKeys();
110
        foreach ($aKeyValues as $sConfigKey) {
111
            if ($this->hashString($sConfigKey ?? '', 'md5') == $sKey) {
112
                return true;
113
            }
114
        }
115
        return false;
116
    }
117
118
    /**
119
     * Replace substitutes in a given text with the given replacements
120
     *
121
     * @param  string   $sText
122
     * @param  array    $aSubstitutionArray
123
     * @param  int|bool $iMaxLength
124
     * @return string
125
     */
126
    public function handleSubstituteReplacement($sText, $aSubstitutionArray, $iMaxLength = false)
127
    {
128
        if (!empty($sText)) {
129
            $sText = str_replace(['{{', '}}'], ['{', '}'], $sText); // backwards compatibility for changes in MAG2-248
130
            $sText = str_replace(array_keys($aSubstitutionArray), array_values($aSubstitutionArray), $sText);
131
            if ($iMaxLength !== false && strlen($sText) > $iMaxLength) {
132
                $sText = substr($sText, 0, $iMaxLength); // shorten text if too long
0 ignored issues
show
Bug introduced by
It seems like $iMaxLength can also be of type true; however, parameter $length of substr() does only seem to accept integer|null, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

132
                $sText = substr($sText, 0, /** @scrutinizer ignore-type */ $iMaxLength); // shorten text if too long
Loading history...
133
            }
134
            return $sText;
135
        }
136
        return '';
137
    }
138
139
    /**
140
     * Get substituted invoice appendix text
141
     *
142
     * @param  SalesOrder $oOrder
143
     * @return string
144
     */
145
    public function getInvoiceAppendix(SalesOrder $oOrder)
146
    {
147
        $sText = $this->getConfigParam('invoice_appendix', 'invoicing'); // get invoice appendix from config
148
        $aSubstitutionArray = [
149
            '{order_increment_id}' => $oOrder->getIncrementId(),
150
            '{customer_id}' => $oOrder->getCustomerId(),
151
        ];
152
        $sInvoiceAppendix = $this->handleSubstituteReplacement($sText, $aSubstitutionArray, 255);
153
        return $sInvoiceAppendix;
154
    }
155
156
    /**
157
     * Returns narrative text for authorization request
158
     *
159
     * @param  SalesOrder   $oOrder
160
     * @param  PayoneMethod $oPayment
161
     * @return string
162
     */
163
    public function getNarrativeText(SalesOrder $oOrder, PayoneMethod $oPayment)
164
    {
165
        $sText = $this->getConfigParam('narrative_text', $oPayment->getCode(), 'payone_payment'); // get narrative text for payment from config
166
        $aSubstitutionArray = [
167
            '{order_increment_id}' => $oOrder->getIncrementId(),
168
        ];
169
        $sNarrativeText = $this->handleSubstituteReplacement($sText, $aSubstitutionArray, $oPayment->getNarrativeTextMaxLength());
170
        return $sNarrativeText;
171
    }
172
173
    /**
174
     * Format a price to the XX.YY format
175
     *
176
     * @param  double $dPrice    price of any sort
177
     * @param  int    $iDecimals number of digits behind the decimal point
178
     * @return string
179
     */
180
    public function formatNumber($dPrice, $iDecimals = 2)
181
    {
182
        return number_format($dPrice, $iDecimals, '.', '');
183
    }
184
185
    /**
186
     * Masks IBAN
187
     *
188
     * @param string $sUnmasked
189
     * @return string
190
     */
191
    public function maskIban($sUnmasked)
192
    {
193
        $sMasked = '';
194
        for ($i = 0; $i < strlen($sUnmasked); $i++) {
195
            if ($i == 2 || ((strlen($sUnmasked) - 2) % 4 == 0 && (($i - 2) % 4 == 0))) {
196
                $sMasked .= ' ';
197
            }
198
199
            if ($i < 4 || $i >= (strlen($sUnmasked) - 4)) {
200
                $sMasked .= $sUnmasked[$i];
201
            } else {
202
                $sMasked .= 'x';
203
            }
204
        }
205
        return $sMasked;
206
    }
207
208
    /**
209
     * Checks if given string is utf8 encoded
210
     *
211
     * @param  string $sString
212
     * @return bool
213
     */
214
    public function isUTF8($sString)
215
    {
216
        return $sString === mb_convert_encoding(mb_convert_encoding($sString ?? '', "UTF-32", "UTF-8"), "UTF-8", "UTF-32");
217
    }
218
219
    /**
220
     * Return data from data-object
221
     * Needed because of different ways to read from it for different magento versions
222
     *
223
     * @param  DataObject $oData
224
     * @param  string     $sKey
225
     * @return string|null
226
     */
227
    public function getAdditionalDataEntry(DataObject $oData, $sKey)
228
    {
229
        // The way to read the form-parameters changed with version 2.0.6
230
        if (version_compare($this->shopHelper->getMagentoVersion(), '2.0.6', '>=')) { // Magento 2.0.6 and above
231
            $aAdditionalData = $oData->getAdditionalData();
232
            if (isset($aAdditionalData[$sKey])) {
233
                return $aAdditionalData[$sKey];
234
            }
235
            return null;
236
        }
237
        // everything below 2.0.6
238
        return $oData->getData($sKey);
239
    }
240
241
    /**
242
     * Generates a Universally Unique Identifier (UUID)
243
     *
244
     * @return string
245
     * @throws \Exception
246
     */
247
    public function generateUUIDv4()
248
    {
249
        // Generate 16 bytes (128 bits) of random data or use the data passed into the function.
250
        $data = random_bytes(16);
251
        assert(strlen($data) == 16);
252
253
        // Set version to 0100
254
        $data[6] = chr(ord($data[6]) & 0x0f | 0x40);
255
        // Set bits 6-7 to 10
256
        $data[8] = chr(ord($data[8]) & 0x3f | 0x80);
257
258
        // Output the 36 character UUID.
259
        return vsprintf('%s%s-%s-%s-%s-%s%s%s', str_split(bin2hex($data), 4));
0 ignored issues
show
Bug introduced by
It seems like str_split(bin2hex($data), 4) can also be of type true; however, parameter $values of vsprintf() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

259
        return vsprintf('%s%s-%s-%s-%s-%s%s%s', /** @scrutinizer ignore-type */ str_split(bin2hex($data), 4));
Loading history...
260
    }
261
262
    /**
263
     * In the Payone universe different hash mechanisms are needed
264
     * Returns a hashed string and defines a default through the sAlgorithm parameter
265
     *
266
     * @param  string $sString
267
     * @param  string $sAlgorithm
268
     * @param  string $sKey
269
     * @return string
270
     */
271
    public function hashString($sString, $sAlgorithm = 'sha384', $sKey = false)
272
    {
273
        if ($sAlgorithm == "sha384" && $sKey !== false) {
274
            return hash_hmac($sAlgorithm, $sString, $sKey ?? '');
275
        }
276
        return hash($sAlgorithm, $sString);
277
    }
278
}
279