1: <?php
2:
3: namespace Baril\Sqlout;
4:
5: use Closure;
6: use Laravel\Scout\Builder as ScoutBuilder;
7:
8: class Builder extends ScoutBuilder
9: {
10: public const NATURAL_LANGUAGE = 'in natural language mode';
11: public const QUERY_EXPANSION = 'in natural language mode with query expansion';
12: public const BOOLEAN = 'in boolean mode';
13:
14: /**
15: * The search mode (one of the consts above).
16: *
17: * @var string
18: */
19: public $mode;
20:
21: /**
22: * The array of scopes that will be applied to the model query.
23: *
24: * @var array
25: */
26: public $scopes = [];
27:
28: /**
29: * Create a new search builder instance.
30: *
31: * @param \Illuminate\Database\Eloquent\Model $model
32: * @param string $query
33: * @param \Closure $callback
34: * @param bool $softDelete
35: * @return void
36: */
37: public function __construct($model, $query, $callback = null, $softDelete = false)
38: {
39: parent::__construct($model, $query, $callback, $softDelete);
40: if ($softDelete) {
41: unset($this->wheres['__soft_deleted']);
42: }
43: }
44:
45: public function __call($method, $parameters)
46: {
47: if (static::hasMacro($method)) {
48: return parent::__call($method, $parameters);
49: }
50:
51: $this->scopes[] = [$method, $parameters];
52: return $this;
53: }
54:
55: public function scope(Closure $callback)
56: {
57: $this->scopes[] = $callback;
58: return $this;
59: }
60:
61: /**
62: * Add a constraint to the search query.
63: *
64: * @param string $field
65: * @param mixed $value
66: * @return $this
67: */
68: public function where($field, $value)
69: {
70: $args = func_get_args();
71: $this->scopes[] = ['where', $args];
72: return $this;
73: }
74:
75: /**
76: * Include soft deleted records in the results.
77: *
78: * @return $this
79: */
80: public function withTrashed()
81: {
82: $this->scopes[] = ['withTrashed', []];
83: return $this;
84: }
85:
86: /**
87: * Include only soft deleted records in the results.
88: *
89: * @return $this
90: */
91: public function onlyTrashed()
92: {
93: $this->scopes[] = ['onlyTrashed', []];
94: return $this;
95: }
96:
97: /**
98: * Order the query by score.
99: *
100: * @param string $direction
101: * @return $this
102: */
103: public function orderByScore($direction = 'desc')
104: {
105: return $this->orderBy('_score', $direction);
106: }
107:
108: /**
109: * Restrict the search to the provided field(s).
110: *
111: * @param string|array|\Illuminate\Contracts\Support\Arrayable $fields
112: * @return $this
113: */
114: public function only($fields)
115: {
116: return parent::where('field', $fields);
117: }
118:
119: /**
120: * Switches to the provided mode.
121: *
122: * @param string $mode
123: * @return $this
124: */
125: public function mode($mode)
126: {
127: $this->mode = trim(strtolower($mode));
128: return $this;
129: }
130:
131: /**
132: * Switches to natural language mode.
133: *
134: * @param string $mode
135: * @return $this
136: */
137: public function inNaturalLanguageMode()
138: {
139: return $this->mode(static::NATURAL_LANGUAGE);
140: }
141:
142: /**
143: * Switches to natural language mode with query expansion.
144: *
145: * @param string $mode
146: * @return $this
147: */
148: public function withQueryExpansion()
149: {
150: return $this->mode(static::QUERY_EXPANSION);
151: }
152:
153: /**
154: * Switches to boolean mode.
155: *
156: * @param string $mode
157: * @return $this
158: */
159: public function inBooleanMode()
160: {
161: return $this->mode(static::BOOLEAN);
162: }
163:
164: /**
165: * Returns the total number of hits
166: *
167: * @return int
168: */
169: public function count()
170: {
171: return $this->engine()->getTotalCount(
172: $this->engine()->search($this)
173: );
174: }
175: }
176: