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

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