Data.php 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. /**
  7. * EAV attribute data validator
  8. *
  9. * @author Magento Core Team <core@magentocommerce.com>
  10. */
  11. namespace Magento\Eav\Model\Validator\Attribute;
  12. use Magento\Eav\Model\Attribute;
  13. class Data extends \Magento\Framework\Validator\AbstractValidator
  14. {
  15. /**
  16. * @var array
  17. */
  18. protected $_attributes = [];
  19. /**
  20. * @var array
  21. */
  22. protected $_attributesWhiteList = [];
  23. /**
  24. * @var array
  25. */
  26. protected $_attributesBlackList = [];
  27. /**
  28. * @var array
  29. */
  30. protected $_data = [];
  31. /**
  32. * @var \Magento\Eav\Model\AttributeDataFactory
  33. */
  34. protected $_attrDataFactory;
  35. /**
  36. * @param \Magento\Eav\Model\AttributeDataFactory $attrDataFactory
  37. */
  38. public function __construct(\Magento\Eav\Model\AttributeDataFactory $attrDataFactory)
  39. {
  40. $this->_attrDataFactory = $attrDataFactory;
  41. }
  42. /**
  43. * Set list of attributes for validation in isValid method.
  44. *
  45. * @param Attribute[] $attributes
  46. * @return $this
  47. */
  48. public function setAttributes(array $attributes)
  49. {
  50. $this->_attributes = $attributes;
  51. return $this;
  52. }
  53. /**
  54. * Set codes of attributes that should be filtered in validation process.
  55. *
  56. * All attributes not in this list 't be involved in validation.
  57. *
  58. * @param array $attributesCodes
  59. * @return $this
  60. */
  61. public function setAttributesWhiteList(array $attributesCodes)
  62. {
  63. $this->_attributesWhiteList = $attributesCodes;
  64. return $this;
  65. }
  66. /**
  67. * Set codes of attributes that should be excluded in validation process.
  68. *
  69. * All attributes in this list won't be involved in validation.
  70. *
  71. * @param array $attributesCodes
  72. * @return $this
  73. */
  74. public function setAttributesBlackList(array $attributesCodes)
  75. {
  76. $this->_attributesBlackList = $attributesCodes;
  77. return $this;
  78. }
  79. /**
  80. * Set data for validation in isValid method.
  81. *
  82. * @param array $data
  83. * @return $this
  84. */
  85. public function setData(array $data)
  86. {
  87. $this->_data = $data;
  88. return $this;
  89. }
  90. /**
  91. * Validate EAV model attributes with data models
  92. *
  93. * @param \Magento\Framework\Model\AbstractModel $entity
  94. * @return bool
  95. */
  96. public function isValid($entity)
  97. {
  98. /** @var $attributes Attribute[] */
  99. $attributes = $this->_getAttributes($entity);
  100. $data = [];
  101. if ($this->_data) {
  102. $data = $this->_data;
  103. } elseif ($entity instanceof \Magento\Framework\DataObject) {
  104. $data = $entity->getData();
  105. }
  106. foreach ($attributes as $attribute) {
  107. $attributeCode = $attribute->getAttributeCode();
  108. if (!$attribute->getDataModel() && !$attribute->getFrontendInput()) {
  109. continue;
  110. }
  111. $dataModel = $this->_attrDataFactory->create($attribute, $entity);
  112. $dataModel->setExtractedData($data);
  113. if (!isset($data[$attributeCode])) {
  114. $data[$attributeCode] = null;
  115. }
  116. $result = $dataModel->validateValue($data[$attributeCode]);
  117. if (true !== $result) {
  118. $this->_addErrorMessages($attributeCode, (array)$result);
  119. }
  120. }
  121. return count($this->_messages) == 0;
  122. }
  123. /**
  124. * Get attributes involved in validation.
  125. *
  126. * This method return specified $_attributes if they defined by setAttributes method, otherwise if $entity
  127. * is EAV-model it returns it's all available attributes, otherwise it return empty array.
  128. *
  129. * @param \Magento\Framework\Model\AbstractModel $entity
  130. * @return array
  131. */
  132. protected function _getAttributes($entity)
  133. {
  134. /** @var \Magento\Eav\Model\Attribute[] $attributes */
  135. $attributes = [];
  136. if ($this->_attributes) {
  137. $attributes = $this->_attributes;
  138. } elseif ($entity instanceof \Magento\Framework\Model\AbstractModel &&
  139. $entity->getResource() instanceof \Magento\Eav\Model\Entity\AbstractEntity
  140. ) { // $entity is EAV-model
  141. /** @var \Magento\Eav\Model\Entity\Type $entityType */
  142. $entityType = $entity->getEntityType();
  143. $attributes = $entityType->getAttributeCollection()->getItems();
  144. }
  145. $attributesByCode = [];
  146. $attributesCodes = [];
  147. foreach ($attributes as $attribute) {
  148. if (!$attribute->getIsVisible()) {
  149. continue;
  150. }
  151. $attributeCode = $attribute->getAttributeCode();
  152. $attributesByCode[$attributeCode] = $attribute;
  153. $attributesCodes[] = $attributeCode;
  154. }
  155. $ignoreAttributes = $this->_attributesBlackList;
  156. if ($this->_attributesWhiteList) {
  157. $ignoreAttributes = array_merge(
  158. $ignoreAttributes,
  159. array_diff($attributesCodes, $this->_attributesWhiteList)
  160. );
  161. }
  162. foreach ($ignoreAttributes as $attributeCode) {
  163. unset($attributesByCode[$attributeCode]);
  164. }
  165. return $attributesByCode;
  166. }
  167. /**
  168. * Add error messages
  169. *
  170. * @param string $code
  171. * @param array $messages
  172. * @return void
  173. */
  174. protected function _addErrorMessages($code, array $messages)
  175. {
  176. if (!array_key_exists($code, $this->_messages)) {
  177. $this->_messages[$code] = $messages;
  178. } else {
  179. $this->_messages[$code] = array_merge($this->_messages[$code], $messages);
  180. }
  181. }
  182. }