AbstractModel.php 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Catalog\Model;
  7. use Magento\Framework\Api\AttributeValueFactory;
  8. /**
  9. * Abstract model for catalog entities
  10. * @api
  11. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  12. * @author Magento Core Team <core@magentocommerce.com>
  13. * @since 100.0.2
  14. */
  15. abstract class AbstractModel extends \Magento\Framework\Model\AbstractExtensibleModel
  16. {
  17. /**
  18. * Attribute default values
  19. *
  20. * This array contain default values for attributes which was redefine
  21. * value for store
  22. *
  23. * @var array|null
  24. */
  25. protected $_defaultValues;
  26. /**
  27. * This array contains codes of attributes which have value in current store
  28. *
  29. * @var array|null
  30. */
  31. protected $_storeValuesFlags;
  32. /**
  33. * Locked attributes
  34. *
  35. * @var array
  36. */
  37. protected $_lockedAttributes = [];
  38. /**
  39. * Is model deleteable
  40. *
  41. * @var boolean
  42. */
  43. protected $_isDeleteable = true;
  44. /**
  45. * Is model readonly
  46. *
  47. * @var boolean
  48. */
  49. protected $_isReadonly = false;
  50. /**
  51. * Store manager
  52. *
  53. * @var \Magento\Store\Model\StoreManagerInterface
  54. */
  55. protected $_storeManager;
  56. /**
  57. * @var \Magento\Catalog\Model\Attribute\ScopeOverriddenValue
  58. */
  59. private $scopeOverriddenValue;
  60. /**
  61. * @param \Magento\Framework\Model\Context $context
  62. * @param \Magento\Framework\Registry $registry
  63. * @param \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory
  64. * @param AttributeValueFactory $customAttributeFactory
  65. * @param \Magento\Store\Model\StoreManagerInterface $storeManager
  66. * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
  67. * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
  68. * @param array $data
  69. */
  70. public function __construct(
  71. \Magento\Framework\Model\Context $context,
  72. \Magento\Framework\Registry $registry,
  73. \Magento\Framework\Api\ExtensionAttributesFactory $extensionFactory,
  74. AttributeValueFactory $customAttributeFactory,
  75. \Magento\Store\Model\StoreManagerInterface $storeManager,
  76. \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
  77. \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
  78. array $data = []
  79. ) {
  80. $this->_storeManager = $storeManager;
  81. parent::__construct(
  82. $context,
  83. $registry,
  84. $extensionFactory,
  85. $customAttributeFactory,
  86. $resource,
  87. $resourceCollection,
  88. $data
  89. );
  90. }
  91. /**
  92. * Lock attribute
  93. *
  94. * @param string $attributeCode
  95. * @return $this
  96. */
  97. public function lockAttribute($attributeCode)
  98. {
  99. $this->_lockedAttributes[$attributeCode] = true;
  100. return $this;
  101. }
  102. /**
  103. * Unlock attribute
  104. *
  105. * @param string $attributeCode
  106. * @return $this
  107. */
  108. public function unlockAttribute($attributeCode)
  109. {
  110. if ($this->isLockedAttribute($attributeCode)) {
  111. unset($this->_lockedAttributes[$attributeCode]);
  112. }
  113. return $this;
  114. }
  115. /**
  116. * Unlock all attributes
  117. *
  118. * @return $this
  119. */
  120. public function unlockAttributes()
  121. {
  122. $this->_lockedAttributes = [];
  123. return $this;
  124. }
  125. /**
  126. * Retrieve locked attributes
  127. *
  128. * @return array
  129. */
  130. public function getLockedAttributes()
  131. {
  132. return array_keys($this->_lockedAttributes);
  133. }
  134. /**
  135. * Checks that model have locked attributes
  136. *
  137. * @return boolean
  138. */
  139. public function hasLockedAttributes()
  140. {
  141. return !empty($this->_lockedAttributes);
  142. }
  143. /**
  144. * Retrieve locked attributes
  145. *
  146. * @param mixed $attributeCode
  147. * @return boolean
  148. */
  149. public function isLockedAttribute($attributeCode)
  150. {
  151. return isset($this->_lockedAttributes[$attributeCode]);
  152. }
  153. /**
  154. * Overwrite data in the object.
  155. *
  156. * The $key can be string or array.
  157. * If $key is string, the attribute value will be overwritten by $value
  158. *
  159. * If $key is an array, it will overwrite all the data in the object.
  160. *
  161. * $isChanged will specify if the object needs to be saved after an update.
  162. *
  163. * @param string|array $key
  164. * @param mixed $value
  165. * @return $this
  166. */
  167. public function setData($key, $value = null)
  168. {
  169. if ($this->hasLockedAttributes()) {
  170. if (is_array($key)) {
  171. foreach ($this->getLockedAttributes() as $attribute) {
  172. if (isset($key[$attribute])) {
  173. unset($key[$attribute]);
  174. }
  175. }
  176. } elseif ($this->isLockedAttribute($key)) {
  177. return $this;
  178. }
  179. } elseif ($this->isReadonly()) {
  180. return $this;
  181. }
  182. return parent::setData($key, $value);
  183. }
  184. /**
  185. * Unset data from the object.
  186. *
  187. * The $key can be a string only. Array will be ignored.
  188. *
  189. * $isChanged will specify if the object needs to be saved after an update.
  190. *
  191. * @param string $key
  192. * @return $this
  193. */
  194. public function unsetData($key = null)
  195. {
  196. if ($key !== null && $this->isLockedAttribute($key) || $this->isReadonly()) {
  197. return $this;
  198. }
  199. return parent::unsetData($key);
  200. }
  201. /**
  202. * Get collection instance
  203. *
  204. * @return \Magento\Catalog\Model\ResourceModel\Collection\AbstractCollection
  205. * @deprecated 102.0.0 because collections should be used directly via factory
  206. */
  207. public function getResourceCollection()
  208. {
  209. $collection = parent::getResourceCollection()->setStoreId($this->getStoreId());
  210. return $collection;
  211. }
  212. /**
  213. * Load entity by attribute
  214. *
  215. * @param \Magento\Eav\Model\Entity\Attribute\AttributeInterface|integer|string|array $attribute
  216. * @param null|string|array $value
  217. * @param string $additionalAttributes
  218. * @return bool|\Magento\Catalog\Model\AbstractModel
  219. */
  220. public function loadByAttribute($attribute, $value, $additionalAttributes = '*')
  221. {
  222. $collection = $this->getResourceCollection()->addAttributeToSelect(
  223. $additionalAttributes
  224. )->addAttributeToFilter(
  225. $attribute,
  226. $value
  227. )->setPage(
  228. 1,
  229. 1
  230. );
  231. foreach ($collection as $object) {
  232. return $object;
  233. }
  234. return false;
  235. }
  236. /**
  237. * Retrieve sore object
  238. *
  239. * @return \Magento\Store\Model\Store
  240. */
  241. public function getStore()
  242. {
  243. return $this->_storeManager->getStore($this->getStoreId());
  244. }
  245. /**
  246. * Retrieve all store ids of object current website
  247. *
  248. * @return array
  249. */
  250. public function getWebsiteStoreIds()
  251. {
  252. return $this->getStore()->getWebsite()->getStoreIds(true);
  253. }
  254. /**
  255. * Adding attribute code and value to default value registry
  256. *
  257. * Default value existing is flag for using store value in data
  258. *
  259. * @param string $attributeCode
  260. * @param mixed $value
  261. * @return $this
  262. *
  263. * @deprecated 101.0.0
  264. */
  265. public function setAttributeDefaultValue($attributeCode, $value)
  266. {
  267. $this->_defaultValues[$attributeCode] = $value;
  268. return $this;
  269. }
  270. /**
  271. * Get attribute scope overridden value instance
  272. *
  273. * @return \Magento\Catalog\Model\Attribute\ScopeOverriddenValue
  274. *
  275. * @deprecated 101.0.0
  276. */
  277. private function getAttributeScopeOverriddenValue()
  278. {
  279. if ($this->scopeOverriddenValue === null) {
  280. $this->scopeOverriddenValue = \Magento\Framework\App\ObjectManager::getInstance()
  281. ->get(\Magento\Catalog\Model\Attribute\ScopeOverriddenValue::class);
  282. }
  283. return $this->scopeOverriddenValue;
  284. }
  285. /**
  286. * Retrieve default value for attribute code
  287. *
  288. * @param string $attributeCode
  289. * @return array|boolean
  290. *
  291. * @deprecated 101.0.0
  292. */
  293. public function getAttributeDefaultValue($attributeCode)
  294. {
  295. if ($this->_defaultValues === null) {
  296. $entityType = [
  297. \Magento\Catalog\Model\Product::ENTITY => \Magento\Catalog\Api\Data\ProductInterface::class,
  298. \Magento\Catalog\Model\Category::ENTITY => \Magento\Catalog\Api\Data\CategoryInterface::class,
  299. ][$this->getResource()->getEntityType()->getEntityTypeCode()];
  300. $this->_defaultValues = $this->getAttributeScopeOverriddenValue()->getDefaultValues($entityType, $this);
  301. }
  302. return array_key_exists($attributeCode, $this->_defaultValues) ? $this->_defaultValues[$attributeCode] : false;
  303. }
  304. /**
  305. * Set attribute code flag if attribute has value in current store and does not use value of default store as value
  306. *
  307. * @param string $attributeCode
  308. * @return $this
  309. *
  310. * @deprecated 101.0.0
  311. */
  312. public function setExistsStoreValueFlag($attributeCode)
  313. {
  314. $this->_storeValuesFlags[$attributeCode] = true;
  315. return $this;
  316. }
  317. /**
  318. * Check if object attribute has value in current store
  319. *
  320. * @param string $attributeCode
  321. * @return bool
  322. * @SuppressWarnings(PHPMD.BooleanGetMethodName)
  323. *
  324. * @deprecated 101.0.0
  325. */
  326. public function getExistsStoreValueFlag($attributeCode)
  327. {
  328. if ($this->_storeValuesFlags === null) {
  329. $entityType = [
  330. \Magento\Catalog\Model\Product::ENTITY => \Magento\Catalog\Api\Data\ProductInterface::class,
  331. \Magento\Catalog\Model\Category::ENTITY => \Magento\Catalog\Api\Data\CategoryInterface::class,
  332. ][$this->getResource()->getEntityType()->getEntityTypeCode()];
  333. return $this->getAttributeScopeOverriddenValue()->containsValue(
  334. $entityType,
  335. $this,
  336. $attributeCode,
  337. $this->getStore()->getId()
  338. );
  339. }
  340. return array_key_exists($attributeCode, $this->_storeValuesFlags);
  341. }
  342. /**
  343. * Before save unlock attributes
  344. *
  345. * @return \Magento\Catalog\Model\AbstractModel
  346. */
  347. public function beforeSave()
  348. {
  349. $this->unlockAttributes();
  350. return parent::beforeSave();
  351. }
  352. /**
  353. * Checks model is deletable
  354. *
  355. * @return boolean
  356. */
  357. public function isDeleteable()
  358. {
  359. return $this->_isDeleteable;
  360. }
  361. /**
  362. * Set is deletable flag
  363. *
  364. * @param boolean $value
  365. * @return $this
  366. */
  367. public function setIsDeleteable($value)
  368. {
  369. $this->_isDeleteable = (bool)$value;
  370. return $this;
  371. }
  372. /**
  373. * Checks model is deletable
  374. *
  375. * @return boolean
  376. */
  377. public function isReadonly()
  378. {
  379. return $this->_isReadonly;
  380. }
  381. /**
  382. * Set is deletable flag
  383. *
  384. * @param boolean $value
  385. * @return $this
  386. */
  387. public function setIsReadonly($value)
  388. {
  389. $this->_isReadonly = (bool)$value;
  390. return $this;
  391. }
  392. }