Instance.php 8.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253
  1. <?php
  2. /**
  3. * Copyright © Magento, Inc. All rights reserved.
  4. * See COPYING.txt for license details.
  5. */
  6. namespace Magento\Widget\Model\ResourceModel\Widget;
  7. use Magento\Framework\Model\AbstractModel;
  8. /**
  9. * Widget Instance Resource Model
  10. *
  11. * @api
  12. * @since 100.0.2
  13. */
  14. class Instance extends \Magento\Framework\Model\ResourceModel\Db\AbstractDb
  15. {
  16. /**
  17. * Define main table
  18. *
  19. * @return void
  20. */
  21. protected function _construct()
  22. {
  23. $this->_init('widget_instance', 'instance_id');
  24. }
  25. /**
  26. * Perform actions after object load
  27. *
  28. * @param \Magento\Widget\Model\Widget\Instance $object
  29. * @return $this
  30. */
  31. protected function _afterLoad(AbstractModel $object)
  32. {
  33. $connection = $this->getConnection();
  34. $select = $connection->select()->from(
  35. $this->getTable('widget_instance_page')
  36. )->where(
  37. 'instance_id = ?',
  38. (int)$object->getId()
  39. );
  40. $result = $connection->fetchAll($select);
  41. $object->setData('page_groups', $result);
  42. return parent::_afterLoad($object);
  43. }
  44. /**
  45. * Perform actions after object save
  46. *
  47. * @param \Magento\Widget\Model\Widget\Instance $object
  48. * @return $this
  49. */
  50. protected function _afterSave(AbstractModel $object)
  51. {
  52. $pageTable = $this->getTable('widget_instance_page');
  53. $pageLayoutTable = $this->getTable('widget_instance_page_layout');
  54. $connection = $this->getConnection();
  55. $select = $connection->select()->from($pageTable, 'page_id')->where('instance_id = ?', (int)$object->getId());
  56. $pageIds = $connection->fetchCol($select);
  57. $removePageIds = array_diff($pageIds, $object->getData('page_group_ids'));
  58. if (is_array($pageIds) && count($pageIds) > 0) {
  59. $inCond = $connection->prepareSqlCondition('page_id', ['in' => $pageIds]);
  60. $select = $connection->select()->from($pageLayoutTable, 'layout_update_id')->where($inCond);
  61. $removeLayoutUpdateIds = $connection->fetchCol($select);
  62. $connection->delete($pageLayoutTable, $inCond);
  63. $this->_deleteLayoutUpdates($removeLayoutUpdateIds);
  64. }
  65. $this->_deleteWidgetInstancePages($removePageIds);
  66. foreach ($object->getData('page_groups') as $pageGroup) {
  67. $pageLayoutUpdateIds = $this->_saveLayoutUpdates($object, $pageGroup);
  68. $data = [
  69. 'page_group' => $pageGroup['group'],
  70. 'layout_handle' => $pageGroup['layout_handle'],
  71. 'block_reference' => $pageGroup['block_reference'],
  72. 'page_for' => $pageGroup['for'],
  73. 'entities' => $pageGroup['entities'],
  74. 'page_template' => $pageGroup['template'],
  75. ];
  76. $pageId = $pageGroup['page_id'];
  77. if (in_array($pageGroup['page_id'], $pageIds)) {
  78. $connection->update($pageTable, $data, ['page_id = ?' => (int)$pageId]);
  79. } else {
  80. $connection->insert($pageTable, array_merge(['instance_id' => $object->getId()], $data));
  81. $pageId = $connection->lastInsertId($pageTable);
  82. }
  83. foreach ($pageLayoutUpdateIds as $layoutUpdateId) {
  84. $connection->insert(
  85. $pageLayoutTable,
  86. ['page_id' => $pageId, 'layout_update_id' => $layoutUpdateId]
  87. );
  88. }
  89. }
  90. return parent::_afterSave($object);
  91. }
  92. /**
  93. * Prepare and save layout updates data
  94. *
  95. * @param \Magento\Widget\Model\Widget\Instance $widgetInstance
  96. * @param array $pageGroupData
  97. * @return string[] of inserted layout updates ids
  98. */
  99. protected function _saveLayoutUpdates($widgetInstance, $pageGroupData)
  100. {
  101. $connection = $this->getConnection();
  102. $pageLayoutUpdateIds = [];
  103. $storeIds = $this->_prepareStoreIds($widgetInstance->getStoreIds());
  104. $layoutUpdateTable = $this->getTable('layout_update');
  105. $layoutUpdateLinkTable = $this->getTable('layout_link');
  106. foreach ($pageGroupData['layout_handle_updates'] as $handle) {
  107. $xml = $widgetInstance->generateLayoutUpdateXml(
  108. $pageGroupData['block_reference'],
  109. $pageGroupData['template']
  110. );
  111. $insert = ['handle' => $handle, 'xml' => $xml];
  112. if (strlen($widgetInstance->getSortOrder())) {
  113. $insert['sort_order'] = $widgetInstance->getSortOrder();
  114. }
  115. $connection->insert($layoutUpdateTable, $insert);
  116. $layoutUpdateId = $connection->lastInsertId($layoutUpdateTable);
  117. $pageLayoutUpdateIds[] = $layoutUpdateId;
  118. $data = [];
  119. foreach ($storeIds as $storeId) {
  120. $data[] = [
  121. 'store_id' => $storeId,
  122. 'theme_id' => $widgetInstance->getThemeId(),
  123. 'layout_update_id' => $layoutUpdateId,
  124. ];
  125. }
  126. $connection->insertMultiple($layoutUpdateLinkTable, $data);
  127. }
  128. return $pageLayoutUpdateIds;
  129. }
  130. /**
  131. * Prepare store ids.
  132. * If one of store id is default (0) return all store ids
  133. *
  134. * @param array $storeIds
  135. * @return array
  136. */
  137. protected function _prepareStoreIds($storeIds)
  138. {
  139. if (in_array('0', $storeIds)) {
  140. $storeIds = [0];
  141. }
  142. return $storeIds;
  143. }
  144. /**
  145. * Perform actions before object delete.
  146. * Collect page ids and layout update ids and set to object for further delete
  147. *
  148. * @param \Magento\Framework\Model\AbstractModel $object
  149. * @return $this
  150. */
  151. protected function _beforeDelete(AbstractModel $object)
  152. {
  153. $connection = $this->getConnection();
  154. $select = $connection->select()->from(
  155. ['main_table' => $this->getTable('widget_instance_page')],
  156. []
  157. )->joinInner(
  158. ['layout_page_table' => $this->getTable('widget_instance_page_layout')],
  159. 'layout_page_table.page_id = main_table.page_id',
  160. ['layout_update_id']
  161. )->where(
  162. 'main_table.instance_id=?',
  163. $object->getId()
  164. );
  165. $result = $connection->fetchCol($select);
  166. $object->setLayoutUpdateIdsToDelete($result);
  167. return $this;
  168. }
  169. /**
  170. * Perform actions after object delete.
  171. * Delete layout updates by layout update ids collected in _beforeSave
  172. *
  173. * @param \Magento\Widget\Model\Widget\Instance $object
  174. * @return $this
  175. */
  176. protected function _afterDelete(AbstractModel $object)
  177. {
  178. $this->_deleteLayoutUpdates($object->getLayoutUpdateIdsToDelete());
  179. return parent::_afterDelete($object);
  180. }
  181. /**
  182. * Delete widget instance pages by given ids
  183. *
  184. * @param array $pageIds
  185. * @return $this
  186. */
  187. protected function _deleteWidgetInstancePages($pageIds)
  188. {
  189. $connection = $this->getConnection();
  190. if ($pageIds) {
  191. $inCond = $connection->prepareSqlCondition('page_id', ['in' => $pageIds]);
  192. $connection->delete($this->getTable('widget_instance_page'), $inCond);
  193. }
  194. return $this;
  195. }
  196. /**
  197. * Delete layout updates by given ids
  198. *
  199. * @param array $layoutUpdateIds
  200. * @return $this
  201. */
  202. protected function _deleteLayoutUpdates($layoutUpdateIds)
  203. {
  204. $connection = $this->getConnection();
  205. if ($layoutUpdateIds) {
  206. $inCond = $connection->prepareSqlCondition('layout_update_id', ['in' => $layoutUpdateIds]);
  207. $connection->delete($this->getTable('layout_update'), $inCond);
  208. }
  209. return $this;
  210. }
  211. /**
  212. * Get store ids to which specified item is assigned
  213. *
  214. * @param int $id
  215. * @return string[]
  216. */
  217. public function lookupStoreIds($id)
  218. {
  219. $connection = $this->getConnection();
  220. $select = $connection->select()->from(
  221. $this->getMainTable(),
  222. 'store_ids'
  223. )->where(
  224. "{$this->getIdFieldName()} = ?",
  225. (int)$id
  226. );
  227. $storeIds = $connection->fetchOne($select);
  228. return $storeIds ? explode(',', $storeIds) : [];
  229. }
  230. }