11<?php
22namespace Lof \ProductTags \Model \ResourceModel ;
3+ use Magento \Framework \Model \AbstractModel ;
4+ use Magento \Catalog \Model \Indexer \Category \Product \Processor ;
5+ use Magento \Framework \DataObject ;
6+ use Magento \Framework \EntityManager \EntityManager ;
7+ use Magento \Eav \Model \Entity \Attribute \UniqueValidationInterface ;
38
49class Tag extends \Magento \Framework \Model \ResourceModel \Db \AbstractDb
510{
11+ protected $ _tagProductTable = '' ;
12+
613 protected function _construct ()
714 {
815 $ this ->_init ('lof_producttags_tag ' , 'tag_id ' );
916 }
17+
18+ /**
19+ * Process page data after saving
20+ *
21+ * @param AbstractModel $object
22+ * @return $this
23+ * @throws LocalizedException
24+ */
25+ protected function _afterSave (AbstractModel $ object )
26+ {
27+ $ this ->_saveTagProducts ($ object );
28+ return parent ::_afterSave ($ object );
29+ }
30+
31+ public function getTagProductTable ()
32+ {
33+ if (!$ this ->_tagProductTable ) {
34+ $ this ->_tagProductTable = $ this ->getTable ('lof_producttags_product ' );
35+ }
36+ return $ this ->_tagProductTable ;
37+ }
38+ protected function _saveTagProducts ($ tag )
39+ {
40+ $ tag ->setIsChangedProductList (false );
41+ $ id = $ tag ->getId ();
42+
43+ /**
44+ * new tag-product relationships
45+ */
46+ $ products = $ tag ->getPostedProducts ();
47+ /**
48+ * Example re-save category
49+ */
50+ if ($ products === null ) {
51+ return $ this ;
52+ }
53+
54+ /**
55+ * old category-product relationships
56+ */
57+ $ oldProducts = $ tag ->getProductsPosition ();
58+
59+ $ insert = array_diff_key ($ products , $ oldProducts );
60+ $ delete = array_diff_key ($ oldProducts , $ products );
61+
62+ /**
63+ * Find product ids which are presented in both arrays
64+ * and saved before (check $oldProducts array)
65+ */
66+ $ update = array_intersect_key ($ products , $ oldProducts );
67+ $ update = array_diff_assoc ($ update , $ oldProducts );
68+
69+ $ connection = $ this ->getConnection ();
70+
71+ /**
72+ * Delete products from tag
73+ */
74+ if (!empty ($ delete )) {
75+ $ cond = ['product_id IN(?) ' => array_keys ($ delete ), 'tag_id=? ' => $ id ];
76+ $ connection ->delete ($ this ->getTagProductTable (), $ cond );
77+ }
78+
79+ /**
80+ * Add products to tag
81+ */
82+ if (!empty ($ insert )) {
83+ $ data = [];
84+ foreach ($ insert as $ productId => $ position ) {
85+ $ data [] = [
86+ 'tag_id ' => (int )$ id ,
87+ 'product_id ' => (int )$ productId ,
88+ 'position ' => (int )$ position ,
89+ ];
90+ }
91+ $ connection ->insertMultiple ($ this ->getTagProductTable (), $ data );
92+ }
93+
94+ /**
95+ * Update product positions in category
96+ */
97+ if (!empty ($ update )) {
98+ $ newPositions = [];
99+ foreach ($ update as $ productId => $ position ) {
100+ $ delta = $ position - $ oldProducts [$ productId ];
101+ if (!isset ($ newPositions [$ delta ])) {
102+ $ newPositions [$ delta ] = [];
103+ }
104+ $ newPositions [$ delta ][] = $ productId ;
105+ }
106+
107+ foreach ($ newPositions as $ delta => $ productIds ) {
108+ $ bind = ['position ' => new \Zend_Db_Expr ("position + ( {$ delta }) " )];
109+ $ where = ['tag_id = ? ' => (int )$ id , 'product_id IN (?) ' => $ productIds ];
110+ $ connection ->update ($ this ->getTagProductTable (), $ bind , $ where );
111+ }
112+ }
113+ if (!empty ($ insert ) || !empty ($ delete )) {
114+ $ productIds = array_unique (array_merge (array_keys ($ insert ), array_keys ($ delete )));
115+ $ tag ->setChangedProductIds ($ productIds );
116+ }
117+ if (!empty ($ insert ) || !empty ($ update ) || !empty ($ delete )) {
118+ $ tag ->setIsChangedProductList (true );
119+
120+ /**
121+ * Setting affected products to tag for third party engine index refresh
122+ */
123+ $ productIds = array_keys ($ insert + $ delete + $ update );
124+ $ tag ->setAffectedProductIds ($ productIds );
125+ }
126+
127+ return $ this ;
128+ }
129+ /**
130+ * Get positions of associated to tag products
131+ *
132+ * @param \Lof\ProductTags\Model\Tag $tag
133+ * @return array
134+ */
135+ public function getProductsPosition ($ tag )
136+ {
137+ $ select = $ this ->getConnection ()->select ()->from (
138+ $ this ->getTagProductTable (),
139+ ['product_id ' , 'position ' ]
140+ )->where (
141+ "{$ this ->getTable ('lof_producttags_product ' )}.tag_id = ? " ,
142+ (int )$ tag ->getId ()
143+ );
144+
145+ $ bind = ['tag_id ' => (int )$ tag ->getId ()];
146+
147+ return $ this ->getConnection ()->fetchPairs ($ select , $ bind );
148+ }
10149}
0 commit comments