PluginProbe
Datafeedr API / 1.1.2
Datafeedr API v1.1.2
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 1.0.33 All 181 releases
datafeedr-api / classes / class-dfrapi-searchform.php

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

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