8
8
namespace Magento \QuoteGraphQl \Plugin ;
9
9
10
10
use Magento \Catalog \Model \ResourceModel \Product \Attribute \CollectionFactory as AttributeCollectionFactory ;
11
- use Magento \Eav \Model \Validator \Attribute \Code ;
12
- use Magento \Framework \App \ObjectManager ;
13
11
use Magento \Framework \GraphQl \Query \Fields ;
12
+ use Magento \Framework \Validator \StringLength ;
14
13
use Magento \Framework \Validator \ValidateException ;
14
+ use Magento \Framework \Validator \ValidatorChain ;
15
15
use Magento \Quote \Model \Quote \Config as QuoteConfig ;
16
16
17
17
/**
18
18
* Class for extending product attributes for quote.
19
19
*/
20
20
class ProductAttributesExtender
21
21
{
22
+ /**
23
+ * Validation pattern for attribute code
24
+ */
25
+ private const VALIDATION_RULE_PATTERN = '/^[a-zA-Z]+[a-zA-Z0-9_]*$/u ' ;
26
+
27
+ private const ATTRIBUTE_CODE_MAX_LENGTH = 60 ;
28
+
29
+ private const ATTRIBUTE_CODE_MIN_LENGTH = 1 ;
30
+
22
31
/**
23
32
* @var Fields
24
33
*/
@@ -30,27 +39,29 @@ class ProductAttributesExtender
30
39
private $ attributeCollectionFactory ;
31
40
32
41
/**
33
- * @var Code
42
+ * @var string
43
+ */
44
+ private $ fieldsHash = '' ;
45
+
46
+ /**
47
+ * @var array
34
48
*/
35
- private Code $ attributeCodeValidator ;
49
+ private $ attributes ;
36
50
37
51
/**
38
52
* @param Fields $fields
39
53
* @param AttributeCollectionFactory $attributeCollectionFactory
40
- * @param Code|null $attributeCodeValidator
41
54
*/
42
55
public function __construct (
43
56
Fields $ fields ,
44
- AttributeCollectionFactory $ attributeCollectionFactory ,
45
- Code $ attributeCodeValidator = null
57
+ AttributeCollectionFactory $ attributeCollectionFactory
46
58
) {
47
59
$ this ->fields = $ fields ;
48
60
$ this ->attributeCollectionFactory = $ attributeCollectionFactory ;
49
- $ this ->attributeCodeValidator = $ attributeCodeValidator ?? ObjectManager::getInstance ()->get (Code::class);
50
61
}
51
62
52
63
/**
53
- * Get only attribute code that pass validation
64
+ * Get only attribute codes that pass validation
54
65
*
55
66
* @return array
56
67
*/
@@ -60,31 +71,66 @@ private function getValidatedAttributeCodes(): array
60
71
}
61
72
62
73
/**
63
- * @param string|int $code
74
+ * Validate attribute code
75
+ *
76
+ * @param string|int $attributeCode
64
77
* @return bool
65
78
* @throws ValidateException
66
79
*/
67
- private function validateAttributeCode (string |int $ code )
80
+ private function validateAttributeCode (string |int $ attributeCode ): bool
68
81
{
69
- return $ this ->attributeCodeValidator ->isValid ((string )$ code );
82
+ $ attributeCode = trim ((string )$ attributeCode );
83
+ if (strlen ($ attributeCode ) > 0
84
+ && !preg_match (self ::VALIDATION_RULE_PATTERN , $ attributeCode )
85
+ ) {
86
+ return false ;
87
+ }
88
+
89
+ $ minLength = self ::ATTRIBUTE_CODE_MIN_LENGTH ;
90
+ $ maxLength = self ::ATTRIBUTE_CODE_MAX_LENGTH ;
91
+ $ isAllowedLength = ValidatorChain::is (
92
+ $ attributeCode ,
93
+ StringLength::class,
94
+ ['min ' => $ minLength , 'max ' => $ maxLength ]
95
+ );
96
+ if (!$ isAllowedLength ) {
97
+ return false ;
98
+ }
99
+
100
+ return true ;
70
101
}
71
102
72
103
/**
73
- * Add requested product attributes.
104
+ * Get attributes collection based on validated codes
74
105
*
75
- * @param QuoteConfig $subject
76
- * @param array $result
77
106
* @return array
78
- * @SuppressWarnings(PHPMD.UnusedFormalParameter)
79
107
*/
80
- public function afterGetProductAttributes ( QuoteConfig $ subject , array $ result ): array
108
+ private function getAttributeCollection ()
81
109
{
82
110
$ attributeCollection = $ this ->attributeCollectionFactory ->create ()
83
111
->removeAllFieldsFromSelect ()
84
112
->addFieldToSelect ('attribute_code ' )
85
113
->setCodeFilter ($ this ->getValidatedAttributeCodes ())
86
114
->load ();
87
- $ attributes = $ attributeCollection ->getColumnValues ('attribute_code ' );
115
+ return $ attributeCollection ->getColumnValues ('attribute_code ' );
116
+ }
117
+
118
+ /**
119
+ * Add requested product attributes.
120
+ *
121
+ * @param QuoteConfig $subject
122
+ * @param array $result
123
+ * @return array
124
+ * @SuppressWarnings(PHPMD.UnusedFormalParameter)
125
+ */
126
+ public function afterGetProductAttributes (QuoteConfig $ subject , array $ result ): array
127
+ {
128
+ $ hash = hash ('sha256 ' , json_encode ($ this ->fields ->getFieldsUsedInQuery ()));
129
+ if (!$ this ->fieldsHash || $ this ->fieldsHash !== $ hash ) {
130
+ $ this ->fieldsHash = hash ('sha256 ' , json_encode ($ this ->fields ->getFieldsUsedInQuery ()));
131
+ $ this ->attributes = $ this ->getAttributeCollection ();
132
+ }
133
+ $ attributes = $ this ->attributes ;
88
134
89
135
return array_unique (array_merge ($ result , $ attributes ));
90
136
}
0 commit comments