PluginProbe
Datafeedr API / 1.4.3
Datafeedr API v1.4.3
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 / classes / class-dfrapi-searchform.php

class-dfrapi-searchform.php in Datafeedr API 1.4.3, at classes/class-dfrapi-searchform.php

1,137 lines 52.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 defined( 'ABSPATH' ) || exit;
4
5
6 class Dfrapi_SearchForm
7 {
8 function fields() {
9
10 $opFulltext = array(
11 'match' => __( 'matches', 'datafeedr-api' ),
12 'contain' => __( 'contains', 'datafeedr-api' ),
13 'not_contain' => __( 'doesn\'t contain', 'datafeedr-api' ),
14 'start' => __( 'starts with', 'datafeedr-api' ),
15 'end' => __( 'ends with', 'datafeedr-api' ),
16 );
17
18 $opFulltextExact = array_merge( $opFulltext, array(
19 'is' => __( 'is', 'datafeedr-api' )
20 ) );
21
22 $opRange = array(
23 'eq' => __( 'equal to', 'datafeedr-api' ),
24 'lt' => __( 'less than', 'datafeedr-api' ),
25 'lte' => __( 'less than or equal to', 'datafeedr-api' ),
26 'gt' => __( 'greater than', 'datafeedr-api' ),
27 'gte' => __( 'greater than or equal to', 'datafeedr-api' ),
28 'between' => __( 'between', 'datafeedr-api' )
29 );
30
31 $opIs = array(
32 'is' => __( 'is', 'datafeedr-api' )
33 );
34
35 $opIsIsnt = array(
36 'is' => __( 'is', 'datafeedr-api' ),
37 'is_not' => __( 'isn\'t', 'datafeedr-api' )
38 );
39
40 $opYesNo = array(
41 'yes' => __( 'yes', 'datafeedr-api' ),
42 'no' => __( 'no', 'datafeedr-api' )
43 );
44
45 $opInStock = array(
46 'yes_unknown' => __( 'yes or unknown', 'datafeedr-api' ),
47 'yes' => __( 'yes', 'datafeedr-api' ),
48 'no' => __( 'no', 'datafeedr-api' ),
49 );
50
51 $sortOpts = array(
52 '' => __( 'Relevance', 'datafeedr-api' ),
53 '+price' => __( 'Price Ascending', 'datafeedr-api' ),
54 '-price' => __( 'Price Descending', 'datafeedr-api' ),
55 '+saleprice' => __( 'Sale Price Ascending', 'datafeedr-api' ),
56 '-saleprice' => __( 'Sale Price Descending', 'datafeedr-api' ),
57 '+finalprice' => __( 'Final Price Ascending', 'datafeedr-api' ),
58 '-finalprice' => __( 'Final Price Descending', 'datafeedr-api' ),
59 '+salediscount' => __( 'Discount Ascending', 'datafeedr-api' ),
60 '-salediscount' => __( 'Discount Descending', 'datafeedr-api' ),
61 '+merchant' => __( 'Merchant', 'datafeedr-api' ),
62 '+time_updated' => __( 'Last Updated Ascending', 'datafeedr-api' ),
63 '-time_updated' => __( 'Last Updated Descending', 'datafeedr-api' ),
64 '+_id' => __( 'Product ID Ascending', 'datafeedr-api' ),
65 '-_id' => __( 'Product ID Descending', 'datafeedr-api' ),
66 );
67
68 return array(
69 array(
70 'title' => __( 'Any Field', 'datafeedr-api' ),
71 'name' => 'any',
72 'input' => 'text',
73 'operator' => $opFulltext,
74 'help' => $this->help( 'any' )
75 ),
76 array(
77 'title' => __( 'Product Name', 'datafeedr-api' ),
78 'name' => 'name',
79 'input' => 'text',
80 'operator' => $opFulltextExact,
81 'help' => $this->help( 'name' )
82 ),
83 array(
84 'title' => __( 'Product ID', 'datafeedr-api' ),
85 'name' => 'id',
86 'input' => 'text',
87 'operator' => $opIsIsnt,
88 'help' => $this->help( 'id' )
89 ),
90 array(
91 'title' => __( 'Barcode', 'datafeedr-api' ),
92 'name' => 'barcode',
93 'input' => 'text',
94 'operator' => $opIsIsnt,
95 'help' => $this->help( 'barcode' )
96 ),
97 array(
98 'title' => __( 'Brand', 'datafeedr-api' ),
99 'name' => 'brand',
100 'input' => 'text',
101 'operator' => $opFulltextExact,
102 'help' => $this->help( 'brand' )
103 ),
104 array(
105 'title' => __( 'Color', 'datafeedr-api' ),
106 'name' => 'color',
107 'input' => 'text',
108 'operator' => $opFulltextExact,
109 'help' => $this->help( 'color' )
110 ),
111 array(
112 'title' => __( 'Material', 'datafeedr-api' ),
113 'name' => 'material',
114 'input' => 'text',
115 'operator' => $opFulltextExact,
116 'help' => $this->help( 'material' )
117 ),
118 array(
119 'title' => __( 'Size', 'datafeedr-api' ),
120 'name' => 'size',
121 'input' => 'text',
122 'operator' => $opFulltextExact,
123 'help' => $this->help( 'size' )
124 ),
125 array(
126 'title' => __( 'Gender', 'datafeedr-api' ),
127 'name' => 'gender',
128 'input' => 'text',
129 'operator' => $opFulltextExact,
130 'help' => $this->help( 'gender' )
131 ),
132 array(
133 'title' => __( 'SKU', 'datafeedr-api' ),
134 'name' => 'sku',
135 'input' => 'text',
136 'operator' => $opFulltextExact,
137 'help' => $this->help( 'sku' )
138 ),
139 array(
140 'title' => __( 'Condition', 'datafeedr-api' ),
141 'name' => 'condition',
142 'input' => 'text',
143 'operator' => $opFulltextExact,
144 'help' => $this->help( 'condition' )
145 ),
146 array(
147 'title' => __( 'Description', 'datafeedr-api' ),
148 'name' => 'description',
149 'input' => 'text',
150 'operator' => $opFulltext,
151 'help' => $this->help( 'description' )
152 ),
153 array(
154 'title' => __( 'Tags', 'datafeedr-api' ),
155 'name' => 'tags',
156 'input' => 'text',
157 'operator' => array(
158 'in' => __( 'contain', 'datafeedr-api' ),
159 'not_in' => __( 'don\'t contain', 'datafeedr-api' )
160 ),
161 'help' => $this->help( 'tags' )
162 ),
163 array(
164 'title' => __( 'Category', 'datafeedr-api' ),
165 'name' => 'category',
166 'input' => 'text',
167 'operator' => $opFulltext,
168 'help' => $this->help( 'category' )
169 ),
170 array(
171 'title' => __( 'Product Type', 'datafeedr-api' ),
172 'name' => 'type',
173 'input' => 'select',
174 'options' => array(
175 'products' => __( 'Product', 'datafeedr-api' ),
176 'coupons' => __( 'Coupon', 'datafeedr-api' )
177 ),
178 'operator' => $opIs,
179 'help' => $this->help( 'type' )
180 ),
181 array(
182 'title' => __( 'Currency', 'datafeedr-api' ),
183 'name' => 'currency',
184 'input' => 'select',
185 'options' => array(
186 'AUD' => 'AUD',
187 'BRL' => 'BRL',
188 'CAD' => 'CAD',
189 'CHF' => 'CHF',
190 'CZK' => 'CZK',
191 'DKK' => 'DKK',
192 'EUR' => 'EUR',
193 'GBP' => 'GBP',
194 'INR' => 'INR',
195 'NOK' => 'NOK',
196 'NZD' => 'NZD',
197 'PLN' => 'PLN',
198 'SEK' => 'SEK',
199 'TRY' => 'TRY',
200 'USD' => 'USD',
201 ),
202 'operator' => $opIsIsnt,
203 'help' => $this->help( 'currency' )
204 ),
205 array(
206 'title' => __( 'Price', 'datafeedr-api' ),
207 'name' => 'price',
208 'input' => 'range',
209 'operator' => $opRange,
210 'help' => $this->help( 'price' )
211 ),
212 array(
213 'title' => __( 'Sale Price', 'datafeedr-api' ),
214 'name' => 'saleprice',
215 'input' => 'range',
216 'operator' => $opRange,
217 'help' => $this->help( 'saleprice' )
218 ),
219 array(
220 'title' => __( 'Final Price', 'datafeedr-api' ),
221 'name' => 'finalprice',
222 'input' => 'range',
223 'operator' => $opRange,
224 'help' => $this->help( 'finalprice' )
225 ),
226 array(
227 'title' => __( 'Discount', 'datafeedr-api' ),
228 'name' => 'salediscount',
229 'input' => 'range',
230 'operator' => $opRange,
231 'help' => $this->help( 'salediscount' )
232 ),
233 array(
234 'title' => __( 'Network', 'datafeedr-api' ),
235 'name' => 'source_id',
236 'input' => 'network',
237 'operator' => $opIsIsnt,
238 'help' => $this->help( 'source_id' )
239 ),
240 array(
241 'title' => __( 'Merchant', 'datafeedr-api' ),
242 'name' => 'merchant_id',
243 'input' => 'merchant',
244 'operator' => $opIsIsnt,
245 'help' => $this->help( 'merchant_id' )
246 ),
247 array(
248 'title' => __( 'On Sale', 'datafeedr-api' ),
249 'name' => 'onsale',
250 'input' => 'none',
251 'operator' => $opYesNo,
252 'help' => $this->help( 'onsale' )
253 ),
254 array(
255 'title' => __( 'In Stock', 'datafeedr-api' ),
256 'name' => 'instock',
257 'input' => 'none',
258 'operator' => $opInStock,
259 'help' => $this->help( 'instock' )
260 ),
261 array(
262 'title' => __( 'Stock Quantity', 'datafeedr-api' ),
263 'name' => 'stockquantity',
264 'input' => 'range',
265 'operator' => $opRange,
266 'help' => $this->help( 'instock' )
267 ),
268 array(
269 'title' => __( 'Has Direct URL', 'datafeedr-api' ),
270 'name' => 'direct_url',
271 'input' => 'none',
272 'operator' => $opYesNo,
273 'help' => $this->help( 'direct_url' )
274 ),
275 array(
276 'title' => __( 'Has Image', 'datafeedr-api' ),
277 'name' => 'image',
278 'input' => 'none',
279 'operator' => $opYesNo,
280 'help' => $this->help( 'image' )
281 ),
282 array(
283 'title' => __( 'Has Barcode', 'datafeedr-api' ),
284 'name' => 'has_barcode',
285 'input' => 'none',
286 'operator' => $opYesNo,
287 'help' => $this->help( 'has_barcode' )
288 ),
289 array(
290 'title' => __( 'Last Updated', 'datafeedr-api' ),
291 'name' => 'time_updated',
292 'input' => 'range',
293 'operator' => array( 'lt' => 'before', 'gt' => 'after', 'between' => 'between' ),
294 'help' => $this->help( 'time_updated' )
295 ),
296 array(
297 'title' => __( 'Limit', 'datafeedr-api' ),
298 'name' => 'limit',
299 'input' => 'text',
300 'operator' => array( 'is' => 'is' ),
301 'help' => $this->help( 'limit' )
302 ),
303 array(
304 'title' => __( 'Merchant Limit', 'datafeedr-api' ),
305 'name' => 'merchant_limit',
306 'input' => 'select',
307 'options' => array_filter( range( 0, 10 ), function ( $num ) {
308 return $num != 0;
309 } ),
310 'operator' => array( 'is' => 'is' ),
311 'help' => $this->help( 'merchant_limit' )
312 ),
313 array(
314 'title' => __( 'Sort By', 'datafeedr-api' ),
315 'name' => 'sort',
316 'input' => 'none',
317 'operator' => $sortOpts,
318 'help' => $this->help( 'sort' )
319 ),
320 array(
321 'title' => __( 'Exclude Duplicates', 'datafeedr-api' ),
322 'name' => 'duplicates',
323 'input' => 'text',
324 'operator' => array(
325 'is' => __( 'matching these fields', 'datafeedr-api' ),
326 ),
327 'help' => $this->help( 'duplicates' )
328 )
329 );
330 }
331
332 function defaults() {
333 return array(
334 'any' => array( 'operator' => 'match', 'value' => '' ),
335 'id' => array( 'operator' => 'is', 'value' => '' ),
336 'barcode' => array( 'operator' => 'is', 'value' => '' ),
337 'name' => array( 'operator' => 'match', 'value' => '' ),
338 'brand' => array( 'operator' => 'match', 'value' => '' ),
339 'color' => array( 'operator' => 'match', 'value' => '' ),
340 'material' => array( 'operator' => 'match', 'value' => '' ),
341 'size' => array( 'operator' => 'match', 'value' => '' ),
342 'gender' => array( 'operator' => 'match', 'value' => '' ),
343 'sku' => array( 'operator' => 'match', 'value' => '' ),
344 'condition' => array( 'operator' => 'match', 'value' => '' ),
345 'type' => array( 'value' => 'product' ),
346 'currency' => array( 'value' => 'USD' ),
347 'price' => array( 'operator' => 'between', 'value' => '0', 'value2' => '999999' ),
348 'saleprice' => array( 'operator' => 'between', 'value' => '0', 'value2' => '999999' ),
349 'source_id' => array( 'value' => array() ),
350 'merchant_id' => array( 'value' => array() ),
351 'onsale' => array( 'value' => '1' ),
352 'instock' => array( 'value' => 'yes_unknown' ),
353 'stockquantity' => array( 'operator' => 'between', 'value' => '0', 'value2' => '100' ),
354 'direct_url' => array( 'value' => '1' ),
355 'image' => array( 'value' => '1' ),
356 'has_barcode' => array( 'value' => '1' ),
357 'thumbnail' => array( 'value' => '1' ),
358 'time_updated' => array( 'operator' => 'lt', 'value' => 'today' ),
359 'limit' => array( 'value' => 1000 ),
360 'merchant_limit' => array( 'value' => 5 ),
361 );
362 }
363
364 public $useSelected;
365 public $prefix;
366
367 function get($ary, $key, $default="") {
368 return is_array($ary) && isset($ary[$key]) ? $ary[$key] : $default;
369 }
370
371 function inputPrefix($index) {
372 return sprintf('%s[%s]', $this->prefix ? $this->prefix : "query", $index);
373 }
374
375 function byName($a, $b) {
376 return strcasecmp($a['name'], $b['name']);
377 }
378
379 function ary($s) {
380 if(!is_array($s))
381 $s = explode(',', trim($s));
382 return array_filter($s, 'strlen');
383 }
384
385 function ids($lst) {
386 $ids = array();
387 foreach($lst as $obj)
388 $ids []= $obj['_id'];
389 return $ids;
390 }
391
392 function selectOpts($opts, $selectedValue=NULL) {
393 $html = "";
394 foreach($opts as $value => $title) {
395 $sel = $selectedValue == $value ? "selected='selected'" : "";
396 $title = htmlspecialchars($title);
397 $value = htmlspecialchars($value);
398 $html .= "<option value=\"$value\" $sel>$title</option>";
399 }
400 return $html;
401 }
402
403 function allNetworks() {
404 $lst = dfrapi_api_get_all_networks();
405 usort($lst, array($this, 'byName'));
406 return $lst;
407 }
408
409 function selectedNetworks() {
410 $selected = $this->get(get_option( 'dfrapi_networks' ), 'ids');
411 if(empty($selected))
412 return array();
413
414 $lst = array();
415 foreach($this->allNetworks() as $net)
416 if(isset($selected[$net['_id']]))
417 $lst []= $net;
418 return $lst;
419 }
420
421 function groupClass($nid) {
422 if (empty($nid)) { return ''; }
423 $networks = $this->allNetworks();
424 foreach($networks as $network) {
425 if ($network['_id'] == $nid) {
426 $name = str_replace( array( " ", "-", "." ), "", $network['group'] );
427 $type = ( $network['type'] == 'coupons' ) ? '_coupons' : '';
428 return 'network_logo_16x16_' . strtolower( $name . $type );
429 }
430 }
431 }
432
433 function selectedMerchants() {
434 $selected = $this->get(get_option( 'dfrapi_merchants' ), 'ids');
435 if(empty($selected))
436 return array();
437
438 $lst = array();
439 foreach(dfrapi_api_get_merchants_by_id($selected) as $merchant) {
440 $lst []= $merchant;
441 }
442 usort($lst, array($this, 'byName'));
443 return $lst;
444 }
445
446 function networksMerchantsPopup($kind, $value) {
447 $title = array(
448 'network' => __( 'Select Networks', 'datafeedr-api' ),
449 'merchant' => __( 'Select Merchants', 'datafeedr-api' )
450 );
451 $clear = __( 'Clear search', 'datafeedr-api' );
452 $ok = __( 'OK', 'datafeedr-api' );
453 $cells = "";
454
455 $all = ($kind == 'network') ?
456 ($this->useSelected ? $this->selectedNetworks() : $this->allNetworks()) :
457 $this->selectedMerchants();
458
459 foreach($all as $obj) {
460 $id = absint($obj['_id']);
461 $nid = absint(($kind == 'network') ? $obj['_id'] : $obj['source_id']);
462 $group_class = esc_attr($this->groupClass($nid));
463
464 $name = esc_html($obj['name']);
465 $checked = in_array($id, $value) ? "checked='checked'" : "";
466
467 $cells .= "
468 <div class='inline_frame_element nid_{$nid}'>
469 <label>
470 <input type='checkbox' value='{$id}' $checked />
471 <span class='element_name {$group_class}'>{$name}</span>
472 </label>
473 </div>
474 ";
475 }
476
477 return "
478 <h1>{$title[$kind]}</h1>
479 <div class='filter_action'>
480 Search: <input type='text' />
481 <a class='reset_search button' title='{$clear}'>&times;</a>
482 </div>
483 <div class='inline_frame'>
484 <div>
485 {$cells}
486 <div class='clearfix'></div>
487 </div>
488 </div>
489 <div><a class='button submit'>$ok</a></div>
490 ";
491 }
492
493 function networksMerchantsNames($kind, $value, $maxNames=5) {
494 $all = ($kind == 'network') ? $this->allNetworks() : dfrapi_api_get_merchants_by_id($value);
495 $names = array();
496 foreach($all as $obj) {
497 if(in_array($obj['_id'], $value)) {
498 $names []= '<span>' . esc_html($obj['name']) . '</span>';
499 if(count($names) >= $maxNames)
500 break;
501 }
502 }
503 $html = implode(', ', $names);
504 if(count($value) - count($names)) {
505 $html .= ' ' . sprintf(__( 'and %s more', 'datafeedr-api' ), count($value) - count($names));
506 }
507 return $html;
508 }
509
510 function chooseBox($kind, $field, $index, $value) {
511 $pfx = $this->inputPrefix($index);
512 $value = esc_attr(implode(',', $this->ary($value)));
513 $choose = __( 'choose', 'datafeedr-api' );
514 return "
515 <div class='dfrapi_choose_box' rel='{$kind}'>
516 <span class='names'></span>
517 <a class='button choose_{$kind}'>{$choose}</a>
518 <input name='{$pfx}[value]' type='hidden' value=\"$value\"/>
519 </div>
520 ";
521 }
522
523 function ajaxHandler() {
524 $command = $this->get( $_POST, 'command' );
525 $value = array_values( array_unique( array_filter( array_map( 'absint', $this->ary( $this->get( $_POST, 'value' ) ) ) ) ) );
526 $this->useSelected = (int) $this->get( $_POST, 'useSelected', 1 );
527
528 if ( $command === 'choose_network' ) {
529 return $this->networksMerchantsPopup( 'network', $value );
530 }
531
532 if ( $command === 'choose_merchant' ) {
533 return $this->networksMerchantsPopup( 'merchant', $value );
534 }
535
536 if ( $command === 'names_network' ) {
537 return $this->networksMerchantsNames( 'network', $value );
538 }
539
540 if ( $command === 'names_merchant' && ! empty( $value ) ) {
541 return $this->networksMerchantsNames( 'merchant', $value );
542 }
543
544 // switch ( $command ) {
545 // case "choose_network":
546 // return $this->networksMerchantsPopup( 'network', $value );
547 // case "choose_merchant":
548 // return $this->networksMerchantsPopup( 'merchant', $value );
549 // case "names_network":
550 // return $this->networksMerchantsNames( 'network', $value );
551 // case "names_merchant":
552 // return $this->networksMerchantsNames( 'merchant', $value );
553 // }
554
555 return '';
556 }
557
558 function renderField($field, $index, $params) {
559 $pfx = $this->inputPrefix($index);
560 $value = $this->get($params, 'value');
561 $operator = $this->get($params, 'operator');
562 $input = "";
563 $percent_sign = ( isset( $field['name'] ) && $field['name'] == 'salediscount') ? '%' : '';
564
565 switch($field['input']) {
566 case 'text':
567 $value = htmlspecialchars($value);
568 $input = "<input class='long' name='{$pfx}[value]' type='text' value=\"$value\"/>";
569 break;
570 case 'select':
571 $opts = $this->selectOpts($field['options'], $value);
572 $input = "<select name='{$pfx}[value]'>{$opts}</select>";
573 break;
574 case 'range':
575 $value = htmlspecialchars($value);
576 $value2 = htmlspecialchars($this->get($params, 'value2'));
577 $and = __( 'and', 'datafeedr-api' );
578 $input = "
579 <input class='short' name='{$pfx}[value]' type='text' value=\"$value\"/>{$percent_sign}
580 <span class='value2' style='display:none'>
581 $and
582 <input class='short' name='{$pfx}[value2]' type='text' value=\"$value2\" />
583 </span>
584 ";
585 break;
586 case 'network':
587 $input = $this->chooseBox('network', $field, $index, $value);
588 break;
589 case 'merchant':
590 $input = $this->chooseBox('merchant', $field, $index, $value);
591 break;
592 case 'none':
593 $input = "";
594 break;
595 }
596
597 if(count($field['operator']) == 1) {
598 $key = key($field['operator']);
599 $val = current($field['operator']);
600 $operator = "
601 <input type='hidden' name='{$pfx}[operator]' value=\"{$key}\" />
602 <span>{$val}</span>
603 ";
604 } else {
605 $opts = $this->selectOpts($field['operator'], $operator);
606 $operator = "<select name='{$pfx}[operator]'>{$opts}</select>";
607 }
608 return array($operator, $input);
609 }
610
611 function renderRow($field, $index, $params, $show) {
612 $pfx = $this->inputPrefix($index);
613 list($operator, $input) = $this->renderField($field, $index, $params);
614 $fieldOpts = '';
615 foreach($this->fields() as $f) {
616 if(!$this->useSelected && $f['name'] == 'merchant_id')
617 continue;
618 $sel = $field['name'] == $f['name'] ? "selected='selected'" : "";
619 $fieldOpts .= "<option value=\"{$f['name']}\" $sel>{$f['title']}</option>";
620 }
621 $style = $show ? "" : "style='display:none'";
622 return "
623 <div class='filter filter_{$field['name']}' {$style}>
624 <div class='valuewrapper'>
625 <div class='value'>{$input}</div>
626 </div>
627 <div class='plusminus'><a class='minus'></a> </div>
628 <div class='field'><select name='{$pfx}[field]' style='width: 140px'>{$fieldOpts}</select><a href='#' class='dfrapi_search_help'>?</a></div>
629 <div class='operator'>{$operator}</div>
630 <div class='clearfix'></div>
631 <div class='help' style='display:none;'><a href='#' class='dfrapi_search_help'><span class='dashicons dashicons-no'> </span></a>{$field['help']}</div>
632 </div>
633 ";
634 }
635
636 function render($prefix, $query, $useSelected=true) {
637 $this->prefix = $prefix;
638 $this->useSelected = intval($useSelected);
639 if(!$query)
640 $query = array(
641 array('field'=>'any', 'value'=>'')
642 );
643 $defaults = $this->defaults();
644
645 $fieldMap = array();
646 $fieldUsed = array();
647 foreach($this->fields() as $f) {
648 if(!$this->useSelected && $f['name'] == 'merchant_id')
649 continue;
650 $fieldMap[$f['name']] = $f;
651 }
652
653 $form = "";
654 $index = 0;
655 foreach($query as $params) {
656 $field = $this->get($fieldMap, $this->get($params, 'field'));
657 if(!$field)
658 continue;
659 $fieldUsed[$field['name']] = 1;
660 $form .= $this->renderRow($field, $index++, $params, true);
661 }
662 $show = ($index == 0); // if none shown, show the first
663 foreach($fieldMap as $field) {
664 $name = $field['name'];
665 if(!isset($fieldUsed[$name])) {
666 $form .= $this->renderRow($field, $index++, isset($defaults[$name]) ? $defaults[$name] : null, $show);
667 $show = FALSE;
668 }
669 }
670
671 $loading = __( 'Loading, please wait', 'datafeedr-api' );
672 $add = __( 'add filter', 'datafeedr-api' );
673 return "
674 <div id='dfrapi_search_form'>
675 <input type='hidden' id='dfrapi_useSelected' value='{$this->useSelected}' />
676 <div id='dfprs_loading_content' style='display:none'>
677 <div class='dfrapi_loading'></div>
678 <h3>{$loading}</h3>
679 </div>
680 {$form}
681 <div class='clearfix'></div>
682 <div id='dfrapi_search_form_filter'><a href='#'><span class='dashicons dashicons-plus'> </span> $add</a></div>
683 </div>
684 ";
685 }
686
687 function combineLists($lst, $func) {
688 if(!count($lst))
689 return array();
690 if(count($lst) == 1)
691 return current($lst);
692 $lst = call_user_func_array($func, $lst);
693 return count($lst) ? $lst : NULL;
694 }
695
696 function idFilter($inList, $exList) {
697 $inList = $this->combineLists($inList, 'array_intersect');
698 $exList = $this->combineLists($exList, 'array_merge');
699
700 if(is_null($inList) || is_null($exList)) {
701 return NULL;
702 }
703 if(count($inList)) {
704 if(count($exList)) {
705 $inList = array_diff($inList, $exList);
706 if(!count($inList))
707 return NULL;
708 }
709 return array("IN", $inList);
710 }
711 if(count($exList)) {
712 return array("!IN", $exList);
713 }
714 return array(NULL, NULL);
715 }
716
717 function fulltextFilter($operator, $value) {
718 if($operator == 'match')
719 return array("LIKE", $value);
720 $value = trim(preg_replace('~[!\\[\\]"^$]+~', " ", $value));
721 if(strlen($value)) {
722 switch($operator) {
723 case 'is': return array('LIKE', "^$value\$");
724 case 'contain': return array('LIKE', $value);
725 case 'not_contain': return array('!LIKE', $value);
726 case 'start': return array('LIKE', "^$value");
727 case 'end': return array('LIKE', "$value\$");
728 }
729 }
730 return array(NULL, NULL);
731 }
732
733 function makeFilters($query, $useSelected=TRUE) {
734
735 $filters = array();
736
737 $selected = array(
738 'in:source_id' => array(),
739 'ex:source_id' => array(),
740 'in:merchant_id' => array(),
741 'ex:merchant_id' => array(),
742 );
743
744 $allNetworks = $this->ids($this->allNetworks());
745
746 if($useSelected) {
747 $selected['in:source_id'] []= $this->ids($this->selectedNetworks());
748 $selected['in:merchant_id'] []= $this->ids($this->selectedMerchants());
749 } else {
750 $selected['in:source_id'] []= $allNetworks;
751 }
752
753 foreach($query as $params) {
754 $fname = $params['field'];
755 $value = $this->get($params, 'value');
756 $value2 = $this->get($params, 'value2');
757 $operator = strtolower($this->get($params, 'operator'));
758
759 switch($fname) {
760 case 'any':
761 case 'name':
762 case 'brand':
763 case 'color':
764 case 'material':
765 case 'size':
766 case 'gender':
767 case 'sku':
768 case 'condition':
769 case 'description':
770 case 'merchant':
771 case 'source':
772 case 'category':
773 $s = $this->fulltextFilter($operator, $value);
774 if(!is_null($s[0])) {
775 $filters []= "{$fname} {$s[0]} {$s[1]}";
776 }
777 break;
778 case 'tags':
779 $operator = ($operator == 'in') ? "LIKE" : "!LIKE";
780 $filters []= "{$fname} {$operator} {$value}";
781 break;
782 case 'currency':
783 $op = ($operator == 'is') ? '=' : '!=';
784 $filters []= "{$fname} $op {$value}";
785 break;
786 case 'id':
787 case 'barcode':
788 $op = ($operator == 'is') ? 'IN' : '!IN';
789 $filters []= "{$fname} $op {$value}";
790 break;
791 case 'price':
792 case 'finalprice':
793 case 'saleprice':
794 case 'salediscount':
795 case 'stockquantity':
796 $conv = in_array( $fname, [ 'salediscount', 'stockquantity' ] ) ? 'intval' : 'dfrapi_price_to_int';
797 $value = $conv($value);
798 switch($operator) {
799 case 'between':
800 $value2 = $conv($value2);
801 $filters []= "{$fname} > {$value}";
802 $filters []= "{$fname} < {$value2}";
803 break;
804 case 'eq':
805 $filters []= "{$fname} = {$value}";
806 break;
807 case 'lt':
808 $filters []= "{$fname} < {$value}";
809 break;
810 case 'lte':
811 $filters []= "{$fname} <= {$value}";
812 break;
813 case 'gt':
814 $filters []= "{$fname} > {$value}";
815 break;
816 case 'gte':
817 $filters []= "{$fname} >= {$value}";
818 break;
819 }
820 break;
821 case 'source_id':
822 case 'merchant_id':
823 $key = ($operator == 'is') ? 'in' : 'ex';
824 $selected["$key:$fname"] []= $this->ary($value);
825 break;
826 case 'type':
827 $ids = array();
828 foreach($this->allNetworks() as $net) {
829 if($net['type'] == $value)
830 $ids []= $net['_id'];
831 }
832 $selected["in:source_id"] []= $ids;
833 break;
834 case 'onsale':
835 $value = ($operator == 'yes') ? '1' : '0';
836 $filters []= "{$fname} = {$value}";
837 break;
838 case 'instock':
839 if ( $operator == 'yes' ) {
840 $filters [] = "{$fname} = 1";
841 break;
842 } elseif ( $operator == 'no' ) {
843 $filters [] = "{$fname} = 0";
844 break;
845 } else {
846 $filters [] = "{$fname} > 0";
847 break;
848 }
849 case 'direct_url':
850 $operator = ($operator == 'yes') ? '!EMPTY' : 'EMPTY';
851 $filters []= "{$fname} {$operator}";
852 break;
853 case 'image':
854 case 'thumbnail':
855 $operator = ($operator == 'yes') ? '!EMPTY' : 'EMPTY';
856 $filters []= "image {$operator}";
857 break;
858 case 'has_barcode':
859 $operator = ( $operator === 'yes') ? '!EMPTY' : 'EMPTY';
860 $filters []= "barcode {$operator}";
861 break;
862 case 'time_updated':
863 $value = @date('Y-m-d H:i:s', strtotime($value));
864 switch($operator) {
865 case 'between':
866 $value2 = @date('Y-m-d H:i:s', strtotime($value2));
867 $filters []= "{$fname} > {$value}";
868 $filters []= "{$fname} < {$value2}";
869 break;
870 case 'lt':
871 $filters []= "{$fname} < {$value}";
872 break;
873 case 'gt':
874 $filters []= "{$fname} > {$value}";
875 break;
876 }
877 break;
878 }
879 }
880
881 $s = $this->idFilter($selected['in:source_id'], $selected['ex:source_id']);
882 if(is_null($s))
883 return array('error' => 'No networks selected');
884 if(!is_null($s[0]) && count($s[1]) < count($allNetworks))
885 $filters []= "source_id {$s[0]} ". implode(',', $s[1]);
886
887 $s = $this->idFilter($selected['in:merchant_id'], $selected['ex:merchant_id']);
888 if(is_null($s))
889 return array('error' => 'No merchants selected');
890 if(!is_null($s[0])) {
891 $m = implode(',', $s[1]);
892 if ($m)
893 $filters []= "merchant_id {$s[0]} $m";
894 }
895
896 return $filters;
897
898 }
899
900 function help_tip($tip) {
901 return '
902 <div class="dfrapi_search_tip">
903 <span class="dashicons dashicons-lightbulb"></span>
904 <p>
905 <strong>' . __( 'TIP:', 'datafeedr-api' ) . '</strong> ' .
906 $tip . '
907 </p>
908 </div>
909 ';
910 }
911
912 function help_operators() {
913 return '
914 <p>
915 <span class="dashicons dashicons-info"></span>
916 <em>
917 <a href="https://datafeedrapi.helpscoutdocs.com/article/216-search-operators" target="_blank">' . __('Learn more', 'datafeedr-api' ) . '</a> ' .
918 __('about advanced uses of this field.', 'datafeedr-api' ) . '
919 </em>
920 </p>
921 ';
922 }
923
924 function help($field) {
925
926 $help = array();
927
928 // Any
929 $help['any'] = '<h3>' . __('Any Field', 'datafeedr-api' ) . '</h3>';
930 $help['any'] .= '<p>' . __( 'Search all indexed text fields at once to return a broad set of results.', 'datafeedr-api' ) . '</p>';
931 $help['any'] .= '<p>' . __( 'The fields listed below are indexed as text fields and searchable using Any Field. Image, currency, and price fields are not searched.', 'datafeedr-api' ) . '</p>';
932 $help['any'] .= '<p><em>' . __( '*Note that not all merchants and networks provide every field. ', 'datafeedr-api' ) . '</em></p>';
933 $help['any'] .= '<p>' . __( 'Fields searched using Any Field:', 'datafeedr-api' ) . '</p>';
934 $help['any'] .= '<table width="100%" border="0" style="margin-bottom:20px"><tr><td width="33%" valign="top">accommodationtype<br />address<br />artist<br />author<br />bestsellers<br />brand<br />category<br />city<br />color<br />commissiontype<br />condition<br />country<br />county<br />description<br />destination<br />discount</td><td width="33%" valign="top">discounttype<br />ean<br />fabric<br />featured<br />flavour<br />gender<br />genre<br />isbn<br />language<br />location<br />manufacturer<br />manufacturerid<br />material<br />size<br />gender<br />model<br />mpn<br />name</td><td width="33%" valign="top">offercode<br />offertype<br />platform<br />productnumber<br />promo<br />publisher<br />rating<br />region<br />size<br />sku<br />stars<br />state<br />subcategory<br />tags<br />upc<br />weight</td></tr></table>';
935 $help['any'] .= $this->help_operators();
936
937 // Name
938 $help['name'] = '<h3>' . __('Product Name', 'datafeedr-api' ) . '</h3>';
939 $help['name'] .= '<p>' . __( 'Search by product name to narrow your results.', 'datafeedr-api' ) . '</p>';
940 $help['name'] .= $this->help_tip( __( 'Some merchants include color, size, gender, product codes, sale information and promotions in the product name field.', 'datafeedr-api' ) );
941 $help['name'] .= $this->help_operators();
942
943 // ID
944 $help['id'] = '<h3>' . __('Product ID', 'datafeedr-api' ) . '</h3>';
945 $help['id'] .= '<p>' . __( 'Search by Product ID to find specific products.', 'datafeedr-api' ) . '</p>';
946 $help['id'] .= $this->help_tip( __( 'Separate each product ID with a comma "," to search for multiple products by their IDs.<br /><br />Example: <strong>4088900432286084, 8177000167015036, 2651801988581531</strong>', 'datafeedr-api' ) );
947 $help['id'] .= '<p>' . __( 'Product IDs are assigned by Datafeedr and are not related to any IDs merchants use to identify their products. Each product in the Datafeedr product database has a unique Product ID.', 'datafeedr-api' ) . '</p>';
948 // $help['id'] .= $this->help_operators();
949
950 // Barcode
951 $help['barcode'] = '<h3>' . __('Barcode', 'datafeedr-api' ) . '</h3>';
952 $help['barcode'] .= '<p>' . __( 'Search for products by their barcode (ie. EAN, UPC or GTIN value).', 'datafeedr-api' ) . '</p>';
953 $help['barcode'] .= $this->help_tip( __( 'Separate each barcode with a comma "," to search for multiple products by their barcodes.<br /><br />Example: <strong>889169871993, 889169900167, 889169488559</strong>', 'datafeedr-api' ) );
954 $help['barcode'] .= '<p>' . __( 'The Barcode search filter ignores leading zeros. Therefore, searching for <strong>889169871993</strong> and searching for <strong>00889169871993</strong> will return the same results.', 'datafeedr-api' ) . '</p>';
955
956 // Brand
957 $help['brand'] = '<h3>' . __('Brand', 'datafeedr-api' ) . '</h3>';
958 $help['brand'] .= '<p>' . __( 'Search by brand name to get specific results. Not every item has a brand name.', 'datafeedr-api' ) . '</p>';
959 $help['brand'] .= $this->help_tip( __( 'Enter the shorter version of a brand name in this field. Omit words such as "Incorporated", "Limited" and their abbreviations like Inc., Ltd. and so on.', 'datafeedr-api' ) );
960 $help['brand'] .= $this->help_operators();
961
962 // Color
963 $help['color'] = '<h3>' . __('Color', 'datafeedr-api' ) . '</h3>';
964 $help['color'] .= '<p>' . __( 'Search by color to get specific results. Not every item has a color field.', 'datafeedr-api' ) . '</p>';
965
966 // Material
967 $help['material'] = '<h3>' . __('Material', 'datafeedr-api' ) . '</h3>';
968 $help['material'] .= '<p>' . __( 'Search by material to get specific results. Not every item has a material field.', 'datafeedr-api' ) . '</p>';
969
970 // Size
971 $help['size'] = '<h3>' . __('Size', 'datafeedr-api' ) . '</h3>';
972 $help['size'] .= '<p>' . __( 'Search by size to get specific results. Not every item has a size field.', 'datafeedr-api' ) . '</p>';
973
974 // Gender
975 $help['gender'] = '<h3>' . __('Gender', 'datafeedr-api' ) . '</h3>';
976 $help['gender'] .= '<p>' . __( 'Search by gender to get specific results. Not every item has a gender field.', 'datafeedr-api' ) . '</p>';
977
978 // SKU
979 $help['sku'] = '<h3>' . __('SKU', 'datafeedr-api' ) . '</h3>';
980 $help['sku'] .= '<p>' . __( 'Search by SKU to get specific results. Not every item has a SKU field.', 'datafeedr-api' ) . '</p>';
981
982 // Condition
983 $help['condition'] = '<h3>' . __('Condition', 'datafeedr-api' ) . '</h3>';
984 $help['condition'] .= '<p>' . __( 'Search by condition to get specific results. Not every item has a condition field.', 'datafeedr-api' ) . '</p>';
985
986 // Description
987 $help['description'] = '<h3>' . __('Description', 'datafeedr-api' ) . '</h3>';
988 $help['description'] .= '<p>' . __( 'Search the description field for product attributes such as size, color, material, gender or usage.', 'datafeedr-api' ) . '</p>';
989 $help['description'] .= $this->help_tip( __( 'Most merchants provide a product description. Some product details may only appear in the description and not in any other field. However, some merchants duplicate the product name or product code in the description field without supplying additional details or leave the product description blank.', 'datafeedr-api' ) );
990 $help['description'] .= $this->help_operators();
991
992 // Tags
993 $help['tags'] = '<h3>' . __('Tags', 'datafeedr-api' ) . '</h3>';
994 $help['tags'] .= '<p>' . __( 'Limit search results based on product tag and keyword information.', 'datafeedr-api' ) . '</p>';
995 $help['tags'] .= $this->help_tip( __( 'This field contains data from various keyword-related fields provided by the merchant. This field does not always exist.', 'datafeedr-api' ) );
996
997 // Category
998 $help['category'] = '<h3>' . __('Category', 'datafeedr-api' ) . '</h3>';
999 $help['category'] .= '<p>' . __( 'Limit search results based on category information.', 'datafeedr-api' ) . '</p>';
1000 $help['category'] .= $this->help_tip( __( 'This field contains data from various category-related fields provided by the merchant. This field does not always exist.', 'datafeedr-api' ) );
1001 $help['category'] .= $this->help_operators();
1002
1003 // Type
1004 $help['type'] = '<h3>' . __('Product Type', 'datafeedr-api' ) . '</h3>';
1005 $help['type'] .= '<p>' . __( 'Limit your search results to one type of item, either Product or Coupon.', 'datafeedr-api' ) . '</p>';
1006 $help['type'] .= $this->help_tip( __( 'In order to use this filter, you must have already selected merchants that provide that type of item. For example, if you choose "Product type: Coupon" but have not selected any merchants that offer coupons, your search will return an error.', 'datafeedr-api' ) );
1007
1008 // Currency
1009 $help['currency'] = '<h3>' . __('Currency', 'datafeedr-api' ) . '</h3>';
1010 $help['currency'] .= '<p>' . __( 'Limit your search results to items with a specific currency code.', 'datafeedr-api' ) . '</p>';
1011 $help['currency'] .= $this->help_tip( __( 'Selecting a currency code is one way to limit your search results to items from a specific country. However, not every item has been given a currency code value by the merchant. Items without a currency code will be excluded from your search results.', 'datafeedr-api' ) );
1012
1013 // Price
1014 $help['price'] = '<h3>' . __('Price', 'datafeedr-api' ) . '</h3>';
1015 $help['price'] .= '<p>' . __( 'Filter your search results based on price. Return products less than, greater than, or within a price range that you set.', 'datafeedr-api' ) . '</p>';
1016 $help['price'] .= $this->help_tip( __( 'This field does not search on sale price. If you set a price range to less than 30, you will exclude an item with a regular price of 40 that is on sale for less than 30.', 'datafeedr-api' ) );
1017
1018 // Sale Price
1019 $help['saleprice'] = '<h3>' . __('Sale Price', 'datafeedr-api' ) . '</h3>';
1020 $help['saleprice'] .= '<p>' . __( 'Filter your search results based on sale price. Return items less than, greater than, or within a sale price range that you set.', 'datafeedr-api' ) . '</p>';
1021 $help['saleprice'] .= $this->help_tip( __( 'This field does not search on regular price. If you set a sale price range to between 50 and 100, an item with a sale price of 40 will be excluded even if it\'s regular price matches the range you set.', 'datafeedr-api' ) );
1022
1023 // Final Price
1024 $help['finalprice'] = '<h3>' . __('Final Price', 'datafeedr-api' ) . '</h3>';
1025 $help['finalprice'] .= '<p>' . __( 'Filter your search results based on the final price. Return items less than, greater than, or within a sale price range that you set.', 'datafeedr-api' ) . '</p>';
1026 $help['finalprice'] .= $this->help_tip( __( 'The final price is the lower price when comparing the regular price and sale price field.', 'datafeedr-api' ) );
1027
1028 // Discount
1029 $help['salediscount'] = '<h3>' . __('Discount', 'datafeedr-api' ) . '</h3>';
1030 $help['salediscount'] .= '<p>' . __( 'Limit your search results to items with a specified discount. Enter the number in terms of percentage (1 - 100) to indicate a discount less than, greater than, or between a given range. You do not need to enter the percentage sign.', 'datafeedr-api' ) . '</p>';
1031 $help['salediscount'] .= $this->help_tip( __( 'To display, for example, only products that are on sale for a discount of 20% or more, choose the "greater than" operator and type "19".', 'datafeedr-api' ) );
1032
1033 // Network
1034 $help['source_id'] = '<h3>' . __('Network', 'datafeedr-api' ) . '</h3>';
1035 $help['source_id'] .= '<p>' . __( 'Limit your search results to items from one or more affiliate networks.', 'datafeedr-api' ) . '</p>';
1036 $help['source_id'] .= $this->help_tip( __( 'Affiliate networks are generally country-specific. Using the Network filter is one way to limit your search results by country.', 'datafeedr-api' ) );
1037
1038 // Merchant
1039 $help['merchant_id'] = '<h3>' . __('Merchant', 'datafeedr-api' ) . '</h3>';
1040 $help['merchant_id'] .= '<p>' . __( 'Limit your search results to items from one or more merchants.', 'datafeedr-api' ) . '</p>';
1041 $help['merchant_id'] .= $this->help_tip( __( 'Using the Merchant filter is a quick way to exclude unrelated products and reduce the number of API requests made when building a Product Set. For example, if you are creating a Product Set related to cat products, exclude all merchants that only sell dog products.', 'datafeedr-api' ) );
1042
1043 // On Sale
1044 $help['onsale'] = '<h3>' . __('On Sale', 'datafeedr-api' ) . '</h3>';
1045 $help['onsale'] .= '<p>' . __( 'Set this field to "<strong>yes</strong>" to return only items which are on sale. To exclude products which are on sale, set this field to "<strong>no</strong>".', 'datafeedr-api' ) . '</p>';
1046
1047 // In Stock
1048 $help['instock'] = '<h3>' . __('In Stock', 'datafeedr-api' ) . '</h3>';
1049 $help['instock'] .= '<p>' . __( 'This allows you to filter products by stock status.', 'datafeedr-api' ) . '</p>';
1050 $help['instock'] .= '<p>' . __( '<strong>yes or unknown</strong>: This will return products which are explicitly set as "in-stock" or products which have no field containing stock-related information.', 'datafeedr-api' ) . '</p>';
1051 $help['instock'] .= '<p>' . __( '<strong>yes</strong>: This will only return products which are explicitly set as "in-stock".', 'datafeedr-api' ) . '</p>';
1052 $help['instock'] .= '<p>' . __( '<strong>no</strong>: This will only return products which are explicitly set as NOT "in-stock".', 'datafeedr-api' ) . '</p>';
1053 $help['instock'] .= $this->help_tip( __( 'Not all products contain stock-related information. Therefore selecting "yes or unknown" is the recommended choice when you want to find products which are "in-stock".', 'datafeedr-api' ) );
1054
1055 // Stock Quantity
1056 $help['instock'] = '<h3>' . __('Stock Quantity', 'datafeedr-api' ) . '</h3>';
1057 $help['instock'] .= '<p>' . __( 'This allows you to filter products by the number of products in stock.', 'datafeedr-api' ) . '</p>';
1058 $help['instock'] .= '<p>' . __( '<strong>NOTE</strong>: Not all products have a "Stock Quantity" value. Therefore, searching for a product with a stock quantity greater than or equal to "0" will eliminate all products which have an unknow "Stock Quantity".', 'datafeedr-api' ) . '</p>';
1059 $help['instock'] .= '<p>' . __( 'To search for products which either have a stock quantity in a specific range AND also include products which do not have a stock quantity value, use the "between" search option and enter "-1" for the first option and enter the upper limit (ie. 100) for the second value.', 'datafeedr-api' ) . '</p>';
1060
1061 // Has Direct URL
1062 $help['direct_url'] = '<h3>' . __('Has Direct URL', 'datafeedr-api' ) . '</h3>';
1063 $help['direct_url'] .= '<p>' . __( 'Limit your search results to items which have a direct URL (or which don\'t).', 'datafeedr-api' ) . '</p>';
1064 $help['direct_url'] .= $this->help_tip( __( 'A "Direct URL" is a URL directly to the product page on the merchant\'s website. By default, the "Direct URL" is never used as the URL in your "Buy" links. However, if you need the products in your store to contain a "Direct URL" to the product page on the merchants\' websites, then you should use this filter. This is most useful if you are using Skimlinks (or similar service) to generate your affiliate links instead of the affiliate networks.', 'datafeedr-api' ) );
1065
1066 // Has Image
1067 $help['image'] = '<h3>' . __('Has Image', 'datafeedr-api' ) . '</h3>';
1068 $help['image'] .= '<p>' . __( 'Limit your search results to items which have an image (or which don\'t).', 'datafeedr-api' ) . '</p>';
1069 $help['image'] .= $this->help_tip( __( 'Sometimes the image URL in the merchant\'s data feed is broken. Items with broken images will still return in search results even though there appears to be no image.', 'datafeedr-api' ) );
1070
1071 // Has Barcode
1072 $help['has_barcode'] = '<h3>' . __('Has Barcode', 'datafeedr-api' ) . '</h3>';
1073 $help['has_barcode'] .= '<p>' . __( 'Limit your search results to products which have a barcode (ie. a UPC, EAN or GTIN value).', 'datafeedr-api' ) . '</p>';
1074
1075 // Last Updated
1076 $help['time_updated'] = '<h3>' . __('Last Updated', 'datafeedr-api' ) . '</h3>';
1077 $help['time_updated'] .= '<p>' . __( 'Filter products by the last time they were updated by the merchant. Enter an English textual datetime description using PHP\'s <a href="http://www.php.net/strtotime" target="_blank">strtotime()</a> function.', 'datafeedr-api' ) . '</p>';
1078 $help['time_updated'] .= '<h3>' . __('Examples', 'datafeedr-api' ) . '</h3>';
1079 $help['time_updated'] .= '<p>';
1080 $help['time_updated'] .= '<tt>' . __('last week', 'datafeedr-api' ) . '</tt><br />';
1081 $help['time_updated'] .= '<tt>' . __('2 days ago', 'datafeedr-api' ) . '</tt><br />';
1082 $help['time_updated'] .= '<tt>' . __('1 month ago', 'datafeedr-api' ) . '</tt>';
1083 $help['time_updated'] .= '</p>';
1084 $help['time_updated'] .= '<p>' . __( '', 'datafeedr-api' ) . '</p>';
1085 $help['time_updated'] .= $this->help_tip( __( 'An item\'s Last Updated date will not change if the merchant does not change any product information during a data feed update.', 'datafeedr-api' ) );
1086
1087 // Limit
1088 $help['limit'] = '<h3>' . __('Limit', 'datafeedr-api' ) . '</h3>';
1089 $help['limit'] .= '<p>' . __( 'Limit the number of items returned in your search results. The maximum number of products that can be returned is 10,000.', 'datafeedr-api' ) . '</p>';
1090 $help['limit'] .= $this->help_tip( __( 'Limiting the number of products returned helps reduce the number of API requests made during searching and updating Product Sets.', 'datafeedr-api' ) );
1091
1092 // Merchant Limit
1093 $help['merchant_limit'] = '<h3>' . __('Merchant Limit', 'datafeedr-api' ) . '</h3>';
1094 $help['merchant_limit'] .= '<p>' . __( 'Limit the number of items returned per merchant. The number must be between 1 and 10.', 'datafeedr-api' ) . '</p>';
1095 $help['merchant_limit'] .= $this->help_tip( __( 'This is useful to use when you have one merchant which has many products that match your search but other merchants have fewer of those same products and you want equal distribution between all merchants.', 'datafeedr-api' ) );
1096
1097 // Sort By
1098 $help['sort'] = '<h3>' . __('Sort By', 'datafeedr-api' ) . '</h3>';
1099 $help['sort'] .= '<p>' . __( 'Change the sort criteria by which items are displayed in your search results.', 'datafeedr-api' ) . '</p>';
1100 $help['sort'] .= $this->help_tip( __( 'By default, search results are sorted by relevance. You can change that to sort by price, sale price, discount, or last updated date in ascending order (lowest to highest) or descending order (highest to lowest). You can also sort by merchant, which lists items alphabetically by merchant name.', 'datafeedr-api' ) );
1101
1102 // Exclude Duplicates
1103 $help['duplicates'] = '<h3>' . __('Exclude Duplicates', 'datafeedr-api' ) . '</h3>';
1104 $help['duplicates'] .= '<p>' . __( 'Exclude items that contain identical product names, image URLs, etc. Enter one or more terms from the list below. Separate terms by a space (meaning AND) or | (pipe symbol, meaning OR).', 'datafeedr-api' ) . '<br />';
1105 $help['duplicates'] .= '<p>' . __( 'Enter one of these terms to exclude duplicates matching these fields:', 'datafeedr-api' ) . '<br />';
1106 $help['duplicates'] .= '<tt>' . __('name', 'datafeedr-api' ) . '</tt><br />';
1107 $help['duplicates'] .= '<tt>' . __('brand', 'datafeedr-api' ) . '</tt><br />';
1108 $help['duplicates'] .= '<tt>' . __('description', 'datafeedr-api' ) . '</tt><br />';
1109 $help['duplicates'] .= '<tt>' . __('currency', 'datafeedr-api' ) . '</tt><br />';
1110 $help['duplicates'] .= '<tt>' . __('price', 'datafeedr-api' ) . '</tt><br />';
1111 $help['duplicates'] .= '<tt>' . __('saleprice', 'datafeedr-api' ) . '</tt><br />';
1112 $help['duplicates'] .= '<tt>' . __('source_id', 'datafeedr-api' ) . '</tt><br />';
1113 $help['duplicates'] .= '<tt>' . __('merchant_id', 'datafeedr-api' ) . '</tt><br />';
1114 $help['duplicates'] .= '<tt>' . __('direct_url', 'datafeedr-api' ) . '</tt><br />';
1115 $help['duplicates'] .= '<tt>' . __('onsale', 'datafeedr-api' ) . '</tt><br />';
1116 $help['duplicates'] .= '<tt>' . __('image', 'datafeedr-api' ) . '</tt><br />';
1117 $help['duplicates'] .= '<tt>' . __('thumbnail', 'datafeedr-api' ) . '</tt>';
1118 $help['duplicates'] .= '</p>';
1119 $help['duplicates'] .= '<h3>' . __('Examples', 'datafeedr-api' ) . '</h3>';
1120 $help['duplicates'] .= '<p>';
1121 $help['duplicates'] .= '<tt>' . __('image</tt> - Exclude items which have the same image URL.', 'datafeedr-api' ) . '<br />';
1122 $help['duplicates'] .= '<tt>' . __('name image</tt> - Exclude items with the same name AND the same image URL.', 'datafeedr-api' ) . '<br />';
1123 $help['duplicates'] .= '<tt>' . __('name|image</tt> - Exclude items with the same name OR the same image URL.', 'datafeedr-api' ) . '<br />';
1124 $help['duplicates'] .= '<tt>' . __('merchant_id name|image</tt> - Exclude items which have the same merchant id AND (product name OR image URL).', 'datafeedr-api' ) . '<br />';
1125 $help['duplicates'] .= '</p>';
1126 $help['duplicates'] .= $this->help_tip( __( 'By excluding duplicates, you will eliminate all but one item. For example, if 20 products have identical image URLs and you exclude duplicates matching the <strong>image</strong> field, <em>one</em> item will be returned and 19 items will be excluded.', 'datafeedr-api' ) );
1127
1128 if (isset($help[$field])) {
1129 return $help[$field];
1130 } else {
1131 return '';
1132 }
1133
1134 } // help()
1135
1136 }
1137