PluginProbe
Datafeedr API / 1.0.29
Datafeedr API v1.0.29
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.0.29, at classes/class-dfrapi-searchform.php

868 lines 39.4 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3
4
5 class Dfrapi_SearchForm
6 {
7 function fields() {
8 $opFulltext = array(
9 'contain' => __( 'contains', DFRAPI_DOMAIN ),
10 'not_contain' => __( 'doesn\'t contain', DFRAPI_DOMAIN ),
11 'start' => __( 'starts with', DFRAPI_DOMAIN ),
12 'end' => __( 'ends with', DFRAPI_DOMAIN ),
13 'match' => __( 'matches', DFRAPI_DOMAIN )
14 );
15 $opFulltextExact = array_merge($opFulltext, array(
16 'is' => __( 'is', DFRAPI_DOMAIN )
17 ));
18 $opRange = array(
19 'lt' => __( 'less than', DFRAPI_DOMAIN ),
20 'gt' => __( 'greater than', DFRAPI_DOMAIN ),
21 'between' => __( 'between', DFRAPI_DOMAIN )
22 );
23 $opIs = array(
24 'is' => __( 'is', DFRAPI_DOMAIN )
25 );
26 $opIsIsnt = array(
27 'is' => __( 'is', DFRAPI_DOMAIN ),
28 'is_not' => __( 'isn\'t', DFRAPI_DOMAIN )
29 );
30 $opYesNo = array(
31 'yes' => __( 'yes', DFRAPI_DOMAIN ),
32 'no' => __( 'no', DFRAPI_DOMAIN )
33 );
34
35 $sortOpts = array(
36 '' => __( 'Relevance', DFRAPI_DOMAIN ),
37 '+price' => __( 'Price Ascending', DFRAPI_DOMAIN ),
38 '-price' => __( 'Price Decending', DFRAPI_DOMAIN ),
39 '+saleprice' => __( 'Sale Price Ascending', DFRAPI_DOMAIN ),
40 '-saleprice' => __( 'Sale Price Decending', DFRAPI_DOMAIN ),
41 '+salediscount' => __( 'Discount Ascending', DFRAPI_DOMAIN ),
42 '-salediscount' => __( 'Discount Decending', DFRAPI_DOMAIN ),
43 '+merchant' => __( 'Merchant', DFRAPI_DOMAIN ),
44 '+time_updated' => __( 'Last Updated Ascending', DFRAPI_DOMAIN ),
45 '-time_updated' => __( 'Last Updated Decending', DFRAPI_DOMAIN )
46 );
47
48 return array(
49 array(
50 'title' => __( 'Any Field', DFRAPI_DOMAIN ),
51 'name' => 'any',
52 'input' => 'text',
53 'operator' => $opFulltext,
54 'help' => $this->help('any')
55 ),
56 array(
57 'title' => __( 'Product Name', DFRAPI_DOMAIN ),
58 'name' => 'name',
59 'input' => 'text',
60 'operator' => $opFulltextExact,
61 'help' => $this->help('name')
62 ),
63 array(
64 'title' => __( 'Brand', DFRAPI_DOMAIN ),
65 'name' => 'brand',
66 'input' => 'text',
67 'operator' => $opFulltextExact,
68 'help' => $this->help('brand')
69 ),
70 array(
71 'title' => __( 'Description', DFRAPI_DOMAIN ),
72 'name' => 'description',
73 'input' => 'text',
74 'operator' => $opFulltext,
75 'help' => $this->help('description')
76 ),
77 array(
78 'title' => __( 'Tags', DFRAPI_DOMAIN ),
79 'name' => 'tags',
80 'input' => 'text',
81 'operator' => array(
82 'in' => __( 'contain', DFRAPI_DOMAIN ),
83 'not_in' => __( 'don\'t contain', DFRAPI_DOMAIN )
84 ),
85 'help' => $this->help('tags')
86 ),
87 array(
88 'title' => __( 'Category', DFRAPI_DOMAIN ),
89 'name' => 'category',
90 'input' => 'text',
91 'operator' => $opFulltext,
92 'help' => $this->help('category')
93 ),
94 array(
95 'title' => __( 'Product Type', DFRAPI_DOMAIN ),
96 'name' => 'type',
97 'input' => 'select',
98 'options' => array(
99 'products' => __( 'Product', DFRAPI_DOMAIN ),
100 'coupons' => __( 'Coupon', DFRAPI_DOMAIN )
101 ),
102 'operator' => $opIs,
103 'help' => $this->help('type')
104 ),
105 array(
106 'title' => __( 'Currency', DFRAPI_DOMAIN ),
107 'name' => 'currency',
108 'input' => 'select',
109 'options' => array(
110 'AUD' => 'AUD',
111 'CAD' => 'CAD',
112 'CHF' => 'CHF',
113 'DKK' => 'DKK',
114 'EUR' => 'EUR',
115 'GBP' => 'GBP',
116 'NOK' => 'NOK',
117 'NZD' => 'NZD',
118 'SEK' => 'SEK',
119 'TRY' => 'TRY',
120 'USD' => 'USD',
121 ),
122 'operator' => $opIsIsnt,
123 'help' => $this->help('currency')
124 ),
125 array(
126 'title' => __( 'Price', DFRAPI_DOMAIN ),
127 'name' => 'price',
128 'input' => 'range',
129 'operator' => $opRange,
130 'help' => $this->help('price')
131 ),
132 array(
133 'title' => __( 'Sale Price', DFRAPI_DOMAIN ),
134 'name' => 'saleprice',
135 'input' => 'range',
136 'operator' => $opRange,
137 'help' => $this->help('saleprice')
138 ),
139 array(
140 'title' => __( 'Network', DFRAPI_DOMAIN ),
141 'name' => 'source_id',
142 'input' => 'network',
143 'operator' => $opIsIsnt,
144 'help' => $this->help('source_id')
145 ),
146 array(
147 'title' => __( 'Merchant', DFRAPI_DOMAIN ),
148 'name' => 'merchant_id',
149 'input' => 'merchant',
150 'operator' => $opIsIsnt,
151 'help' => $this->help('merchant_id')
152 ),
153 array(
154 'title' => __( 'On Sale', DFRAPI_DOMAIN ),
155 'name' => 'onsale',
156 'input' => 'none',
157 'operator' => $opYesNo,
158 'help' => $this->help('onsale')
159 ),
160 array(
161 'title' => __( 'Discount', DFRAPI_DOMAIN ),
162 'name' => 'salediscount',
163 'input' => 'range',
164 'operator' => $opRange,
165 'help' => $this->help('salediscount')
166 ),
167 array(
168 'title' => __( 'Has Image', DFRAPI_DOMAIN ),
169 'name' => 'image',
170 'input' => 'none',
171 'operator' => $opYesNo,
172 'help' => $this->help('image')
173 ),
174 array(
175 'title' => __( 'Last Updated', DFRAPI_DOMAIN ),
176 'name' => 'time_updated',
177 'input' => 'range',
178 'operator' => array('lt' => 'before', 'gt' => 'after', 'between' => 'between'),
179 'help' => $this->help('time_updated')
180 ),
181 array(
182 'title' => __( 'Limit', DFRAPI_DOMAIN ),
183 'name' => 'limit',
184 'input' => 'text',
185 'operator' => array('is' => 'is'),
186 'help' => $this->help('limit')
187 ),
188 array(
189 'title' => __( 'Sort By', DFRAPI_DOMAIN ),
190 'name' => 'sort',
191 'input' => 'none',
192 'operator' => $sortOpts,
193 'help' => $this->help('sort')
194 ),
195 array(
196 'title' => __( 'Exclude Duplicates', DFRAPI_DOMAIN ),
197 'name' => 'duplicates',
198 'input' => 'text',
199 'operator' => array(
200 'is' => __( 'matching these fields', DFRAPI_DOMAIN ),
201 ),
202 'help' => $this->help('duplicates')
203 )
204 );
205 }
206
207 function defaults() {
208 return array(
209 'any' => array('operator' => 'contain', 'value'=> ''),
210 'name' => array('operator' => 'contain', 'value'=> ''),
211 'type' => array('value'=> 'product'),
212 'currency' => array('value'=> 'USD'),
213 'price' => array('operator' => 'between', 'value'=> '0', 'value2' => '999999'),
214 'saleprice' => array('operator' => 'between', 'value'=> '0', 'value2' => '999999'),
215 'source_id' => array('value'=> array()),
216 'merchant_id' => array('value'=> array()),
217 'onsale' => array('value'=> '1'),
218 'image' => array('value'=> '1'),
219 'thumbnail' => array('value'=> '1'),
220 'time_updated' => array('operator' => 'lt', 'value'=> 'today'),
221 'limit' => array('value'=> 1000),
222 );
223 }
224
225 public $useSelected;
226 public $prefix;
227
228 function get($ary, $key, $default="") {
229 return is_array($ary) && isset($ary[$key]) ? $ary[$key] : $default;
230 }
231
232 function inputPrefix($index) {
233 return sprintf('%s[%s]', $this->prefix ? $this->prefix : "query", $index);
234 }
235
236 function byName($a, $b) {
237 return strcasecmp($a['name'], $b['name']);
238 }
239
240 function ary($s) {
241 if(!is_array($s))
242 $s = explode(',', trim($s));
243 return array_filter($s, 'strlen');
244 }
245
246 function ids($lst) {
247 $ids = array();
248 foreach($lst as $obj)
249 $ids []= $obj['_id'];
250 return $ids;
251 }
252
253 function selectOpts($opts, $selectedValue=NULL) {
254 $html = "";
255 foreach($opts as $value => $title) {
256 $sel = $selectedValue == $value ? "selected='selected'" : "";
257 $title = htmlspecialchars($title);
258 $value = htmlspecialchars($value);
259 $html .= "<option value=\"$value\" $sel>$title</option>";
260 }
261 return $html;
262 }
263
264 function allNetworks() {
265 $lst = dfrapi_api_get_all_networks();
266 usort($lst, array($this, 'byName'));
267 return $lst;
268 }
269
270 function selectedNetworks() {
271 $selected = $this->get(get_option( 'dfrapi_networks' ), 'ids');
272 if(empty($selected))
273 return array();
274
275 $lst = array();
276 foreach($this->allNetworks() as $net)
277 if(isset($selected[$net['_id']]))
278 $lst []= $net;
279 return $lst;
280 }
281
282 function groupClass($nid) {
283 if (empty($nid)) { return ''; }
284 $networks = $this->allNetworks();
285 foreach($networks as $network) {
286 if ($network['_id'] == $nid) {
287 $name = str_replace( array( " ", "-", "." ), "", $network['group'] );
288 $type = ( $network['type'] == 'coupons' ) ? '_coupons' : '';
289 return 'network_logo_16x16_' . strtolower( $name . $type );
290 }
291 }
292 }
293
294 function selectedMerchants() {
295 $selected = $this->get(get_option( 'dfrapi_merchants' ), 'ids');
296 if(empty($selected))
297 return array();
298
299 $lst = array();
300 foreach(dfrapi_api_get_merchants_by_id($selected) as $merchant) {
301 $lst []= $merchant;
302 }
303 usort($lst, array($this, 'byName'));
304 return $lst;
305 }
306
307 function networksMerchantsPopup($kind, $value) {
308 $title = array(
309 'network' => __( 'Select Networks', DFRAPI_DOMAIN ),
310 'merchant' => __( 'Select Merchants', DFRAPI_DOMAIN )
311 );
312 $clear = __( 'Clear search', DFRAPI_DOMAIN );
313 $ok = __( 'OK', DFRAPI_DOMAIN );
314 $cells = "";
315
316 $all = ($kind == 'network') ?
317 ($this->useSelected ? $this->selectedNetworks() : $this->allNetworks()) :
318 $this->selectedMerchants();
319
320 foreach($all as $obj) {
321 $id = $obj['_id'];
322 $nid = ($kind == 'network') ? $obj['_id'] : $obj['source_id'];
323 $group_class = $this->groupClass($nid);
324
325 $name = $obj['name'];
326 $checked = in_array($id, $value) ? "checked='checked'" : "";
327
328 $cells .= "
329 <div class='inline_frame_element nid_{$nid}'>
330 <label>
331 <input type='checkbox' value='{$id}' $checked />
332 <span class='element_name {$group_class}'>{$name}</span>
333 </label>
334 </div>
335 ";
336 }
337
338 return "
339 <h1>{$title[$kind]}</h1>
340 <div class='filter_action'>
341 Search: <input type='text' />
342 <a class='reset_search button' title='{$clear}'>&times;</a>
343 </div>
344 <div class='inline_frame'>
345 <div>
346 {$cells}
347 <div class='clearfix'></div>
348 </div>
349 </div>
350 <div><a class='button submit'>$ok</a></div>
351 ";
352 }
353
354 function networksMerchantsNames($kind, $value, $maxNames=5) {
355 $all = ($kind == 'network') ? $this->allNetworks() : dfrapi_api_get_merchants_by_id($value);
356 $names = array();
357 foreach($all as $obj) {
358 if(in_array($obj['_id'], $value)) {
359 $names []= "<span>{$obj['name']}</span>";
360 if(count($names) >= $maxNames)
361 break;
362 }
363 }
364 $html = implode(', ', $names);
365 if(count($value) - count($names)) {
366 $html .= ' ' . sprintf(__( 'and %s more', DFRAPI_DOMAIN ), count($value) - count($names));
367 }
368 return $html;
369 }
370
371 function chooseBox($kind, $field, $index, $value) {
372 $pfx = $this->inputPrefix($index);
373 $value = implode(',', $this->ary($value));
374 $choose = __( 'choose', DFRAPI_DOMAIN );
375 return "
376 <div class='dfrapi_choose_box' rel='{$kind}'>
377 <span class='names'></span>
378 <a class='button choose_{$kind}'>{$choose}</a>
379 <input name='{$pfx}[value]' type='hidden' value=\"$value\"/>
380 </div>
381 ";
382 }
383
384 function ajaxHandler() {
385 $command = $this->get($_POST, 'command');
386 $value = $this->ary($this->get($_POST, 'value'));
387 $this->useSelected = intval($this->get($_POST, 'useSelected', 1));
388
389 switch($command) {
390 case "choose_network":
391 return $this->networksMerchantsPopup('network', $value);
392 case "choose_merchant":
393 return $this->networksMerchantsPopup('merchant', $value);
394 case "names_network":
395 return $this->networksMerchantsNames('network', $value);
396 case "names_merchant":
397 return $this->networksMerchantsNames('merchant', $value);
398 }
399 return "";
400 }
401
402 function renderField($field, $index, $params) {
403 $pfx = $this->inputPrefix($index);
404 $value = $this->get($params, 'value');
405 $operator = $this->get($params, 'operator');
406 $input = "";
407 $percent_sign = ( isset( $field['name'] ) && $field['name'] == 'salediscount') ? '%' : '';
408
409 switch($field['input']) {
410 case 'text':
411 $value = htmlspecialchars($value);
412 $input = "<input class='long' name='{$pfx}[value]' type='text' value=\"$value\"/>";
413 break;
414 case 'select':
415 $opts = $this->selectOpts($field['options'], $value);
416 $input = "<select name='{$pfx}[value]'>{$opts}</select>";
417 break;
418 case 'range':
419 $value = htmlspecialchars($value);
420 $value2 = htmlspecialchars($this->get($params, 'value2'));
421 $and = __( 'and', DFRAPI_DOMAIN );
422 $input = "
423 <input class='short' name='{$pfx}[value]' type='text' value=\"$value\"/>{$percent_sign}
424 <span class='value2' style='display:none'>
425 $and
426 <input class='short' name='{$pfx}[value2]' type='text' value=\"$value2\" />
427 </span>
428 ";
429 break;
430 case 'network':
431 $input = $this->chooseBox('network', $field, $index, $value);
432 break;
433 case 'merchant':
434 $input = $this->chooseBox('merchant', $field, $index, $value);
435 break;
436 case 'none':
437 $input = "";
438 break;
439 }
440
441 if(count($field['operator']) == 1) {
442 $key = key($field['operator']);
443 $val = current($field['operator']);
444 $operator = "
445 <input type='hidden' name='{$pfx}[operator]' value=\"{$key}\" />
446 <span>{$val}</span>
447 ";
448 } else {
449 $opts = $this->selectOpts($field['operator'], $operator);
450 $operator = "<select name='{$pfx}[operator]'>{$opts}</select>";
451 }
452 return array($operator, $input);
453 }
454
455 function renderRow($field, $index, $params, $show) {
456 $pfx = $this->inputPrefix($index);
457 list($operator, $input) = $this->renderField($field, $index, $params);
458 $fieldOpts = '';
459 foreach($this->fields() as $f) {
460 if(!$this->useSelected && $f['name'] == 'merchant_id')
461 continue;
462 $sel = $field['name'] == $f['name'] ? "selected='selected'" : "";
463 $fieldOpts .= "<option value=\"{$f['name']}\" $sel>{$f['title']}</option>";
464 }
465 $style = $show ? "" : "style='display:none'";
466 return "
467 <div class='filter filter_{$field['name']}' {$style}>
468 <div class='valuewrapper'>
469 <div class='value'>{$input}</div>
470 </div>
471 <div class='plusminus'><a class='minus'></a> </div>
472 <div class='field'><select name='{$pfx}[field]' style='width: 140px'>{$fieldOpts}</select><a href='#' class='dfrapi_search_help'>?</a></div>
473 <div class='operator'>{$operator}</div>
474 <div class='clearfix'></div>
475 <div class='help' style='display:none;'><a href='#' class='dfrapi_search_help'><span class='dashicons dashicons-no'> </span></a>{$field['help']}</div>
476 </div>
477 ";
478 }
479
480 function render($prefix, $query, $useSelected=TRUE) {
481 $this->prefix = $prefix;
482 $this->useSelected = intval($useSelected);
483 if(!$query)
484 $query = array(
485 array('field'=>'any', 'value'=>'')
486 );
487 $defaults = $this->defaults();
488
489 $fieldMap = array();
490 $fieldUsed = array();
491 foreach($this->fields() as $f) {
492 if(!$this->useSelected && $f['name'] == 'merchant_id')
493 continue;
494 $fieldMap[$f['name']] = $f;
495 }
496
497 $form = "";
498 $index = 0;
499 foreach($query as $params) {
500 $field = $this->get($fieldMap, $this->get($params, 'field'));
501 if(!$field)
502 continue;
503 $fieldUsed[$field['name']] = 1;
504 $form .= $this->renderRow($field, $index++, $params, TRUE);
505 }
506 $show = ($index == 0); // if none shown, show the first
507 foreach($fieldMap as $field) {
508 $name = $field['name'];
509 if(!isset($fieldUsed[$name])) {
510 $form .= $this->renderRow($field, $index++, isset($defaults[$name]) ? $defaults[$name] : null, $show);
511 $show = FALSE;
512 }
513 }
514
515 $loading = __( 'Loading, please wait', DFRAPI_DOMAIN );
516 $add = __( 'add filter', DFRAPI_DOMAIN );
517 return "
518 <div id='dfrapi_search_form'>
519 <input type='hidden' id='dfrapi_useSelected' value='{$this->useSelected}' />
520 <div id='dfprs_loading_content' style='display:none'>
521 <div class='dfrapi_loading'></div>
522 <h3>{$loading}</h3>
523 </div>
524 {$form}
525 <div class='clearfix'></div>
526 <div id='dfrapi_search_form_filter'><a href='#'><span class='dashicons dashicons-plus'> </span> $add</a></div>
527 </div>
528 ";
529 }
530
531 function combineLists($lst, $func) {
532 if(!count($lst))
533 return array();
534 if(count($lst) == 1)
535 return current($lst);
536 $lst = call_user_func_array($func, $lst);
537 return count($lst) ? $lst : NULL;
538 }
539
540 function idFilter($inList, $exList) {
541 $inList = $this->combineLists($inList, 'array_intersect');
542 $exList = $this->combineLists($exList, 'array_merge');
543
544 if(is_null($inList) || is_null($exList)) {
545 return NULL;
546 }
547 if(count($inList)) {
548 if(count($exList)) {
549 $inList = array_diff($inList, $exList);
550 if(!count($inList))
551 return NULL;
552 }
553 return array("IN", $inList);
554 }
555 if(count($exList)) {
556 return array("!IN", $exList);
557 }
558 return array(NULL, NULL);
559 }
560
561 function fulltextFilter($operator, $value) {
562 if($operator == 'match')
563 return array("LIKE", $value);
564 $value = trim(preg_replace('~[!\\[\\]"^$]+~', " ", $value));
565 if(strlen($value)) {
566 switch($operator) {
567 case 'is': return array('LIKE', "^$value\$");
568 case 'contain': return array('LIKE', $value);
569 case 'not_contain': return array('!LIKE', $value);
570 case 'start': return array('LIKE', "^$value");
571 case 'end': return array('LIKE', "$value\$");
572 }
573 }
574 return array(NULL, NULL);
575 }
576
577 function makeFilters($query, $useSelected=TRUE) {
578
579 $filters = array();
580
581 $selected = array(
582 'in:source_id' => array(),
583 'ex:source_id' => array(),
584 'in:merchant_id' => array(),
585 'ex:merchant_id' => array(),
586 );
587
588 $allNetworks = $this->ids($this->allNetworks());
589
590 if($useSelected) {
591 $selected['in:source_id'] []= $this->ids($this->selectedNetworks());
592 $selected['in:merchant_id'] []= $this->ids($this->selectedMerchants());
593 } else {
594 $selected['in:source_id'] []= $allNetworks;
595 }
596
597 foreach($query as $params) {
598 $fname = $params['field'];
599 $value = $this->get($params, 'value');
600 $value2 = $this->get($params, 'value2');
601 $operator = strtolower($this->get($params, 'operator'));
602
603 switch($fname) {
604 case 'any':
605 case 'name':
606 case 'brand':
607 case 'description':
608 case 'category':
609 $s = $this->fulltextFilter($operator, $value);
610 if(!is_null($s[0])) {
611 $filters []= "{$fname} {$s[0]} {$s[1]}";
612 }
613 break;
614 case 'tags':
615 $operator = ($operator == 'in') ? "LIKE" : "!LIKE";
616 $filters []= "{$fname} {$operator} {$value}";
617 break;
618 case 'currency':
619 $op = ($operator == 'is') ? '=' : '!=';
620 $filters []= "{$fname} $op {$value}";
621 break;
622 case 'id':
623 $op = ($operator == 'is') ? 'IN' : '!IN';
624 $filters []= "{$fname} $op {$value}";
625 break;
626 case 'price':
627 case 'saleprice':
628 case 'salediscount':
629 $conv = $fname == 'salediscount' ? 'intval' : 'dfrapi_price_to_int';
630 $value = $conv($value);
631 switch($operator) {
632 case 'between':
633 $value2 = $conv($value2);
634 $filters []= "{$fname} > {$value}";
635 $filters []= "{$fname} < {$value2}";
636 break;
637 case 'lt':
638 $filters []= "{$fname} < {$value}";
639 break;
640 case 'gt':
641 $filters []= "{$fname} > {$value}";
642 break;
643 }
644 break;
645 case 'source_id':
646 case 'merchant_id':
647 $key = ($operator == 'is') ? 'in' : 'ex';
648 $selected["$key:$fname"] []= $this->ary($value);
649 break;
650 case 'type':
651 $ids = array();
652 foreach($this->allNetworks() as $net) {
653 if($net['type'] == $value)
654 $ids []= $net['_id'];
655 }
656 $selected["in:source_id"] []= $ids;
657 break;
658 case 'onsale':
659 $value = ($operator == 'yes') ? '1' : '0';
660 $filters []= "{$fname} = {$value}";
661 break;
662 case 'image':
663 case 'thumbnail':
664 $operator = ($operator == 'yes') ? '!EMPTY' : 'EMPTY';
665 $filters []= "image {$operator}";
666 break;
667 case 'time_updated':
668 $value = @date('Y-m-d H:i:s', strtotime($value));
669 switch($operator) {
670 case 'between':
671 $value2 = @date('Y-m-d H:i:s', strtotime($value2));
672 $filters []= "{$fname} > {$value}";
673 $filters []= "{$fname} < {$value2}";
674 break;
675 case 'lt':
676 $filters []= "{$fname} < {$value}";
677 break;
678 case 'gt':
679 $filters []= "{$fname} > {$value}";
680 break;
681 }
682 break;
683 }
684 }
685
686 $s = $this->idFilter($selected['in:source_id'], $selected['ex:source_id']);
687 if(is_null($s))
688 return array('error' => 'No networks selected');
689 if(!is_null($s[0]) && count($s[1]) < count($allNetworks))
690 $filters []= "source_id {$s[0]} ". implode(',', $s[1]);
691
692 $s = $this->idFilter($selected['in:merchant_id'], $selected['ex:merchant_id']);
693 if(is_null($s))
694 return array('error' => 'No merchants selected');
695 if(!is_null($s[0]))
696 $filters []= "merchant_id {$s[0]} ". implode(',', $s[1]);
697
698 return $filters;
699
700 }
701
702 function help_tip($tip) {
703 return '
704 <div class="dfrapi_search_tip">
705 <span class="dashicons dashicons-lightbulb"></span>
706 <p>
707 <strong>' . __( 'TIP:', DFRAPI_DOMAIN ) . '</strong> ' .
708 $tip . '
709 </p>
710 </div>
711 ';
712 }
713
714 function help_operators() {
715 return '
716 <p>
717 <span class="dashicons dashicons-info"></span>
718 <em>
719 <a href="https://v4.datafeedr.com/node/620" target="_blank">' . __('Learn more', DFRAPI_DOMAIN ) . '</a> ' .
720 __('about advanced uses of this field.', DFRAPI_DOMAIN ) . '
721 </em>
722 </p>
723 ';
724 }
725
726 function help($field) {
727
728 $help = array();
729
730 // Any
731 $help['any'] = '<h3>' . __('Any Field', DFRAPI_DOMAIN ) . '</h3>';
732 $help['any'] .= '<p>' . __( 'Search all indexed text fields at once to return a broad set of results.', DFRAPI_DOMAIN ) . '</p>';
733 $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.', DFRAPI_DOMAIN ) . '</p>';
734 $help['any'] .= '<p><em>' . __( '*Note that not all merchants and networks provide every field. ', DFRAPI_DOMAIN ) . '</em></p>';
735 $help['any'] .= '<p>' . __( 'Fields searched using Any Field:', DFRAPI_DOMAIN ) . '</p>';
736 $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 />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>';
737 $help['any'] .= $this->help_operators();
738
739 // Name
740 $help['name'] = '<h3>' . __('Product Name', DFRAPI_DOMAIN ) . '</h3>';
741 $help['name'] .= '<p>' . __( 'Search by product name to narrow your results.', DFRAPI_DOMAIN ) . '</p>';
742 $help['name'] .= $this->help_tip( __( 'Some merchants include color, size, gender, product codes, sale information and promotions in the product name field.', DFRAPI_DOMAIN ) );
743 $help['name'] .= $this->help_operators();
744
745 // Brand
746 $help['brand'] = '<h3>' . __('Brand', DFRAPI_DOMAIN ) . '</h3>';
747 $help['brand'] .= '<p>' . __( 'Search by brand name to get specific results. Not every item has a brand name.', DFRAPI_DOMAIN ) . '</p>';
748 $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.', DFRAPI_DOMAIN ) );
749 $help['brand'] .= $this->help_operators();
750
751 // Description
752 $help['description'] = '<h3>' . __('Description', DFRAPI_DOMAIN ) . '</h3>';
753 $help['description'] .= '<p>' . __( 'Search the description field for product attributes such as size, color, material, or usage.', DFRAPI_DOMAIN ) . '</p>';
754 $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.', DFRAPI_DOMAIN ) );
755 $help['description'] .= $this->help_operators();
756
757 // Tags
758 $help['tags'] = '<h3>' . __('Tags', DFRAPI_DOMAIN ) . '</h3>';
759 $help['tags'] .= '<p>' . __( 'Limit search results based on product tag and keyword information.', DFRAPI_DOMAIN ) . '</p>';
760 $help['tags'] .= $this->help_tip( __( 'This field contains data from various keyword-related fields provided by the merchant. This field does not always exist.', DFRAPI_DOMAIN ) );
761
762 // Category
763 $help['category'] = '<h3>' . __('Category', DFRAPI_DOMAIN ) . '</h3>';
764 $help['category'] .= '<p>' . __( 'Limit search results based on category information.', DFRAPI_DOMAIN ) . '</p>';
765 $help['category'] .= $this->help_tip( __( 'This field contains data from various category-related fields provided by the merchant. This field does not always exist.', DFRAPI_DOMAIN ) );
766 $help['category'] .= $this->help_operators();
767
768 // Type
769 $help['type'] = '<h3>' . __('Product Type', DFRAPI_DOMAIN ) . '</h3>';
770 $help['type'] .= '<p>' . __( 'Limit your search results to one type of item, either Product or Coupon.', DFRAPI_DOMAIN ) . '</p>';
771 $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.', DFRAPI_DOMAIN ) );
772
773 // Currency
774 $help['currency'] = '<h3>' . __('Currency', DFRAPI_DOMAIN ) . '</h3>';
775 $help['currency'] .= '<p>' . __( 'Limit your search results to items with a specific currency code.', DFRAPI_DOMAIN ) . '</p>';
776 $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.', DFRAPI_DOMAIN ) );
777
778 // Price
779 $help['price'] = '<h3>' . __('Price', DFRAPI_DOMAIN ) . '</h3>';
780 $help['price'] .= '<p>' . __( 'Filter your search results based on price. Return products less than, greater than, or within a price range that you set.', DFRAPI_DOMAIN ) . '</p>';
781 $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.', DFRAPI_DOMAIN ) );
782
783 // Sale Price
784 $help['saleprice'] = '<h3>' . __('Sale Price', DFRAPI_DOMAIN ) . '</h3>';
785 $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.', DFRAPI_DOMAIN ) . '</p>';
786 $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.', DFRAPI_DOMAIN ) );
787
788 // Network
789 $help['source_id'] = '<h3>' . __('Network', DFRAPI_DOMAIN ) . '</h3>';
790 $help['source_id'] .= '<p>' . __( 'Limit your search results to items from one or more affiliate networks.', DFRAPI_DOMAIN ) . '</p>';
791 $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.', DFRAPI_DOMAIN ) );
792
793 // Merchant
794 $help['merchant_id'] = '<h3>' . __('Merchant', DFRAPI_DOMAIN ) . '</h3>';
795 $help['merchant_id'] .= '<p>' . __( 'Limit your search results to items from one or more merchants.', DFRAPI_DOMAIN ) . '</p>';
796 $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.', DFRAPI_DOMAIN ) );
797
798 // On Sale
799 $help['onsale'] = '<h3>' . __('On Sale', DFRAPI_DOMAIN ) . '</h3>';
800 $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>".', DFRAPI_DOMAIN ) . '</p>';
801
802 // Discount
803 $help['salediscount'] = '<h3>' . __('Discount', DFRAPI_DOMAIN ) . '</h3>';
804 $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.', DFRAPI_DOMAIN ) . '</p>';
805 $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".', DFRAPI_DOMAIN ) );
806
807 // Has Image
808 $help['image'] = '<h3>' . __('Has Image', DFRAPI_DOMAIN ) . '</h3>';
809 $help['image'] .= '<p>' . __( 'Limit your search results to items which have an image (or which don\'t).', DFRAPI_DOMAIN ) . '</p>';
810 $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.', DFRAPI_DOMAIN ) );
811
812 // Last Updated
813 $help['time_updated'] = '<h3>' . __('Last Updated', DFRAPI_DOMAIN ) . '</h3>';
814 $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.', DFRAPI_DOMAIN ) . '</p>';
815 $help['time_updated'] .= '<h3>' . __('Examples', DFRAPI_DOMAIN ) . '</h3>';
816 $help['time_updated'] .= '<p>';
817 $help['time_updated'] .= '<tt>' . __('last week', DFRAPI_DOMAIN ) . '</tt><br />';
818 $help['time_updated'] .= '<tt>' . __('2 days ago', DFRAPI_DOMAIN ) . '</tt><br />';
819 $help['time_updated'] .= '<tt>' . __('1 month ago', DFRAPI_DOMAIN ) . '</tt>';
820 $help['time_updated'] .= '</p>';
821 $help['time_updated'] .= '<p>' . __( '', DFRAPI_DOMAIN ) . '</p>';
822 $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.', DFRAPI_DOMAIN ) );
823
824 // Limit
825 $help['limit'] = '<h3>' . __('Limit', DFRAPI_DOMAIN ) . '</h3>';
826 $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.', DFRAPI_DOMAIN ) . '</p>';
827 $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.', DFRAPI_DOMAIN ) );
828
829 // Sort By
830 $help['sort'] = '<h3>' . __('Sort By', DFRAPI_DOMAIN ) . '</h3>';
831 $help['sort'] .= '<p>' . __( 'Change the sort criteria by which items are displayed in your search results.', DFRAPI_DOMAIN ) . '</p>';
832 $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.', DFRAPI_DOMAIN ) );
833
834 // Exclude Duplicates
835 $help['duplicates'] = '<h3>' . __('Exclude Duplicates', DFRAPI_DOMAIN ) . '</h3>';
836 $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).', DFRAPI_DOMAIN ) . '<br />';
837 $help['duplicates'] .= '<p>' . __( 'Enter one of these terms to exclude duplicates matching these fields:', DFRAPI_DOMAIN ) . '<br />';
838 $help['duplicates'] .= '<tt>' . __('name', DFRAPI_DOMAIN ) . '</tt><br />';
839 $help['duplicates'] .= '<tt>' . __('brand', DFRAPI_DOMAIN ) . '</tt><br />';
840 $help['duplicates'] .= '<tt>' . __('currency', DFRAPI_DOMAIN ) . '</tt><br />';
841 $help['duplicates'] .= '<tt>' . __('price', DFRAPI_DOMAIN ) . '</tt><br />';
842 $help['duplicates'] .= '<tt>' . __('saleprice', DFRAPI_DOMAIN ) . '</tt><br />';
843 $help['duplicates'] .= '<tt>' . __('source_id', DFRAPI_DOMAIN ) . '</tt><br />';
844 $help['duplicates'] .= '<tt>' . __('merchant_id', DFRAPI_DOMAIN ) . '</tt><br />';
845 $help['duplicates'] .= '<tt>' . __('onsale', DFRAPI_DOMAIN ) . '</tt><br />';
846 $help['duplicates'] .= '<tt>' . __('image', DFRAPI_DOMAIN ) . '</tt><br />';
847 $help['duplicates'] .= '<tt>' . __('thumbnail', DFRAPI_DOMAIN ) . '</tt>';
848 $help['duplicates'] .= '</p>';
849 $help['duplicates'] .= '<h3>' . __('Examples', DFRAPI_DOMAIN ) . '</h3>';
850 $help['duplicates'] .= '<p>';
851 $help['duplicates'] .= '<tt>' . __('image</tt> - Exclude items which have the same image URL.', DFRAPI_DOMAIN ) . '<br />';
852 $help['duplicates'] .= '<tt>' . __('name image</tt> - Exclude items with the same name AND the same image URL.', DFRAPI_DOMAIN ) . '<br />';
853 $help['duplicates'] .= '<tt>' . __('name|image</tt> - Exclude items with the same name OR the same image URL.', DFRAPI_DOMAIN ) . '<br />';
854 $help['duplicates'] .= '<tt>' . __('merchant_id name|image</tt> - Exclude items which have the same merchant id AND (product name OR image URL).', DFRAPI_DOMAIN ) . '<br />';
855 $help['duplicates'] .= '</p>';
856 $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.', DFRAPI_DOMAIN ) );
857
858
859 if (isset($help[$field])) {
860 return $help[$field];
861 } else {
862 return '';
863 }
864
865 } // help()
866
867 }
868