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

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