1 <?php namespace BookStack\Entities\Tools;
3 use Illuminate\Http\Request;
11 public $searches = [];
29 * Create a new instance from a search string.
31 public static function fromString(string $search): SearchOptions
33 $decoded = static::decode($search);
34 $instance = new static();
35 foreach ($decoded as $type => $value) {
36 $instance->$type = $value;
42 * Create a new instance from a request.
43 * Will look for a classic string term and use that
44 * Otherwise we'll use the details from an advanced search form.
46 public static function fromRequest(Request $request): SearchOptions
48 if (!$request->has('search') && !$request->has('term')) {
49 return static::fromString('');
52 if ($request->has('term')) {
53 return static::fromString($request->get('term'));
56 $instance = new static();
57 $inputs = $request->only(['search', 'types', 'filters', 'exact', 'tags']);
58 $instance->searches = explode(' ', $inputs['search'] ?? []);
59 $instance->exacts = array_filter($inputs['exact'] ?? []);
60 $instance->tags = array_filter($inputs['tags'] ?? []);
61 foreach (($inputs['filters'] ?? []) as $filterKey => $filterVal) {
62 if (empty($filterVal)) {
65 $instance->filters[$filterKey] = $filterVal === 'true' ? '' : $filterVal;
67 if (isset($inputs['types']) && count($inputs['types']) < 4) {
68 $instance->filters['type'] = implode('|', $inputs['types']);
74 * Decode a search string into an array of terms.
76 protected static function decode(string $searchString): array
86 'exacts' => '/"(.*?)"/',
87 'tags' => '/\[(.*?)\]/',
88 'filters' => '/\{(.*?)\}/'
91 // Parse special terms
92 foreach ($patterns as $termType => $pattern) {
94 preg_match_all($pattern, $searchString, $matches);
95 if (count($matches) > 0) {
96 $terms[$termType] = $matches[1];
97 $searchString = preg_replace($pattern, '', $searchString);
101 // Parse standard terms
102 foreach (explode(' ', trim($searchString)) as $searchTerm) {
103 if ($searchTerm !== '') {
104 $terms['searches'][] = $searchTerm;
108 // Split filter values out
110 foreach ($terms['filters'] as $filter) {
111 $explodedFilter = explode(':', $filter, 2);
112 $splitFilters[$explodedFilter[0]] = (count($explodedFilter) > 1) ? $explodedFilter[1] : '';
114 $terms['filters'] = $splitFilters;
120 * Encode this instance to a search string.
122 public function toString(): string
124 $string = implode(' ', $this->searches ?? []);
126 foreach ($this->exacts as $term) {
127 $string .= ' "' . $term . '"';
130 foreach ($this->tags as $term) {
131 $string .= " [{$term}]";
134 foreach ($this->filters as $filterName => $filterVal) {
135 $string .= ' {' . $filterName . ($filterVal ? ':' . $filterVal : '') . '}';