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

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