-
Notifications
You must be signed in to change notification settings - Fork 0
/
uc_cron_gbase.module
478 lines (395 loc) · 15.3 KB
/
uc_cron_gbase.module
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
<?php
require_once('uc_cron_gbase_token.include');
// Menu Functions
/**
* Implements hook_menu
* Menu items for this module
*/
function uc_cron_gbase_menu() {
$items = array();
$items['uc_cron_gbase'] = array(
'description' => 'Ubercart Google Base Cron Integration.',
'page callback' => 'uc_cron_gbase_test',
'access callback' => 'user_access',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
$items['uc_cron_gbase/exchange'] = array(
'description' => 'Ubercart Google Base Cron Integration token exchange.',
'page callback' => 'uc_cron_gbase_exchange_token',
'access callback' => 'user_access',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
$items['uc_cron_gbase/items'] = array(
'description' => 'Ubercart Google Base Cron Integration items feed.',
'page callback' => 'uc_cron_gbase_get_products',
'access callback' => 'user_access',
'access arguments' => array('access content'),
'type' => MENU_CALLBACK,
);
$items['admin/store/settings/uc_cron_gbase'] = array(
'title' => 'Ubercart Google Base Cron Integration',
'description' => 'Settings for Ubercart Google Base Integration.',
'page callback' => 'drupal_get_form',
'page arguments' => array('uc_cron_gbase_store_admin_settings_form'),
'access callback' => 'user_access',
'access arguments' => array('administer ubercart google base integration'),
'type' => MENU_NORMAL_ITEM,
);
$items['uc_cron_gbase/update'] = array(
'title' => 'Ubercart Google Base Cron Integration',
'description' => 'Settings for Ubercart Google Base Integration.',
'page callback' => 'uc_cron_gbase_update_all',
'page arguments' => array('uc_cron_gbase_update_all'),
'access callback' => 'user_access',
'type' => MENU_NORMAL_ITEM,
);
return $items;
}
// End Menu Functions
// Database Functions
/**
* Insert gbase info into the database
*/
function uc_cron_gbase_db_insert($data) {
db_query("INSERT INTO {uc_cron_gbase} (nid, enabled, taxonomy, product_condition, new, upc, created, updated)
VALUES ('%d', '%d', '%s', '%d', 1, '%s', NOW(),NOW())",
$data['nid'],$data['enabled'],$data['taxonomy'],$data['product_condition'],$data['upc']);
}
/**
* Load gbase info from the database
*/
function uc_cron_gbase_db_load($nid) {
$result = db_fetch_array(db_query('SELECT nid,gid,enabled,taxonomy,product_condition,new,upc,created,updated FROM {uc_cron_gbase} WHERE nid = %d', $nid));
return $result;
}
/**
* Update a product in the uc_cron_gbase table
*/
function uc_cron_gbase_db_update($data) {
$result = db_fetch_array(db_query("SELECT nid FROM {uc_cron_gbase} WHERE nid = '%d'",$data['nid']));
if(false === $result) { // Product is not in the uc_cron_gbase table, so add it instead
uc_cron_gbase_db_insert($data);
} else {
db_query("UPDATE {uc_cron_gbase} SET enabled = '%d', taxonomy = '%s', product_condition = '%d', upc = '%s', updated = NOW()
WHERE nid = '%d'",
$data['enabled'],$data['taxonomy'],$data['product_condition'],$data['upc'],$data['nid']);
}
}
/**
* Add the google id to a product
*/
function uc_cron_gbase_db_set_added($nid,$gid) {
db_query("UPDATE {uc_cron_gbase} SET gid = '%s', new = '0' WHERE nid = '%d'",$gid,$nid);
}
/**
* Delete a product from google base
*
*/
function uc_cron_gbase_db_delete($nid) {
db_query("DELETE FROM {uc_cron_gbase} WHERE nid = %d", $nid);
}
/**
* Disable a product in the uc_cron_gbase table
*/
function uc_cron_gbase_db_disable($nid) {
}
/**
* Enable a product in the uc_cron_gbase table
*/
function uc_cron_gbase_db_enable($nid) {
}
// End Database Functions
// Gbase functions
/**
* Add a product to gbase
*/
function uc_cron_gbase_add($node) {
$item = new uc_cron_gbase_xml();
global $base_url;
$uc_gbase = $node->uc_gbase;
// Link product back to owners website
// @todo find out why this is not working
$link = $item->xml->addChild('link');
$link->addAttribute('href',$base_url.'/'.$node->path);
$link->addAttribute('rel','alternative');
$link->addAttribute('type','text/html');
$item->add_attribute('item_type', 'products');
$item->add_attribute('target_language', 'en');
$item->add_attribute('target_country', variable_get('uc_cron_gbase_target_country', 'GB'));
$item->add_element('title', $node->title, 'text');
$item->add_element('content', htmlspecialchars($node->body) , 'html');
$item->add_element('summary', htmlspecialchars($node->teaser));
$item->add_attribute('id', $node->nid);
$item->add_attribute('product_type', htmlspecialchars($node->uc_cron_gbase['taxonomy']), 'text');
$item->add_attribute('price', $node->sell_price*1.175, 'floatUnit'); // @todo calculate correct tax based on ubercart
$conditions = array(0 => 'New', 1 => 'Used', 2 => 'Refurbished');
$item->add_attribute('condition', $conditions[$node->uc_cron_gbase['product_condition']]);
if ($node->shippable) {
$item->add_attribute('weight', $node->weight.' '.$node->weight_units);
$item->add_attribute('width', intval($node->width).' '.$node->length_units);
$item->add_attribute('length', intval($node->length).' '.$node->length_units);
$item->add_attribute('height', intval($node->height).' '.$node->length_units);
}
$images = uc_cron_gbase_get_image_list($node->field_image_cache);
foreach($images as $image){
$item->add_attribute('image_link', $image);
}
$headers = uc_cron_gbase_headers();
$items_feed_url = 'http://www.google.com/base/feeds/items';
$method = 'POST';
// If we have a google base id, use PUT instead of POST to perform an update
if (!empty($node->uc_cron_gbase['gid'])) {
$items_feed_url .= '/' . $node->uc_cron_gbase['gid'];
$method = 'PUT';
}
$uc_cron_gbase_xml = $item->get_xml();
$result = drupal_http_request($items_feed_url, $headers, $method, $uc_cron_gbase_xml);
if (($result->code == '200' || $result->code == '201') && !empty($result->headers['Location'])) {
$gid = substr(strrchr($result->headers['Location'], '/'), 1);
uc_cron_gbase_db_set_added($node->nid,$gid);
return TRUE;
} elseif ($result->code == '404') { // We are doing an update (see $method = 'PUT') but the product page 404'ed
if (!empty($node->uc_cron_gbase['gid'])) {
// let's try inserting this time, unset the gid so it doesn't try an update
unset($node->uc_cron_gbase['gid']);
return uc_cron_gbase_add($node);
} else {
// it's all gone fubar, give me some errors
$xml = new SimpleXMLElement($result->data);
foreach ($xml->error as $error) {
if (user_access('administer google base')) {
echo t('Google Base error: @reason', array('@reason' => (string) $error['reason']));
}
}
}
}
if (user_access('administer ubercart google base integration')) {
$xml = new SimpleXMLElement($result->data);
foreach ($xml->error as $error) {
$field = (string) $error['field'];
if (!empty($field)) {
drupal_set_message(t('Error on Google Base field %field: @reason', array('%field' => $field, '@reason' => (string) $error['reason'])), 'error');
} else {
drupal_set_message(t('Google Base error: @reason', array('@reason' => (string) $error['reason'])), 'error');
}
}
}
return FALSE;
}
/**
* Update a product on gbase
*/
function uc_cron_gbase_update($gid) {
}
/**
* Remove a product on gbase
*/
function uc_cron_gbase_remove() {
}
function uc_cron_gbase_headers() {
$token = uc_cron_gbase_token();
$developer_key = variable_get('uc_gbase_key', '');
$headers = array(
'Content-Type' => 'application/atom+xml',
'Authorization' => 'AuthSub token="' . trim($token) . '"',
);
if (!empty($developer_key)) {
$headers['X-Google-Key'] = 'key=' . $developer_key;
}
return $headers;
}
/**
* Class that has functions for adding items to gbase
*/
class uc_cron_gbase_xml {
public $xml = NULL;
protected $namespace = 'http://base.google.com/ns/1.0';
protected $draftns = 'http://www.w3.org/2005/Atom';
function __construct() {
$xmltext = "<?xml version='1.0'?>\n<entry xmlns='http://www.w3.org/2005/Atom' xmlns:g='$this->namespace'></entry>";
$this->xml = simplexml_load_string($xmltext);
}
function add_element($name, $value, $type = NULL) {
$node = $this->xml->addChild($name, $value);
if (!empty($type)) {
$node->addAttribute('type', $type);
}
}
function add_attribute($name, $value, $type = NULL) {
$node = $this->xml->addChild('g:' . $name, $value, $this->namespace);
if (!empty($type)) {
$node->addAttribute('type', $type);
}
}
function set_draft($draft = FALSE) {
$value = empty($draft) ? 'no' : 'yes';
$control = $this->xml->addChild('app:control', NULL, $this->draftns);
$node = $control->addChild('app:draft', $value, $this->draftns);
}
public function __toString() {
return $this->xml->asXML();
}
public function get_xml() {
return $this->xml->asXML();
}
}
// End Gbase functions
// Form Functions
/**
* Implemets hook_form_alter
* Modify the product node add/edit form with gbase fields
*/
function uc_cron_gbase_form_alter(&$form, $form_state, $form_id) {
if ($form['type']['#value'] == 'product') {
$form['uc_cron_gbase'] = array(
'#type' => 'fieldset',
'#title' => t('Ubercart Google Base Integration Settings'),
'#collapsible' => TRUE,
'#collapsed' => FALSE,
'#tree' => TRUE,
);
// If product should be submitted to Google Base
$form['uc_cron_gbase']['enabled'] = array(
'#type' => 'radios',
'#default_value' => !empty($node->uc_cron_gbase['enabled']) ? $node->uc_cron_gbase['enabled'] : variable_get('uc_cron_gbase_enabled','1'),
'#options' => array(
1 => t('Submit this product item to Google Merchant'),
0 => t('Do not submit this product item to Google Merchant.')
)
);
// Allow used to enter product taxonomy to googles specs
$form['uc_cron_gbase']['upc'] = array(
'#type' => 'textfield',
'#title' => t('EAN-8 UPC-14 product code'),
'#description' =>'The product\'s barcode number',
'#size' => 60,
'#maxlength' => 255,
'#default_value' => !empty($node->uc_cron_gbase['upc']) ? $node->uc_cron_gbase['upc'] : '',
);
// Allow user to enter product taxonomy to googles specs
$form['uc_cron_gbase']['taxonomy'] = array(
'#type' => 'textfield',
'#title' => t('Product Type'),
'#description' =>'The category which this Product should be listed under on Google Product Search,
You Can refer to categories on <a href="http://www.google.com/support/merchants/bin/answer.py?hl=en&answer=160081">Google Merchant Help</a>,
Or you can find the sheet on <a href="http://www.google.com/basepages/producttype/taxonomy.txt">Product Taxonomy</a>,
An example of what you should enter in this field is:<br /> Electronics > Computers > Computer Components > Storage Devices > Hard Drives
',
'#size' => 60,
'#maxlength' => 255,
'#default_value' => !empty($node->uc_cron_gbase['product_type']) ? $node->uc_cron_gbase['product_type'] : variable_get('uc_cron_gbase_default_taxonomy', ''),
);
$form['uc_cron_gbase']['product_condition'] = array(
'#type' => 'radios',
'#title' => 'Product Condition',
'#default_value' => !empty($node->uc_cron_gbase['product_condition']) ? $node->uc_cron_gbase['product_condition'] : variable_get('uc_cron_gbase_default_condition', 0),
'#options' => array(
t('New'),
t('Used'),
t('Refurbished')
)
);
} // form type value
}
/**
* Load form defaults for a node id (nid)
*/
function uc_cron_gbase_load_defaults($nid) {
}
// End Form Functions
// Cron Functions
/**
* Implements hook_cron?
* Go through all products and add/update/remove them to gbase
*/
function uc_cron_gbase_cron() {
$results = db_fetch_array(db_query('SELECT nid,gid,enabled,taxonomy,product_condition,new,upc,created,updated FROM {uc_cron_gbase}'));
dpm($results);
}
// End cron functions
// Node Functions
/**
* Implements hook_nodeapi
* Save/update/delete gbase data from db when product node is edited
*/
function uc_cron_gbase_nodeapi(&$node, $op, $a3 = NULL, $a4 = NULL) {
if($node->type == 'product') {
switch($op) {
case 'load':
$result = $node->uc_cron_gbase_id = @uc_cron_gbase_db_load($node->nid);
return array('uc_cron_gbase' => $result);
break;
case 'insert':
$node->uc_cron_gbase['nid'] = $node->nid;
uc_cron_gbase_db_insert($node->uc_cron_gbase);
break;
case 'update':
$node->uc_cron_gbase['nid'] = $node->nid;
uc_cron_gbase_db_update($node->uc_cron_gbase);
break;
case 'delete':
// @todo add remove from google base code before removing from database, if fails warn user but delete row anyway
// For it's safe to say the node will be deleted so we can't update gbase from a missing node anyways.
drupal_set_message('Product has not been removed from google base because i have not implemented this yet :)');
uc_cron_gbase_db_delete($node->nid);
break;
}
}
}
// End Node Functions
/**
* Insert all products into the gbase queue
* @todo check if they already exist
* @todo write properly, at present this was used as a hack to get everything in for testing
*/
function uc_cron_gbase_db_insert_all() {
$results = db_query("select nid from {node} WHERE type = 'product'");
while($result = db_fetch_array($results)) {
$node = node_load($result['nid']);
$node->uc_cron_gbase['nid'] = $node->nid;
$node->uc_cron_gbase['enabled'] = 1;
$node->uc_cron_gbase['taxonomy'] = 'Computers';
uc_cron_gbase_db_insert($node->uc_cron_gbase);
unset($node);
}
}
/**
* Update/Add products to google base
* @todo make into hook_cron and not be a page
*/
function uc_cron_gbase_update_all() {
// Used to calculate products that need to be renewed
$thirty_days_ago = time() - 2592000;
$thirty_days_ago = time() - 300; // 5 mins ago for testing
$results = db_query('SELECT *,UNIX_TIMESTAMP(updated) AS "timestamp" FROM {uc_cron_gbase}');
while($result = db_fetch_array($results)) {
if($result['new'] == 1 && $result['enabled'] == 1) {
$node = node_load($result['nid']);
uc_cron_gbase_add($node); // Add to Google Base
echo 'added ' . $node->nid . '<br />';
} else if($result['timestamp'] <= $thirty_days_ago && $result['enabled'] == 1 && $result['new'] == 0) {
$node = node_load($result['nid']);
uc_cron_gbase_add($node); // Update on google base
echo 'updated ' . $node->nid . '<br />';
}
unset($node); // Make sure the node is unset so does not carry over
}
}
function uc_cron_gbase_get_image_list($form_image_fields){
global $base_url;
$images = '';
//TODO: this is a kludge to suppress warnings. The data is not arriving here on save.
if(!is_array($form_image_fields)) {
return array();
}
foreach($form_image_fields as $image){
$image_item = isset($image['#default_value'])? $image['#default_value'] : $image;
if(strlen($image_item['filepath']) > 1 && !empty ($image_item['filepath']))
$images = $images.$base_url.'/'.$image_item['filepath'].'$';
}
$images_list = explode('$', $images);
array_pop($images_list);
return $images_list;
}