|
1
|
|
|
<?php |
|
2
|
|
|
|
|
3
|
|
|
use cmsemail\email; |
|
4
|
|
|
use CMSFactory\assetManager; |
|
5
|
|
|
use CMSFactory\Events; |
|
6
|
|
|
use Propel\Runtime\Collection\ObjectCollection; |
|
7
|
|
|
|
|
8
|
|
|
(defined('BASEPATH')) OR exit('No direct script access allowed'); |
|
9
|
|
|
|
|
10
|
|
|
/** |
|
11
|
|
|
* Image CMS |
|
12
|
|
|
* |
|
13
|
|
|
* |
|
14
|
|
|
* Вывоз метода на товаре {module('pricespy')->init($model)->renderButton($model->getId() , $variant->getId())} |
|
15
|
|
|
* |
|
16
|
|
|
* |
|
17
|
|
|
* Класс слежения за ценой |
|
18
|
|
|
* @property pricespy_model $pricespy_model |
|
19
|
|
|
*/ |
|
20
|
|
|
class Pricespy extends MY_Controller |
|
21
|
|
|
{ |
|
22
|
|
|
|
|
23
|
|
|
public $product; |
|
24
|
|
|
|
|
25
|
|
|
public $isInSpy; |
|
26
|
|
|
|
|
27
|
|
|
public function __construct() { |
|
28
|
|
|
parent::__construct(); |
|
29
|
|
|
$this->load->module('core'); |
|
30
|
|
|
$this->load->model('pricespy_model'); |
|
31
|
|
|
$lang = new MY_Lang(); |
|
32
|
|
|
$lang->load('pricespy'); |
|
33
|
|
|
} |
|
34
|
|
|
|
|
35
|
|
|
/** |
|
36
|
|
|
* send email to user |
|
37
|
|
|
* @param $spy |
|
38
|
|
|
* @return bool |
|
|
|
|
|
|
39
|
|
|
*/ |
|
40
|
|
|
private static function sendNotificationByEmail($spy) { |
|
41
|
|
|
|
|
42
|
|
|
$data = [ |
|
43
|
|
|
'hash' => $spy->hash, |
|
44
|
|
|
'productName' => $spy->name, |
|
45
|
|
|
'userName' => $spy->username, |
|
46
|
|
|
'siteUrl' => site_url('/'), |
|
47
|
|
|
'linkModule' => site_url('/pricespy/'), |
|
48
|
|
|
'unlinkSpy' => site_url('/pricespy/unspy/'. $spy->hash), |
|
49
|
|
|
]; |
|
50
|
|
|
|
|
51
|
|
|
return email::getInstance()->sendEmail($spy->email, 'pricespy', $data); |
|
52
|
|
|
} |
|
53
|
|
|
|
|
54
|
|
|
public static function adminAutoload() { |
|
55
|
|
|
parent::adminAutoload(); |
|
56
|
|
|
|
|
57
|
|
|
Events::create()->onShopProductUpdate()->setListener('priceUpdate'); |
|
58
|
|
|
Events::create()->onShopProductDelete()->setListener('priceDelete'); |
|
59
|
|
|
} |
|
60
|
|
|
|
|
61
|
|
|
/** |
|
62
|
|
|
* |
|
63
|
|
|
*/ |
|
64
|
|
|
public function index() { |
|
65
|
|
|
if ($this->dx_auth->is_logged_in()) { |
|
66
|
|
|
assetManager::create() |
|
67
|
|
|
->registerScript('spy'); |
|
68
|
|
|
$this->renderUserSpys(); |
|
69
|
|
|
} else { |
|
70
|
|
|
redirect('auth/login'); |
|
71
|
|
|
} |
|
72
|
|
|
} |
|
73
|
|
|
|
|
74
|
|
|
/** |
|
75
|
|
|
* deleting from spy if product deleted |
|
76
|
|
|
* @param array $product |
|
77
|
|
|
*/ |
|
78
|
|
|
public static function priceDelete($product) { |
|
79
|
|
|
if (!$product) { |
|
80
|
|
|
return; |
|
81
|
|
|
} |
|
82
|
|
|
|
|
83
|
|
|
$CI = &get_instance(); |
|
84
|
|
|
|
|
85
|
|
|
$product = $product['model']; |
|
86
|
|
|
$ids = []; |
|
87
|
|
|
/** @var SProducts $p */ |
|
88
|
|
|
foreach ($product as $key => $p) { |
|
89
|
|
|
$ids[$key] = $p->getId(); |
|
90
|
|
|
} |
|
91
|
|
|
|
|
92
|
|
|
$CI->db->where_in('productId', $ids); |
|
93
|
|
|
$CI->db->delete('mod_price_spy'); |
|
94
|
|
|
} |
|
95
|
|
|
|
|
96
|
|
|
/** |
|
97
|
|
|
* updating price |
|
98
|
|
|
* @param array $product |
|
99
|
|
|
*/ |
|
100
|
|
|
public static function priceUpdate($product) { |
|
101
|
|
|
|
|
102
|
|
|
if (!$product) { |
|
103
|
|
|
return; |
|
104
|
|
|
} |
|
105
|
|
|
|
|
106
|
|
|
$CI = &get_instance(); |
|
107
|
|
|
|
|
108
|
|
|
/** @var CI_DB_result $spys */ |
|
109
|
|
|
$spys = $CI->db |
|
110
|
|
|
->from('mod_price_spy') |
|
111
|
|
|
->join('shop_product_variants', 'mod_price_spy.productVariantId=shop_product_variants.id') |
|
112
|
|
|
->join('users', 'mod_price_spy.userId=users.id') |
|
113
|
|
|
->join('shop_products_i18n', 'shop_products_i18n.id=mod_price_spy.productId') |
|
114
|
|
|
->where('mod_price_spy.productId', $product['productId']) |
|
115
|
|
|
->get(); |
|
116
|
|
|
|
|
117
|
|
|
if ($spys->num_rows() > 0) { |
|
118
|
|
|
|
|
119
|
|
|
$spys = $spys->result(); |
|
120
|
|
|
|
|
121
|
|
|
foreach ($spys as $spy) { |
|
122
|
|
|
|
|
123
|
|
|
if ($spy->price != $spy->productPrice) { |
|
124
|
|
|
|
|
125
|
|
|
$CI->db->set('productPrice', $spy->price); |
|
126
|
|
|
$CI->db->where('productVariantId', $spy->productVariantId); |
|
127
|
|
|
$CI->db->update('mod_price_spy'); |
|
128
|
|
|
|
|
129
|
|
|
if ($spy->price < $spy->productPrice) { |
|
130
|
|
|
self::sendNotificationByEmail($spy); |
|
131
|
|
|
} |
|
132
|
|
|
} |
|
133
|
|
|
} |
|
134
|
|
|
} |
|
135
|
|
|
|
|
136
|
|
|
} |
|
137
|
|
|
|
|
138
|
|
|
/** |
|
139
|
|
|
* set spy for product |
|
140
|
|
|
* @param int $id product ID |
|
141
|
|
|
* @param int $varId variant ID |
|
142
|
|
|
*/ |
|
143
|
|
|
public function spy($id, $varId) { |
|
144
|
|
|
|
|
145
|
|
|
$product = SProductVariantsQuery::create() |
|
146
|
|
|
->findPk($varId); |
|
147
|
|
|
|
|
148
|
|
|
if ($this->pricespy_model->setSpy($id, $varId, $product->getPrice())) { |
|
149
|
|
|
echo json_encode( |
|
150
|
|
|
['answer' => 'sucesfull'] |
|
151
|
|
|
); |
|
152
|
|
|
} else { |
|
153
|
|
|
echo json_encode( |
|
154
|
|
|
['answer' => 'error'] |
|
155
|
|
|
); |
|
156
|
|
|
} |
|
157
|
|
|
} |
|
158
|
|
|
|
|
159
|
|
|
/** |
|
160
|
|
|
* |
|
161
|
|
|
* @param string $hash |
|
162
|
|
|
*/ |
|
163
|
|
|
public function unSpy($hash) { |
|
164
|
|
|
if ($this->pricespy_model->delSpyByHash($hash)) { |
|
165
|
|
|
echo json_encode( |
|
166
|
|
|
['answer' => 'sucesfull'] |
|
167
|
|
|
); |
|
168
|
|
|
} else { |
|
169
|
|
|
echo json_encode( |
|
170
|
|
|
['answer' => 'error'] |
|
171
|
|
|
); |
|
172
|
|
|
} |
|
173
|
|
|
} |
|
174
|
|
|
|
|
175
|
|
|
/** |
|
176
|
|
|
* @param SProducts $model |
|
177
|
|
|
* @return $this|bool |
|
|
|
|
|
|
178
|
|
|
*/ |
|
179
|
|
|
public function init($model) { |
|
180
|
|
|
|
|
181
|
|
|
if ($this->dx_auth->is_logged_in()) { |
|
182
|
|
|
|
|
183
|
|
|
if (!$model instanceof SProducts) { |
|
|
|
|
|
|
184
|
|
|
return false; |
|
185
|
|
|
} |
|
186
|
|
|
|
|
187
|
|
|
$this->setAllVariantModel($model->getProductVariants()); |
|
188
|
|
|
|
|
189
|
|
|
assetManager::create() |
|
190
|
|
|
->registerScript('spy'); |
|
191
|
|
|
} |
|
192
|
|
|
|
|
193
|
|
|
return $this; |
|
194
|
|
|
} |
|
195
|
|
|
|
|
196
|
|
|
/** |
|
197
|
|
|
* @param ObjectCollection $model |
|
198
|
|
|
* @return void |
|
199
|
|
|
*/ |
|
200
|
|
|
private function setAllVariantModel(ObjectCollection $model) { |
|
201
|
|
|
|
|
202
|
|
|
if ($model->count() > 0) { |
|
203
|
|
|
/** @var SProductVariants $item */ |
|
204
|
|
|
foreach ($model as $item) { |
|
205
|
|
|
|
|
206
|
|
|
$this->checkVariants($item->getId()); |
|
207
|
|
|
|
|
208
|
|
|
} |
|
209
|
|
|
} |
|
210
|
|
|
|
|
211
|
|
|
} |
|
212
|
|
|
|
|
213
|
|
|
/** |
|
214
|
|
|
* @param int $variant_id |
|
215
|
|
|
* @return void |
|
216
|
|
|
*/ |
|
217
|
|
|
private function checkVariants($variant_id) { |
|
218
|
|
|
|
|
219
|
|
|
/** @var CI_DB_result $products */ |
|
220
|
|
|
$products = $this->db |
|
221
|
|
|
->where_in('productVariantId', $variant_id) |
|
222
|
|
|
->where('userId', $this->dx_auth->get_user_id()) |
|
223
|
|
|
->get('mod_price_spy'); |
|
224
|
|
|
|
|
225
|
|
|
if ($products->num_rows() > 0) { |
|
226
|
|
|
|
|
227
|
|
|
$products = $products->result_array(); |
|
228
|
|
|
$this->setIsInSpy($products); |
|
229
|
|
|
|
|
230
|
|
|
} |
|
231
|
|
|
|
|
232
|
|
|
} |
|
233
|
|
|
|
|
234
|
|
|
/** |
|
235
|
|
|
* @param array $products |
|
236
|
|
|
* @return void |
|
237
|
|
|
*/ |
|
238
|
|
|
private function setIsInSpy(array $products) { |
|
239
|
|
|
|
|
240
|
|
|
foreach ($products as $product) { |
|
241
|
|
|
|
|
242
|
|
|
$this->isInSpy[$product['productVariantId']] = $product; |
|
243
|
|
|
} |
|
244
|
|
|
|
|
245
|
|
|
} |
|
246
|
|
|
|
|
247
|
|
|
/** |
|
248
|
|
|
* render spy buttons |
|
249
|
|
|
* @param int $id product ID |
|
250
|
|
|
* @param int $varId variant ID |
|
251
|
|
|
*/ |
|
252
|
|
|
public function renderButton($id, $varId) { |
|
253
|
|
|
if ($this->dx_auth->is_logged_in()) { |
|
254
|
|
|
|
|
255
|
|
|
$data = [ |
|
256
|
|
|
'Id' => $id, |
|
257
|
|
|
'varId' => $varId, |
|
258
|
|
|
]; |
|
259
|
|
|
|
|
260
|
|
|
if ($this->isInSpy[$varId] == '') { |
|
261
|
|
|
assetManager::create() |
|
262
|
|
|
->setData('data', $data) |
|
263
|
|
|
->setData('value', lang('Notify about price cut', 'pricespy')) |
|
264
|
|
|
->setData('class', 'btn btn-info') |
|
265
|
|
|
->render('button', true); |
|
266
|
|
|
} else { |
|
267
|
|
|
assetManager::create() |
|
268
|
|
|
->setData('data', $data) |
|
269
|
|
|
->setData('value', lang('Already in tracking', 'pricespy')) |
|
270
|
|
|
->setData('class', 'btn inSpy btn-success') |
|
271
|
|
|
->render('button', true); |
|
272
|
|
|
} |
|
273
|
|
|
} |
|
274
|
|
|
} |
|
275
|
|
|
|
|
276
|
|
|
/** |
|
277
|
|
|
* render spys for user |
|
278
|
|
|
*/ |
|
279
|
|
|
private function renderUserSpys() { |
|
280
|
|
|
$products = $this->db |
|
281
|
|
|
->where('userId', $this->dx_auth->get_user_id()) |
|
282
|
|
|
->join('shop_product_variants', 'shop_product_variants.id=mod_price_spy.productVariantId') |
|
283
|
|
|
->join('shop_products_i18n', 'shop_products_i18n.id=mod_price_spy.productId') |
|
284
|
|
|
->join('shop_products', 'shop_products.id=mod_price_spy.productId') |
|
285
|
|
|
->join('route', 'route.entity_id = mod_price_spy.productId and route.type = "product"') |
|
286
|
|
|
->get('mod_price_spy') |
|
287
|
|
|
->result_array(); |
|
288
|
|
|
|
|
289
|
|
|
foreach ($products as &$product) { |
|
290
|
|
|
$product['url'] = \core\models\Route::createRouteUrl($product['url'], $product['parent_url'], 'product'); |
|
291
|
|
|
} |
|
292
|
|
|
|
|
293
|
|
|
assetManager::create() |
|
294
|
|
|
->setData('products', $products) |
|
295
|
|
|
->render('spys'); |
|
296
|
|
|
} |
|
297
|
|
|
|
|
298
|
|
|
public function _install() { |
|
299
|
|
|
$pattern = $this->pricespy_model->getEmailPattern(); |
|
300
|
|
|
|
|
301
|
|
|
$this->db->insert('mod_email_paterns', $pattern); |
|
302
|
|
|
|
|
303
|
|
|
$pattern_i18n = $this->pricespy_model->getEmailPatternI18n(); |
|
304
|
|
|
|
|
305
|
|
|
$this->db->insert('mod_email_paterns_i18n', $pattern_i18n); |
|
306
|
|
|
|
|
307
|
|
|
$this->load->dbforge(); |
|
308
|
|
|
($this->dx_auth->is_admin()) OR exit; |
|
309
|
|
|
$fields = [ |
|
310
|
|
|
'id' => [ |
|
311
|
|
|
'type' => 'INT', |
|
312
|
|
|
'auto_increment' => TRUE, |
|
313
|
|
|
], |
|
314
|
|
|
'userId' => [ |
|
315
|
|
|
'type' => 'VARCHAR', |
|
316
|
|
|
'constraint' => '30', |
|
317
|
|
|
'null' => TRUE, |
|
318
|
|
|
], |
|
319
|
|
|
'productId' => [ |
|
320
|
|
|
'type' => 'VARCHAR', |
|
321
|
|
|
'constraint' => '30', |
|
322
|
|
|
'null' => TRUE, |
|
323
|
|
|
], |
|
324
|
|
|
'productVariantId' => [ |
|
325
|
|
|
'type' => 'VARCHAR', |
|
326
|
|
|
'constraint' => '30', |
|
327
|
|
|
'null' => TRUE, |
|
328
|
|
|
], |
|
329
|
|
|
'productPrice' => [ |
|
330
|
|
|
'type' => 'VARCHAR', |
|
331
|
|
|
'constraint' => '30', |
|
332
|
|
|
'null' => TRUE, |
|
333
|
|
|
], |
|
334
|
|
|
'oldProductPrice' => [ |
|
335
|
|
|
'type' => 'VARCHAR', |
|
336
|
|
|
'constraint' => '30', |
|
337
|
|
|
'null' => TRUE, |
|
338
|
|
|
], |
|
339
|
|
|
'hash' => [ |
|
340
|
|
|
'type' => 'VARCHAR', |
|
341
|
|
|
'constraint' => '40', |
|
342
|
|
|
'null' => TRUE, |
|
343
|
|
|
], |
|
344
|
|
|
]; |
|
345
|
|
|
|
|
346
|
|
|
$this->dbforge->add_field($fields); |
|
347
|
|
|
$this->dbforge->add_key('id', TRUE); |
|
348
|
|
|
$this->dbforge->create_table('mod_price_spy'); |
|
349
|
|
|
|
|
350
|
|
|
$this->db->where('name', 'pricespy'); |
|
351
|
|
|
$this->db->update( |
|
352
|
|
|
'components', |
|
353
|
|
|
[ |
|
354
|
|
|
'enabled' => 1, |
|
355
|
|
|
'autoload' => 1, |
|
356
|
|
|
] |
|
357
|
|
|
); |
|
358
|
|
|
} |
|
359
|
|
|
|
|
360
|
|
|
public function _deinstall() { |
|
361
|
|
|
$this->load->dbforge(); |
|
362
|
|
|
($this->dx_auth->is_admin()) OR exit; |
|
363
|
|
|
$this->dbforge->drop_table('mod_price_spy'); |
|
364
|
|
|
} |
|
365
|
|
|
|
|
366
|
|
|
} |
|
367
|
|
|
|
|
368
|
|
|
/* End of file pricespy.php */ |
This check compares the return type specified in the
@returnannotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.If the return type contains the type array, this check recommends the use of a more specific type like
String[]orarray<String>.