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+
39+ protected function _saveTagProducts ($ tag )
40+ {
41+ $ tag ->setIsChangedProductList (false );
42+ $ id = $ tag ->getId ();
43+
44+ /**
45+ * new tag-product relationships
46+ */
47+ $ products = $ tag ->getPostedProducts ();
48+ /**
49+ * Example re-save category
50+ */
51+ if ($ products === null ) {
52+ return $ this ;
53+ }
54+
55+ /**
56+ * old category-product relationships
57+ */
58+ $ oldProducts = $ tag ->getProductsPosition ();
59+
60+ $ insert = array_diff_key ($ products , $ oldProducts );
61+ $ delete = array_diff_key ($ oldProducts , $ products );
62+
63+ /**
64+ * Find product ids which are presented in both arrays
65+ * and saved before (check $oldProducts array)
66+ */
67+ $ update = array_intersect_key ($ products , $ oldProducts );
68+ $ update = array_diff_assoc ($ update , $ oldProducts );
69+
70+ $ connection = $ this ->getConnection ();
71+
72+ /**
73+ * Delete products from tag
74+ */
75+ if (!empty ($ delete )) {
76+ $ cond = ['product_id IN(?) ' => array_keys ($ delete ), 'tag_id=? ' => $ id ];
77+ $ connection ->delete ($ this ->getTagProductTable (), $ cond );
78+ }
79+
80+ /**
81+ * Add products to tag
82+ */
83+ if (!empty ($ insert )) {
84+ $ data = [];
85+ foreach ($ insert as $ productId => $ position ) {
86+ $ data [] = [
87+ 'tag_id ' => (int )$ id ,
88+ 'product_id ' => (int )$ productId ,
89+ 'position ' => (int )$ position ,
90+ ];
91+ }
92+ $ connection ->insertMultiple ($ this ->getTagProductTable (), $ data );
93+ }
94+
95+ /**
96+ * Update product positions in category
97+ */
98+ if (!empty ($ update )) {
99+ $ newPositions = [];
100+ foreach ($ update as $ productId => $ position ) {
101+ $ delta = $ position - $ oldProducts [$ productId ];
102+ if (!isset ($ newPositions [$ delta ])) {
103+ $ newPositions [$ delta ] = [];
104+ }
105+ $ newPositions [$ delta ][] = $ productId ;
106+ }
107+
108+ foreach ($ newPositions as $ delta => $ productIds ) {
109+ $ bind = ['position ' => new \Zend_Db_Expr ("position + ( {$ delta }) " )];
110+ $ where = ['tag_id = ? ' => (int )$ id , 'product_id IN (?) ' => $ productIds ];
111+ $ connection ->update ($ this ->getTagProductTable (), $ bind , $ where );
112+ }
113+ }
114+ if (!empty ($ insert ) || !empty ($ delete )) {
115+ $ productIds = array_unique (array_merge (array_keys ($ insert ), array_keys ($ delete )));
116+ $ tag ->setChangedProductIds ($ productIds );
117+ }
118+
119+ if (!empty ($ insert ) || !empty ($ update ) || !empty ($ delete )) {
120+ $ tag ->setIsChangedProductList (true );
121+
122+ /**
123+ * Setting affected products to tag for third party engine index refresh
124+ */
125+ $ productIds = array_keys ($ insert + $ delete + $ update );
126+ $ tag ->setAffectedProductIds ($ productIds );
127+ }
128+
129+ return $ this ;
130+ }
131+ /**
132+ * Get positions of associated to tag products
133+ *
134+ * @param \Lof\ProductTags\Model\Tag $tag
135+ * @return array
136+ */
137+ public function getProductsPosition ($ tag )
138+ {
139+ $ select = $ this ->getConnection ()->select ()->from (
140+ $ this ->getTagProductTable (),
141+ ['product_id ' , 'position ' ]
142+ )->where (
143+ "{$ this ->getTable ('lof_producttags_product ' )}.tag_id = ? " ,
144+ (int )$ tag ->getId ()
145+ );
146+
147+ $ bind = ['tag_id ' => (int )$ tag ->getId ()];
148+
149+ return $ this ->getConnection ()->fetchPairs ($ select , $ bind );
150+ }
10151}
0 commit comments