PluginProbe
Datafeedr API / 1.0.31
Datafeedr API v1.0.31
1.4.3 1.4.2 1.0.125 1.0.13 1.0.14 1.0.15 1.0.16 1.0.17 1.0.18 1.0.19 1.0.2 1.0.20 1.0.21 1.0.22 1.0.23 1.0.24 1.0.25 1.0.26 1.0.27 1.0.28 1.0.29 1.0.3 1.0.30 1.0.31 1.0.32 All 182 releases
datafeedr-api / functions / api.php

api.php in Datafeedr API 1.0.31, at functions/api.php

574 lines 16.7 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 function dfrapi_api_get_status() {
4 $api = dfrapi_api( dfrapi_get_transport_method() );
5 try {
6 $status = $api->getStatus();
7 dfrapi_api_update_status( $api );
8 return $status;
9 } catch( Exception $err ) {
10 return dfrapi_api_error( $err );
11 }
12
13 }
14
15 function dfrapi_get_transport_method() {
16 $configuration = (array) get_option( 'dfrapi_configuration' );
17 $transport = ( isset( $configuration['transport_method'] ) ) ? $configuration['transport_method'] : $transport;
18 return $transport;
19 }
20
21 /**
22 * This instantiates the Datafeedr API Library and returns the $api object.
23 */
24 function dfrapi_api( $transport='curl', $timeout=0, $returnObjects=FALSE ) {
25
26 $configuration = (array) get_option( 'dfrapi_configuration' );
27
28 $access_id = false;
29 $secret_key = false;
30 $transport = dfrapi_get_transport_method();
31
32 if ( isset( $configuration['access_id'] ) && ( $configuration['access_id'] != '' ) ) {
33 $access_id = $configuration['access_id'];
34 }
35
36 if ( isset( $configuration['secret_key'] ) && ( $configuration['secret_key'] != '' ) ) {
37 $secret_key = $configuration['secret_key'];
38 }
39
40 if ( $access_id && $secret_key ) {
41 $api = new DatafeedrApi( $access_id, $secret_key, $transport, $timeout, $returnObjects );
42 return $api;
43 } else {
44 return false;
45 }
46 }
47
48 /**
49 * Creates an associate array with the API's error details.
50 */
51 function dfrapi_api_error( $error, $params=FALSE ) {
52
53 // Change "request_count" to "max_requests" because sometimes there's
54 // not even enough API requests left to update the Account info with
55 // the most update to date information.
56 if ( $error->getCode() == 301 ) {
57 $account = get_option( 'dfrapi_account', array() );
58 $account['request_count'] = $account['max_requests'];
59 update_option( 'dfrapi_account', $account );
60 }
61
62 return array(
63 'dfrapi_api_error' => array(
64 'class' => get_class( $error ),
65 'code' => $error->getCode(),
66 'msg' => $error->getMessage(),
67 'params' => $params,
68 )
69 );
70 }
71
72 /**
73 * Creates the proper API request from the $query.
74 */
75 function dfrapi_api_query_to_filters( $query, $useSelected=TRUE ) {
76 $sform = new Dfrapi_SearchForm();
77 return $sform->makeFilters( $query, $useSelected );
78 }
79
80 /**
81 * Returns a parameter value from the $query array.
82 */
83 function dfrapi_api_get_query_param( $query, $param ) {
84 if ( is_array( $query ) && !empty( $query ) ) {
85 foreach( $query as $k => $v ) {
86 if ( $v['field'] == $param ) {
87 return array(
88 'field' => @$v['field'],
89 'operator' => @$v['operator'],
90 'value' => @$v['value'],
91 );
92 }
93 }
94 }
95 return false;
96 }
97
98 /**
99 * This updates the "dfrapi_account" option with the most recent
100 * API status information for this user.
101 */
102 function dfrapi_api_update_status( &$api ) {
103 if ( $status = $api->lastStatus() ) {
104 $account = get_option( 'dfrapi_account', array() );
105 $account['user_id'] = $status['user_id'];
106 $account['plan_id'] = $status['plan_id'];
107 $account['bill_day'] = $status['bill_day'];
108 $account['max_total'] = $status['max_total'];
109 $account['max_length'] = $status['max_length'];
110 $account['max_requests'] = $status['max_requests'];
111 $account['request_count'] = $status['request_count'];
112 $account['network_count'] = $status['network_count'];
113 $account['product_count'] = $status['product_count'];
114 $account['merchant_count'] = $status['merchant_count'];
115 update_option( 'dfrapi_account', $account );
116 }
117 }
118
119 /**
120 * This returns all affiliate networks' information.
121 * This accepts an array of source_ids (network ids)
122 * to return a subset of networks.
123 */
124 function dfrapi_api_get_all_networks( $nids=array() ) {
125 $option_name = 'dfrapi_all_networks';
126 $use_cache = wp_using_ext_object_cache( false );
127 $networks = get_transient( $option_name );
128 wp_using_ext_object_cache( $use_cache );
129 if ( false === $networks || empty ( $networks ) ) {
130 $api = dfrapi_api( dfrapi_get_transport_method() );
131 try {
132 $networks = $api->getNetworks( $nids, TRUE );
133 dfrapi_api_set_network_types( $networks );
134 dfrapi_api_update_status( $api );
135 } catch( Exception $err ) {
136 return dfrapi_api_error( $err );
137 }
138 $use_cache = wp_using_ext_object_cache( false );
139 set_transient( $option_name, $networks, DAY_IN_SECONDS );
140 wp_using_ext_object_cache( $use_cache );
141 }
142 dfrapi_update_transient_whitelist( $option_name );
143 return $networks;
144 }
145
146 /**
147 * Returns a Zanox zmid value.
148 */
149 function dfrapi_api_get_zanox_zmid( $merchant_id, $adspace_id ) {
150 $option_name = 'zmid_' . $merchant_id . '_' . $adspace_id;
151 $use_cache = wp_using_ext_object_cache( false );
152 $zanox = get_transient( $option_name );
153 wp_using_ext_object_cache( $use_cache );
154 if ( $zanox === FALSE || empty ( $zanox ) ) {
155 $api = dfrapi_api( dfrapi_get_transport_method() );
156 try {
157 $zanox_keys = dfrapi_get_zanox_keys();
158 $zanox = $api->getZanoxMerchantIds( $merchant_id, $adspace_id, $zanox_keys['connection_key'] );
159 // If $zanox is empty, that means this user is not approved by this merchant.
160 if ( empty( $zanox ) ) {
161 $zanox = 'dfrapi_unapproved_zanox_merchant';
162 }
163 } catch( Exception $err ) {
164 return dfrapi_api_error( $err );
165 }
166 $use_cache = wp_using_ext_object_cache( false );
167 set_transient( $option_name, $zanox, WEEK_IN_SECONDS );
168 wp_using_ext_object_cache( $use_cache );
169 }
170 dfrapi_update_transient_whitelist( $option_name );
171 return $zanox;
172 }
173
174 /**
175 * This creates 2 options in the options table each time the option
176 * "dfrapi_all_networks" is updated with new network information from the API.
177 *
178 * - dfrapi_product_networks
179 * - dfrapi_coupon_networks
180 *
181 * These are just helper options to figure out if a network is a "product"
182 * network or a "coupon" network.
183 */
184 function dfrapi_api_set_network_types( $networks ) {
185 $product_networks = array();
186 $coupon_networks = array();
187 foreach( $networks as $network ) {
188 if ( $network['type'] == 'products' ) {
189 $product_networks[$network['_id']] = $network;
190 } elseif ( $network['type'] == 'coupons' ) {
191 $coupon_networks[$network['_id']] = $network;
192 }
193 }
194 update_option( 'dfrapi_product_networks', $product_networks );
195 update_option( 'dfrapi_coupon_networks', $coupon_networks );
196 }
197
198 /**
199 * This stores all merchants for a given source_id ($nid).
200 *
201 * It is possible to pass "all" to this function however this creates
202 * memory_limit errors when memory is set to less than 64MB.
203 */
204 function dfrapi_api_get_all_merchants( $nid ) {
205 $option_name = 'dfrapi_all_merchants_for_nid_' . $nid;
206 $use_cache = wp_using_ext_object_cache( false );
207 $merchants = get_transient( $option_name );
208 wp_using_ext_object_cache( $use_cache );
209 if ( false === $merchants || empty ( $merchants ) ) {
210 $api = dfrapi_api( dfrapi_get_transport_method() );
211 try {
212 $merchants = $api->getMerchants( array( intval( $nid ) ), TRUE );
213 dfrapi_api_update_status( $api );
214 } catch( Exception $err ) {
215 return dfrapi_api_error( $err );
216 }
217 $use_cache = wp_using_ext_object_cache( false );
218 set_transient( $option_name, $merchants, DAY_IN_SECONDS );
219 wp_using_ext_object_cache( $use_cache );
220 }
221 dfrapi_update_transient_whitelist( $option_name );
222 return $merchants;
223 }
224
225 /**
226 * This retuns merchant or merchants' information by merchant_id or
227 * an array of merchant IDs.
228 */
229 function dfrapi_api_get_merchants_by_id( $ids, $includeEmpty=FALSE ) {
230 $name = false;
231 if ( is_array( $ids ) ) {
232 sort( $ids, SORT_NUMERIC );
233 $id_string = implode( ",", $ids );
234 $name = md5( $id_string );
235 } elseif ( $ids != '' ) {
236 $name = trim( $ids );
237 }
238 if ( !$name ) { return; }
239 $name = substr( $name, 0, 20 );
240 $option_name = 'dfrapi_merchants_byid_' . $name;
241 $use_cache = wp_using_ext_object_cache( false );
242 $merchants = get_transient( $option_name );
243 wp_using_ext_object_cache( $use_cache );
244 if ( false === $merchants || empty ( $merchants ) ) {
245 $api = dfrapi_api( dfrapi_get_transport_method() );
246 try {
247 $merchants = $api->getMerchantsById( $ids, $includeEmpty );
248 dfrapi_api_update_status( $api );
249 } catch( Exception $err ) {
250 return dfrapi_api_error( $err );
251 }
252 $use_cache = wp_using_ext_object_cache( false );
253 set_transient( $option_name, $merchants, DAY_IN_SECONDS );
254 wp_using_ext_object_cache( $use_cache );
255 }
256 dfrapi_update_transient_whitelist( $option_name );
257 return $merchants;
258 }
259
260 /**
261 * Returns a $response array containing:
262 * - ids: the query passed to the function.
263 * - products: array of products.
264 * - last_status: value of $api->lastStatus().
265 * - found_count: value of $search->getFoundCount().
266 *
267 * If the API throws an exception, that will return dfrapi_api_error( $err );
268 *
269 * @param array $ids An array of product IDs.
270 * @param int $ppp The number of products to return in 1 API request. Max is dictated by API, not plugin.
271 * @param int $page The page number for returning products. This is used to figure the offset.
272 */
273 function dfrapi_api_get_products_by_id( $ids, $ppp=20, $page=1 ) {
274
275 $response = array();
276
277 // Return false if no $ids or no $postid
278 if ( empty( $ids ) ) { return $response; }
279
280 // Make sure $page is a positive integer.
281 $page = intval( abs( $page ) );
282
283 // Make sure $ppp is a positive integer.
284 $ppp = intval( abs( $ppp ) );
285
286 // Make sure $ppp is not greater than "max_length".
287 $account = (array) get_option( 'dfrapi_account' );
288 if ( $ppp > $account['max_length'] ) {
289 $ppp = $account['max_length'];
290 }
291
292 // The maximum number of results a request to the API can return.
293 // Changing this will only break your site. It's not overridable.
294 $max_total = $account['max_total'];
295
296 // Determine offset.
297 $offset = ( ( $page - 1 ) * $ppp );
298
299 // Make sure $limit doesn't go over 10,000.
300 if ( ( $offset + $ppp ) > $max_total ) {
301 $ppp = ( $max_total - $offset );
302 }
303
304 // If $ppp is negative, return empty array();
305 if ( $ppp < 1 ) {
306 return array();
307 }
308
309 // If offset is greater than 10,000 return empty array();
310 if ( $offset >= ( $max_total - $ppp ) ) {
311 return array();
312 }
313
314 try {
315
316 // Initialize API.
317 $api = dfrapi_api( dfrapi_get_transport_method() );
318 if ( ! $api ) {
319 return $response;
320 }
321
322 // Get a range of product IDs to query.
323 $id_range = array_slice( $ids, $offset, $ppp );
324
325 // Return immediately if $id_range is empty.
326 if ( empty( $id_range ) ) {
327 $response['ids'] = array();
328 $response['products'] = array();
329 $response['last_status'] = $api->lastStatus();
330 $response['found_count'] = 0;
331
332 return $response;
333 }
334
335 // Begin query
336 $search = $api->searchRequest();
337
338 // Get filters
339 $filters = dfrapi_api_query_to_filters( array() );
340 if ( isset( $filters['error'] ) ) {
341 throw new DatafeedrError( $filters['error'], 0 );
342 }
343
344 // Loop thru filters.
345 foreach ( $filters as $filter ) {
346 $search->addFilter( $filter );
347 }
348
349 $search->addFilter( 'id IN ' . implode( ",", $id_range ) );
350 $search->setLimit( $ppp );
351 $products = $search->execute();
352
353 // Keep track of IDs which were returned via the API to compare with $id_range (unreturned)
354 $included_ids = array();
355 if ( ! empty( $products ) ) {
356 foreach ( $products as $product ) {
357 $included_ids[] = $product['_id'];
358 }
359 }
360
361 // Excluded product IDs.
362 $excluded_ids = array_diff( $id_range, $included_ids );
363
364 // Add "message" values to excluded IDs if there are some.
365 $excluded_products = array();
366 if ( ! empty( $included_ids ) && ! empty( $excluded_ids ) ) {
367 foreach ( $excluded_ids as $excluded_id ) {
368
369 $wc_url = add_query_arg(
370 array(
371 's' => $excluded_id,
372 'post_status' => 'trash',
373 'post_type' => 'product',
374 ),
375 admin_url( 'edit.php' )
376 );
377
378 // Do not add a 'url' field to this array or the unavailable product WILL be imported.
379 // See /datafeedr-product-sets/classes/class-dfrps-update.php:73
380 $excluded_products[] = array(
381 '_id' => $excluded_id,
382 '_wc_url' => $wc_url,
383 'name' => $excluded_id . ' - ' . __( 'Unavailable', DFRAPI_DOMAIN ),
384 'price' => 0,
385 'finalprice' => 0,
386 'description' => __( 'This product is either temporarily or permanently unavailable.', DFRAPI_DOMAIN ),
387 'image' => DFRAPI_URL . 'images/icons/noimage.png',
388 'merchant' => 'n/a',
389 'source' => 'n/a',
390 );
391 }
392 }
393
394 // Update API status
395 dfrapi_api_update_status( $api );
396
397 // Build $response array().
398 $response['ids'] = $ids;
399 $response['products'] = array_merge( $products, $excluded_products );
400 $response['last_status'] = $api->lastStatus();
401 $response['found_count'] = count( $ids );
402 $response['params'] = $search->getParams();
403
404 // Return it!
405 return $response;
406
407 } catch( Exception $err ) {
408 return dfrapi_api_error( $err );
409 }
410 }
411
412 /**
413 * Returns a $response array containing:
414 * - query: the query passed to the function.
415 * - excluded: ids of excluded products.
416 * - products: array of products.
417 * - last_status: value of $api->lastStatus().
418 * - found_count: value of $search->getFoundCount().
419 * - params: value of $search->getParams().
420 *
421 * Example of $query array():
422 *
423 *
424 * $query[] = array(
425 * 'value' => 'shoes',
426 * 'field' => 'any',
427 * 'operator' => 'contain'
428 * );
429 *
430 * $query[] = array(
431 * 'value' => 'image',
432 * 'field' => 'duplicates',
433 * 'operator' => 'is'
434 * );
435 *
436 * $query[] = array(
437 * 'field' => 'sort',
438 * 'operator' => '+saleprice'
439 * );
440 *
441 *
442 * If the API throws an exception, that will return dfrapi_api_error( $err, $params );
443 *
444 * @param array $query The complete query to pass to the API.
445 * @param int $ppp The number of products to return in 1 API request. Max is dictated by API, not plugin.
446 * @param int $page The page number for returning products. This is used to figure the offset.
447 * @param array $excluded An array of product IDs to exclude from being returned.
448 */
449 function dfrapi_api_get_products_by_query( $query, $ppp=20, $page=1, $excluded=array() ) {
450
451 $response = array();
452
453 // Return false if no $query.
454 if ( empty( $query ) ) { return $response; }
455
456 // Make sure $page is a positive integer.
457 $page = intval( abs( $page ) );
458
459 // Make sure $ppp is a positive integer.
460 $ppp = intval( abs( $ppp ) );
461
462 // Make sure $ppp is not greater than "max_length".
463 $account = (array) get_option( 'dfrapi_account' );
464 if ( $ppp > $account['max_length'] ) {
465 $ppp = $account['max_length'];
466 }
467
468 // The maximum number of results a request to the API can return.
469 // Changing this will only break your site. It's not overridable.
470 $max_total = $account['max_total'];
471
472 // Detemine query limit (if exists).
473 $query_limit = dfrapi_api_get_query_param( $query, 'limit' );
474 $query_limit = ( $query_limit )
475 ? $query_limit['value']
476 : false;
477
478 // No query shall try to return more than 10,000 products.
479 if ( $query_limit && ( $query_limit > $max_total ) ) {
480 $query_limit = $max_total;
481 }
482
483 // Determine offset.
484 $offset = ( ( $page - 1 ) * $ppp );
485
486 // If offset is greater than 10,000 return empty array();
487 if ( $offset >= $max_total ) {
488 return array();
489 }
490
491 // Factor in query limit
492 if ( $query_limit ) {
493 if ( ( $ppp + $offset ) > $query_limit ) {
494 $ppp = ( $query_limit - $offset );
495 }
496 }
497
498 // Make sure $limit doesn't go over 10,000.
499 if ( ( $offset + $ppp ) > $max_total ) {
500 $ppp = ( $max_total - $offset );
501 }
502
503 // If $ppp is negative, return empty array();
504 if ( $ppp < 1 ) {
505 return $response;
506 }
507
508 try {
509
510 // Initialize API.
511 $api = dfrapi_api( dfrapi_get_transport_method() );
512 if ( !$api ) { return $response; }
513
514 $search = $api->searchRequest();
515
516 // Get filters
517 $filters = dfrapi_api_query_to_filters( $query );
518 if(isset($filters['error'])) {
519 throw new DatafeedrError($filters['error'], 0);
520 }
521
522 // Loop thru filters.
523 foreach ( $filters as $filter ) {
524 $search->addFilter( $filter );
525 }
526
527 // Exclude duplicates.
528 $duplicates = dfrapi_api_get_query_param( $query, 'duplicates' );
529 if ( $duplicates ) {
530 $excludes = $duplicates['value'];
531 $search->excludeDuplicates( $excludes );
532 }
533
534 // Exclude blocked products.
535 $excluded = (array) $excluded;
536 if ( !empty( $excluded ) ) {
537 $search->addFilter('id !IN ' . implode( ",", $excluded ) );
538 }
539
540 // Sort products.
541 $sort = dfrapi_api_get_query_param( $query, 'sort' );
542 if( $sort && strlen( $sort['operator'] ) ) {
543 $search->addSort( $sort['operator'] );
544 }
545
546 // Set limits and offset.
547 $search->setLimit( $ppp );
548 $search->setOffset( $offset );
549
550 // Execute query.
551 $products = $search->execute();
552
553 // Update API status
554 dfrapi_api_update_status( $api );
555
556 // Build $response array().
557 $response['query'] = $query;
558 $response['excluded'] = $excluded;
559 $response['products'] = $products;
560 $response['last_status'] = $api->lastStatus();
561 //$response['found_count'] = $search->getFoundCount(); Old, returned wrong value (#8672)
562 $response['found_count'] = $search->getResultCount();
563 $response['params'] = $search->getParams();
564
565 // Return it!
566 return $response;
567
568 } catch( Exception $err ) {
569 $params = $search->getParams();
570 return dfrapi_api_error( $err, $params );
571
572 }
573 }
574