1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
namespace Magento\Quote\Model;
use Magento\Directory\Model\AllowedCountries;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Message\Error;
use Magento\Quote\Model\Quote as QuoteEntity;
use Magento\Quote\Model\Quote\Validator\MinimumOrderAmount\ValidationMessage as OrderAmountValidationMessage;
use Magento\Quote\Model\ValidationRules\QuoteValidationRuleInterface;
/**
* Class to validate the quote
*
* @api
* @since 100.0.2
*/
class QuoteValidator
{
/**
* Maximum available number
*/
const MAXIMUM_AVAILABLE_NUMBER = 10000000000000000;
/**
* @var AllowedCountries
*/
private $allowedCountryReader;
/**
* @var OrderAmountValidationMessage
*/
private $minimumAmountMessage;
/**
* @var QuoteValidationRuleInterface
*/
private $quoteValidationRule;
/**
* QuoteValidator constructor.
*
* @param AllowedCountries|null $allowedCountryReader
* @param OrderAmountValidationMessage|null $minimumAmountMessage
* @param QuoteValidationRuleInterface|null $quoteValidationRule
*/
public function __construct(
AllowedCountries $allowedCountryReader = null,
OrderAmountValidationMessage $minimumAmountMessage = null,
QuoteValidationRuleInterface $quoteValidationRule = null
) {
$this->allowedCountryReader = $allowedCountryReader ?: ObjectManager::getInstance()
->get(AllowedCountries::class);
$this->minimumAmountMessage = $minimumAmountMessage ?: ObjectManager::getInstance()
->get(OrderAmountValidationMessage::class);
$this->quoteValidationRule = $quoteValidationRule ?: ObjectManager::getInstance()
->get(QuoteValidationRuleInterface::class);
}
/**
* Validate quote amount
*
* @param QuoteEntity $quote
* @param float $amount
* @return $this
*/
public function validateQuoteAmount(QuoteEntity $quote, $amount)
{
if (!$quote->getHasError() && $amount >= self::MAXIMUM_AVAILABLE_NUMBER) {
$quote->setHasError(true);
$quote->addMessage(__('This item price or quantity is not valid for checkout.'));
}
return $this;
}
/**
* Validates quote before submit.
*
* @param Quote $quote
* @return $this
* @throws LocalizedException
*/
public function validateBeforeSubmit(QuoteEntity $quote)
{
if ($quote->getHasError()) {
$errors = $this->getQuoteErrors($quote);
throw new LocalizedException(__($errors ?: 'Something went wrong. Please try to place the order again.'));
}
foreach ($this->quoteValidationRule->validate($quote) as $validationResult) {
if ($validationResult->isValid()) {
continue;
}
$messages = $validationResult->getErrors();
$defaultMessage = array_shift($messages);
if ($defaultMessage && !empty($messages)) {
$defaultMessage .= ' %1';
}
if ($defaultMessage) {
throw new LocalizedException(__($defaultMessage, implode(' ', $messages)));
}
}
return $this;
}
/**
* Parses quote error messages and concatenates them into single string.
*
* @param Quote $quote
* @return string
*/
private function getQuoteErrors(QuoteEntity $quote): string
{
$errors = array_map(
function (Error $error) {
return $error->getText();
},
$quote->getErrors()
);
return implode(PHP_EOL, $errors);
}
}