AbstractModel.php 25 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Framework\Model;
  7. use Magento\Framework\Phrase;
  8. /**
  9. * Abstract model class
  10. *
  11. * @api
  12. * @SuppressWarnings(PHPMD.CouplingBetweenObjects)
  13. * @SuppressWarnings(PHPMD.NumberOfChildren)
  14. * @SuppressWarnings(PHPMD.TooManyFields)
  15. * @since 100.0.2
  16. */
  17. abstract class AbstractModel extends \Magento\Framework\DataObject
  18. {
  19. /**
  20. * Prefix of model events names
  21. *
  22. * @var string
  23. */
  24. protected $_eventPrefix = 'core_abstract';
  25. /**
  26. * Parameter name in event
  27. *
  28. * In observe method you can use $observer->getEvent()->getObject() in this case
  29. *
  30. * @var string
  31. */
  32. protected $_eventObject = 'object';
  33. /**
  34. * Name of object id field
  35. *
  36. * @var string
  37. */
  38. protected $_idFieldName = 'id';
  39. /**
  40. * Data changes flag (true after setData|unsetData call)
  41. * @var bool
  42. */
  43. protected $_hasDataChanges = false;
  44. /**
  45. * Original data that was loaded
  46. *
  47. * @var array
  48. */
  49. protected $_origData;
  50. /**
  51. * Object delete flag
  52. *
  53. * @var bool
  54. */
  55. protected $_isDeleted = false;
  56. /**
  57. * Resource model instance
  58. *
  59. * @var \Magento\Framework\Model\ResourceModel\Db\AbstractDb
  60. */
  61. protected $_resource;
  62. /**
  63. * Resource collection
  64. *
  65. * @var \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
  66. */
  67. protected $_resourceCollection;
  68. /**
  69. * Name of the resource model
  70. *
  71. * @var string
  72. */
  73. protected $_resourceName;
  74. /**
  75. * Name of the resource collection model
  76. *
  77. * @var string
  78. */
  79. protected $_collectionName;
  80. /**
  81. * Model cache tag for clear cache in after save and after delete
  82. *
  83. * When you use true - all cache will be clean
  84. *
  85. * @var string|array|bool
  86. */
  87. protected $_cacheTag = false;
  88. /**
  89. * Flag which can stop data saving after before save
  90. * Can be used for next sequence: we check data in _beforeSave, if data are
  91. * not valid - we can set this flag to false value and save process will be stopped
  92. *
  93. * @var bool
  94. */
  95. protected $_dataSaveAllowed = true;
  96. /**
  97. * Flag which allow detect object state: is it new object (without id) or existing one (with id)
  98. *
  99. * @var bool
  100. */
  101. protected $_isObjectNew = null;
  102. /**
  103. * Validator for checking the model state before saving it
  104. *
  105. * @var \Zend_Validate_Interface|bool|null
  106. */
  107. protected $_validatorBeforeSave = null;
  108. /**
  109. * Application Event Dispatcher
  110. *
  111. * @var \Magento\Framework\Event\ManagerInterface
  112. */
  113. protected $_eventManager;
  114. /**
  115. * Application Cache Manager
  116. *
  117. * @var \Magento\Framework\App\CacheInterface
  118. */
  119. protected $_cacheManager;
  120. /**
  121. * @var \Magento\Framework\Registry
  122. */
  123. protected $_registry;
  124. /**
  125. * @var \Psr\Log\LoggerInterface
  126. */
  127. protected $_logger;
  128. /**
  129. * @var \Magento\Framework\App\State
  130. */
  131. protected $_appState;
  132. /**
  133. * @var \Magento\Framework\Model\ActionValidator\RemoveAction
  134. */
  135. protected $_actionValidator;
  136. /**
  137. * Array to store object's original data
  138. *
  139. * @var array
  140. */
  141. protected $storedData = [];
  142. /**
  143. * @param \Magento\Framework\Model\Context $context
  144. * @param \Magento\Framework\Registry $registry
  145. * @param \Magento\Framework\Model\ResourceModel\AbstractResource $resource
  146. * @param \Magento\Framework\Data\Collection\AbstractDb $resourceCollection
  147. * @param array $data
  148. */
  149. public function __construct(
  150. \Magento\Framework\Model\Context $context,
  151. \Magento\Framework\Registry $registry,
  152. \Magento\Framework\Model\ResourceModel\AbstractResource $resource = null,
  153. \Magento\Framework\Data\Collection\AbstractDb $resourceCollection = null,
  154. array $data = []
  155. ) {
  156. $this->_registry = $registry;
  157. $this->_appState = $context->getAppState();
  158. $this->_eventManager = $context->getEventDispatcher();
  159. $this->_cacheManager = $context->getCacheManager();
  160. $this->_resource = $resource;
  161. $this->_resourceCollection = $resourceCollection;
  162. $this->_logger = $context->getLogger();
  163. $this->_actionValidator = $context->getActionValidator();
  164. if (method_exists($this->_resource, 'getIdFieldName')
  165. || $this->_resource instanceof \Magento\Framework\DataObject
  166. ) {
  167. $this->_idFieldName = $this->_getResource()->getIdFieldName();
  168. }
  169. parent::__construct($data);
  170. $this->_construct();
  171. }
  172. /**
  173. * Model construct that should be used for object initialization
  174. *
  175. * @return void
  176. */
  177. protected function _construct()
  178. {
  179. }
  180. /**
  181. * Standard model initialization
  182. *
  183. * @param string $resourceModel
  184. * @return void
  185. */
  186. protected function _init($resourceModel)
  187. {
  188. $this->_setResourceModel($resourceModel);
  189. $this->_idFieldName = $this->_getResource()->getIdFieldName();
  190. }
  191. /**
  192. * Remove unneeded properties from serialization
  193. *
  194. * @return string[]
  195. */
  196. public function __sleep()
  197. {
  198. $properties = array_keys(get_object_vars($this));
  199. $properties = array_diff(
  200. $properties,
  201. [
  202. '_eventManager',
  203. '_cacheManager',
  204. '_registry',
  205. '_appState',
  206. '_actionValidator',
  207. '_logger',
  208. '_resourceCollection',
  209. '_resource',
  210. ]
  211. );
  212. return $properties;
  213. }
  214. /**
  215. * Init not serializable fields
  216. *
  217. * @return void
  218. */
  219. public function __wakeup()
  220. {
  221. $objectManager = \Magento\Framework\App\ObjectManager::getInstance();
  222. $this->_registry = $objectManager->get(\Magento\Framework\Registry::class);
  223. $context = $objectManager->get(\Magento\Framework\Model\Context::class);
  224. if ($context instanceof \Magento\Framework\Model\Context) {
  225. $this->_appState = $context->getAppState();
  226. $this->_eventManager = $context->getEventDispatcher();
  227. $this->_cacheManager = $context->getCacheManager();
  228. $this->_logger = $context->getLogger();
  229. $this->_actionValidator = $context->getActionValidator();
  230. }
  231. }
  232. /**
  233. * Id field name setter
  234. *
  235. * @param string $name
  236. * @return $this
  237. */
  238. public function setIdFieldName($name)
  239. {
  240. $this->_idFieldName = $name;
  241. return $this;
  242. }
  243. /**
  244. * Id field name getter
  245. *
  246. * @return string
  247. */
  248. public function getIdFieldName()
  249. {
  250. return $this->_idFieldName;
  251. }
  252. /**
  253. * Identifier getter
  254. *
  255. * @return mixed
  256. */
  257. public function getId()
  258. {
  259. return $this->_getData($this->_idFieldName);
  260. }
  261. /**
  262. * Identifier setter
  263. *
  264. * @param mixed $value
  265. * @return $this
  266. */
  267. public function setId($value)
  268. {
  269. $this->setData($this->_idFieldName, $value);
  270. return $this;
  271. }
  272. /**
  273. * Set _isDeleted flag value (if $isDeleted parameter is defined) and return current flag value
  274. *
  275. * @param boolean $isDeleted
  276. * @return bool
  277. */
  278. public function isDeleted($isDeleted = null)
  279. {
  280. $result = $this->_isDeleted;
  281. if ($isDeleted !== null) {
  282. $this->_isDeleted = $isDeleted;
  283. }
  284. return $result;
  285. }
  286. /**
  287. * Check if initial object data was changed.
  288. *
  289. * Initial data is coming to object constructor.
  290. * Flag value should be set up to true after any external data changes
  291. *
  292. * @return bool
  293. */
  294. public function hasDataChanges()
  295. {
  296. return $this->_hasDataChanges;
  297. }
  298. /**
  299. * Overwrite data in the object.
  300. *
  301. * The $key parameter can be string or array.
  302. * If $key is string, the attribute value will be overwritten by $value
  303. *
  304. * If $key is an array, it will overwrite all the data in the object.
  305. *
  306. * @param string|array $key
  307. * @param mixed $value
  308. * @return $this
  309. */
  310. public function setData($key, $value = null)
  311. {
  312. if ($key === (array)$key) {
  313. if ($this->_data !== $key) {
  314. $this->_hasDataChanges = true;
  315. }
  316. $this->_data = $key;
  317. } else {
  318. if (!array_key_exists($key, $this->_data) || $this->_data[$key] !== $value) {
  319. $this->_hasDataChanges = true;
  320. }
  321. $this->_data[$key] = $value;
  322. }
  323. return $this;
  324. }
  325. /**
  326. * Unset data from the object.
  327. *
  328. * @param null|string|array $key
  329. * @return $this
  330. */
  331. public function unsetData($key = null)
  332. {
  333. if ($key === null) {
  334. $this->setData([]);
  335. } elseif (is_string($key)) {
  336. if (isset($this->_data[$key]) || array_key_exists($key, $this->_data)) {
  337. $this->_hasDataChanges = true;
  338. unset($this->_data[$key]);
  339. }
  340. } elseif ($key === (array)$key) {
  341. foreach ($key as $element) {
  342. $this->unsetData($element);
  343. }
  344. }
  345. return $this;
  346. }
  347. /**
  348. * Clears data changes status
  349. *
  350. * @param bool $value
  351. * @return $this
  352. */
  353. public function setDataChanges($value)
  354. {
  355. $this->_hasDataChanges = (bool)$value;
  356. return $this;
  357. }
  358. /**
  359. * Get object original data
  360. *
  361. * @param string $key
  362. * @return mixed
  363. */
  364. public function getOrigData($key = null)
  365. {
  366. if ($key === null) {
  367. return $this->_origData;
  368. }
  369. if (isset($this->_origData[$key])) {
  370. return $this->_origData[$key];
  371. }
  372. return null;
  373. }
  374. /**
  375. * Initialize object original data
  376. *
  377. * @FIXME changing original data can't be available as public interface
  378. *
  379. * @param string $key
  380. * @param mixed $data
  381. * @return $this
  382. */
  383. public function setOrigData($key = null, $data = null)
  384. {
  385. if ($key === null) {
  386. $this->_origData = $this->_data;
  387. } else {
  388. $this->_origData[$key] = $data;
  389. }
  390. return $this;
  391. }
  392. /**
  393. * Compare object data with original data
  394. *
  395. * @param string $field
  396. * @return bool
  397. */
  398. public function dataHasChangedFor($field)
  399. {
  400. $newData = $this->getData($field);
  401. $origData = $this->getOrigData($field);
  402. return $newData != $origData;
  403. }
  404. /**
  405. * Set resource names
  406. *
  407. * If collection name is omitted, resource name will be used with _collection appended
  408. *
  409. * @param string $resourceName
  410. * @param string|null $collectionName
  411. * @return void
  412. */
  413. protected function _setResourceModel($resourceName, $collectionName = null)
  414. {
  415. $this->_resourceName = $resourceName;
  416. if ($collectionName === null) {
  417. $collectionName = $resourceName . '\\' . 'Collection';
  418. }
  419. $this->_collectionName = $collectionName;
  420. }
  421. /**
  422. * Get resource instance
  423. *
  424. * @throws \Magento\Framework\Exception\LocalizedException
  425. * @return \Magento\Framework\Model\ResourceModel\Db\AbstractDb
  426. * @deprecated 101.0.0 because resource models should be used directly
  427. */
  428. protected function _getResource()
  429. {
  430. if (empty($this->_resourceName) && empty($this->_resource)) {
  431. throw new \Magento\Framework\Exception\LocalizedException(
  432. new \Magento\Framework\Phrase('The resource isn\'t set.')
  433. );
  434. }
  435. return $this->_resource ?: \Magento\Framework\App\ObjectManager::getInstance()->get($this->_resourceName);
  436. }
  437. /**
  438. * Retrieve model resource name
  439. *
  440. * @return string
  441. */
  442. public function getResourceName()
  443. {
  444. return $this->_resource ? get_class($this->_resource) : ($this->_resourceName ? $this->_resourceName : null);
  445. }
  446. /**
  447. * Get collection instance
  448. *
  449. * @TODO MAGETWO-23541: Incorrect dependencies between Model\AbstractModel and Data\Collection\Db from Framework
  450. * @throws \Magento\Framework\Exception\LocalizedException
  451. * @return \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
  452. * @deprecated 101.0.0 because collections should be used directly via factory
  453. */
  454. public function getResourceCollection()
  455. {
  456. if (empty($this->_resourceCollection) && empty($this->_collectionName)) {
  457. throw new \Magento\Framework\Exception\LocalizedException(
  458. new \Magento\Framework\Phrase('Model collection resource name is not defined.')
  459. );
  460. }
  461. return $this->_resourceCollection ? clone $this
  462. ->_resourceCollection : \Magento\Framework\App\ObjectManager::getInstance()
  463. ->create(
  464. $this->_collectionName
  465. );
  466. }
  467. /**
  468. * Retrieve collection instance
  469. *
  470. * @TODO MAGETWO-23541: Incorrect dependencies between Model\AbstractModel and Data\Collection\Db from Framework
  471. * @return \Magento\Framework\Model\ResourceModel\Db\Collection\AbstractCollection
  472. * @deprecated 101.0.0 because collections should be used directly via factory
  473. */
  474. public function getCollection()
  475. {
  476. return $this->getResourceCollection();
  477. }
  478. /**
  479. * Load object data
  480. *
  481. * @param integer $modelId
  482. * @param null|string $field
  483. * @return $this
  484. * @deprecated 100.1.0 because entities must not be responsible for their own loading.
  485. * Service contracts should persist entities. Use resource model "load" or collections to implement
  486. * service contract model loading operations.
  487. */
  488. public function load($modelId, $field = null)
  489. {
  490. $this->_getResource()->load($this, $modelId, $field);
  491. return $this;
  492. }
  493. /**
  494. * Get array of objects transferred to default events processing
  495. *
  496. * @return array
  497. */
  498. protected function _getEventData()
  499. {
  500. return [
  501. 'data_object' => $this,
  502. $this->_eventObject => $this,
  503. ];
  504. }
  505. /**
  506. * Processing object before load data
  507. *
  508. * @param int $modelId
  509. * @param null|string $field
  510. * @return $this
  511. */
  512. protected function _beforeLoad($modelId, $field = null)
  513. {
  514. $params = ['object' => $this, 'field' => $field, 'value' => $modelId];
  515. $this->_eventManager->dispatch('model_load_before', $params);
  516. $params = array_merge($params, $this->_getEventData());
  517. $this->_eventManager->dispatch($this->_eventPrefix . '_load_before', $params);
  518. return $this;
  519. }
  520. /**
  521. * Processing object after load data
  522. *
  523. * @return $this
  524. */
  525. protected function _afterLoad()
  526. {
  527. $this->_eventManager->dispatch('model_load_after', ['object' => $this]);
  528. $this->_eventManager->dispatch($this->_eventPrefix . '_load_after', $this->_getEventData());
  529. return $this;
  530. }
  531. /**
  532. * Process operation before object load
  533. *
  534. * @param string $identifier
  535. * @param string|null $field
  536. * @return void
  537. * @since 101.0.0
  538. */
  539. public function beforeLoad($identifier, $field = null)
  540. {
  541. $this->_beforeLoad($identifier, $field);
  542. }
  543. /**
  544. * Object after load processing. Implemented as public interface for supporting objects after load in collections
  545. *
  546. * @return $this
  547. */
  548. public function afterLoad()
  549. {
  550. $this->_afterLoad();
  551. $this->updateStoredData();
  552. return $this;
  553. }
  554. /**
  555. * Check whether model has changed data.
  556. * Can be overloaded in child classes to perform advanced check whether model needs to be saved
  557. * e.g. using resourceModel->hasDataChanged() or any other technique
  558. *
  559. * @return boolean
  560. */
  561. protected function _hasModelChanged()
  562. {
  563. return $this->hasDataChanges();
  564. }
  565. /**
  566. * Check if save is allowed
  567. *
  568. * @return bool
  569. */
  570. public function isSaveAllowed()
  571. {
  572. return (bool) $this->_dataSaveAllowed;
  573. }
  574. /**
  575. * Set flag property _hasDataChanges
  576. *
  577. * @param bool $flag
  578. * @return void
  579. */
  580. public function setHasDataChanges($flag)
  581. {
  582. $this->_hasDataChanges = $flag;
  583. }
  584. /**
  585. * Save object data
  586. *
  587. * @return $this
  588. * @throws \Exception
  589. *
  590. * @deprecated 100.1.0 because entities must not be responsible for their own persistence.
  591. * Service contracts should persist entities. Use resource model "save" to implement
  592. * service contract persistence operations.
  593. */
  594. public function save()
  595. {
  596. $this->_getResource()->save($this);
  597. return $this;
  598. }
  599. /**
  600. * Callback function which called after transaction commit in resource model
  601. *
  602. * @return $this
  603. */
  604. public function afterCommitCallback()
  605. {
  606. $this->_eventManager->dispatch('model_save_commit_after', ['object' => $this]);
  607. $this->_eventManager->dispatch($this->_eventPrefix . '_save_commit_after', $this->_getEventData());
  608. return $this;
  609. }
  610. /**
  611. * Check object state (true - if it is object without id on object just created)
  612. * This method can help detect if object just created in _afterSave method
  613. * problem is what in after save object has id and we can't detect what object was
  614. * created in this transaction
  615. *
  616. * @param bool|null $flag
  617. * @return bool
  618. */
  619. public function isObjectNew($flag = null)
  620. {
  621. if ($flag !== null) {
  622. $this->_isObjectNew = $flag;
  623. }
  624. if ($this->_isObjectNew !== null) {
  625. return $this->_isObjectNew;
  626. }
  627. return !(bool)$this->getId();
  628. }
  629. /**
  630. * Processing object before save data
  631. *
  632. * @return $this
  633. */
  634. public function beforeSave()
  635. {
  636. if (!$this->getId()) {
  637. $this->isObjectNew(true);
  638. }
  639. $this->_eventManager->dispatch('model_save_before', ['object' => $this]);
  640. $this->_eventManager->dispatch($this->_eventPrefix . '_save_before', $this->_getEventData());
  641. return $this;
  642. }
  643. /**
  644. * Validate model before saving it
  645. *
  646. * @return $this
  647. * @throws \Magento\Framework\Validator\Exception
  648. */
  649. public function validateBeforeSave()
  650. {
  651. $validator = $this->_getValidatorBeforeSave();
  652. if ($validator && !$validator->isValid($this)) {
  653. $errors = $validator->getMessages();
  654. $exception = new \Magento\Framework\Validator\Exception(
  655. new Phrase(implode(PHP_EOL, $errors))
  656. );
  657. foreach ($errors as $errorMessage) {
  658. $exception->addMessage(new \Magento\Framework\Message\Error($errorMessage));
  659. }
  660. throw $exception;
  661. }
  662. return $this;
  663. }
  664. /**
  665. * Returns validator, which contains all rules to validate this model.
  666. *
  667. * Returns FALSE, if no validation rules exist.
  668. *
  669. * @return \Zend_Validate_Interface|false
  670. */
  671. protected function _getValidatorBeforeSave()
  672. {
  673. if ($this->_validatorBeforeSave === null) {
  674. $this->_validatorBeforeSave = $this->_createValidatorBeforeSave();
  675. }
  676. return $this->_validatorBeforeSave;
  677. }
  678. /**
  679. * Creates validator for the model with all validation rules in it.
  680. *
  681. * Returns FALSE, if no validation rules exist.
  682. *
  683. * @return \Zend_Validate_Interface|bool
  684. */
  685. protected function _createValidatorBeforeSave()
  686. {
  687. $modelRules = $this->_getValidationRulesBeforeSave();
  688. $resourceRules = $this->_getResource()->getValidationRulesBeforeSave();
  689. if (!$modelRules && !$resourceRules) {
  690. return false;
  691. }
  692. if ($modelRules && $resourceRules) {
  693. $validator = new \Zend_Validate();
  694. $validator->addValidator($modelRules);
  695. $validator->addValidator($resourceRules);
  696. } elseif ($modelRules) {
  697. $validator = $modelRules;
  698. } else {
  699. $validator = $resourceRules;
  700. }
  701. return $validator;
  702. }
  703. /**
  704. * Template method to return validate rules for the entity
  705. *
  706. * @return \Zend_Validate_Interface|null
  707. */
  708. protected function _getValidationRulesBeforeSave()
  709. {
  710. return null;
  711. }
  712. /**
  713. * Get list of cache tags applied to model object.
  714. *
  715. * Return false if cache tags are not supported by model
  716. *
  717. * @return array|false
  718. */
  719. public function getCacheTags()
  720. {
  721. $tags = false;
  722. if ($this->_cacheTag) {
  723. if ($this->_cacheTag === true) {
  724. $tags = [];
  725. } else {
  726. if (is_array($this->_cacheTag)) {
  727. $tags = $this->_cacheTag;
  728. } else {
  729. $tags = [$this->_cacheTag];
  730. }
  731. }
  732. }
  733. return $tags;
  734. }
  735. /**
  736. * Remove model object related cache
  737. *
  738. * @return $this
  739. */
  740. public function cleanModelCache()
  741. {
  742. $tags = $this->getCacheTags();
  743. if ($tags !== false) {
  744. $this->_cacheManager->clean($tags);
  745. }
  746. return $this;
  747. }
  748. /**
  749. * Processing object after save data
  750. *
  751. * @return $this
  752. */
  753. public function afterSave()
  754. {
  755. $this->cleanModelCache();
  756. $this->_eventManager->dispatch('model_save_after', ['object' => $this]);
  757. $this->_eventManager->dispatch('clean_cache_by_tags', ['object' => $this]);
  758. $this->_eventManager->dispatch($this->_eventPrefix . '_save_after', $this->_getEventData());
  759. $this->updateStoredData();
  760. return $this;
  761. }
  762. /**
  763. * Delete object from database
  764. *
  765. * @return $this
  766. * @throws \Exception
  767. * @deprecated 100.1.0 because entities must not be responsible for their own deletion.
  768. * Service contracts should delete entities. Use resource model "delete" method to implement
  769. * service contract persistence operations.
  770. */
  771. public function delete()
  772. {
  773. $this->_getResource()->delete($this);
  774. return $this;
  775. }
  776. /**
  777. * Processing object before delete data
  778. *
  779. * @return $this
  780. * @throws \Magento\Framework\Exception\LocalizedException
  781. */
  782. public function beforeDelete()
  783. {
  784. if (!$this->_actionValidator->isAllowed($this)) {
  785. throw new \Magento\Framework\Exception\LocalizedException(
  786. new \Magento\Framework\Phrase('Delete operation is forbidden for current area')
  787. );
  788. }
  789. $this->_eventManager->dispatch('model_delete_before', ['object' => $this]);
  790. $this->_eventManager->dispatch($this->_eventPrefix . '_delete_before', $this->_getEventData());
  791. $this->cleanModelCache();
  792. return $this;
  793. }
  794. /**
  795. * Processing object after delete data
  796. *
  797. * @return $this
  798. */
  799. public function afterDelete()
  800. {
  801. $this->_eventManager->dispatch('model_delete_after', ['object' => $this]);
  802. $this->_eventManager->dispatch('clean_cache_by_tags', ['object' => $this]);
  803. $this->_eventManager->dispatch($this->_eventPrefix . '_delete_after', $this->_getEventData());
  804. $this->storedData = [];
  805. return $this;
  806. }
  807. /**
  808. * Processing manipulation after main transaction commit
  809. *
  810. * @return $this
  811. */
  812. public function afterDeleteCommit()
  813. {
  814. $this->_eventManager->dispatch('model_delete_commit_after', ['object' => $this]);
  815. $this->_eventManager->dispatch($this->_eventPrefix . '_delete_commit_after', $this->_getEventData());
  816. return $this;
  817. }
  818. /**
  819. * Retrieve model resource
  820. *
  821. * @return \Magento\Framework\Model\ResourceModel\Db\AbstractDb
  822. * @deprecated 101.0.0 because resource models should be used directly
  823. */
  824. public function getResource()
  825. {
  826. return $this->_getResource();
  827. }
  828. /**
  829. * Retrieve entity id
  830. *
  831. * @return mixed
  832. */
  833. public function getEntityId()
  834. {
  835. return $this->_getData('entity_id');
  836. }
  837. /**
  838. * Set entity id
  839. *
  840. * @param int $entityId
  841. * @return $this
  842. */
  843. public function setEntityId($entityId)
  844. {
  845. return $this->setData('entity_id', $entityId);
  846. }
  847. /**
  848. * Clearing object for correct deleting by garbage collector
  849. *
  850. * @return $this
  851. */
  852. public function clearInstance()
  853. {
  854. $this->_clearReferences();
  855. $this->_eventManager->dispatch($this->_eventPrefix . '_clear', $this->_getEventData());
  856. $this->_clearData();
  857. return $this;
  858. }
  859. /**
  860. * Clearing cyclic references
  861. *
  862. * @return $this
  863. */
  864. protected function _clearReferences()
  865. {
  866. return $this;
  867. }
  868. /**
  869. * Clearing object's data
  870. *
  871. * @return $this
  872. */
  873. protected function _clearData()
  874. {
  875. return $this;
  876. }
  877. /**
  878. * Synchronize object's stored data with the actual data
  879. *
  880. * @return $this
  881. */
  882. private function updateStoredData()
  883. {
  884. if (isset($this->_data)) {
  885. $this->storedData = $this->_data;
  886. } else {
  887. $this->storedData = [];
  888. }
  889. return $this;
  890. }
  891. /**
  892. * Model StoredData getter
  893. *
  894. * @return array
  895. */
  896. public function getStoredData()
  897. {
  898. return $this->storedData;
  899. }
  900. /**
  901. * Returns _eventPrefix
  902. *
  903. * @return string
  904. */
  905. public function getEventPrefix()
  906. {
  907. return $this->_eventPrefix;
  908. }
  909. }