PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / 4.0.3
Tutor LMS – eLearning and online course solution v4.0.3
4.0.3 4.0.2 4.0.1 4.0.0 3.9.15 3.9.14 3.9.13 3.9.12 3.9.11 trunk 1.0.0 1.0.0-alpha 1.0.1 1.0.2 1.0.3 1.0.4 1.0.5 1.0.6 1.0.7 1.0.8 1.0.9 1.1.0 1.1.1 1.2.0 1.2.1 1.2.11 1.2.12 1.2.13 1.2.20 1.3.0 1.3.1 1.3.2 1.3.3 1.3.4 1.3.5 1.3.6 1.3.7 1.3.8 1.3.9 1.4.0 1.4.1 1.4.2 1.4.3 1.4.4 1.4.5 1.4.6 1.4.7 1.4.8 1.4.9 1.5.0 1.5.1 1.5.2 1.5.3 1.5.4 1.5.5 1.5.6 1.5.7 1.5.8 1.5.9 1.6.0 1.6.1 1.6.2 1.6.3 1.6.4 1.6.5 1.6.6 1.6.7 1.6.8 1.6.9 1.7.0 1.7.1 1.7.2 1.7.3 1.7.4 1.7.5 1.7.6 1.7.7 1.7.8 1.7.9 1.8.0 1.8.1 1.8.10 1.8.2 1.8.3 1.8.4 1.8.5 1.8.6 1.8.7 1.8.8 1.8.9 1.9.0 1.9.1 1.9.10 1.9.11 1.9.12 1.9.13 1.9.14 1.9.15 1.9.16 1.9.2 1.9.3 1.9.4 1.9.5 1.9.6 1.9.7 1.9.8 1.9.9 2.0.0 2.0.1 2.0.10 2.0.2 2.0.3 2.0.4 2.0.5 2.0.6 2.0.7 2.0.8 2.0.9 2.1.0 2.1.1 2.1.10 2.1.2 2.1.3 2.1.4 2.1.5 2.1.6 2.1.7 2.1.8 2.1.9 2.2.0 2.2.1 2.2.2 2.2.3 2.2.4 2.3.0 2.4.0 2.5.0 2.6.0 2.6.1 2.6.2 2.7.0 2.7.1 2.7.2 2.7.3 2.7.4 2.7.5 2.7.6 2.7.7 3.0.0 3.0.1 3.0.2 3.1.0 3.2.0 3.2.1 3.2.2 3.2.3 3.3.0 3.3.1 3.4.0 3.4.1 3.4.2 3.5.0 3.6.0 3.6.1 3.6.2 3.6.3 3.6.4 3.7.0 3.7.1 3.7.2 3.7.3 3.7.4 3.8.0 3.8.1 3.8.2 3.8.3 3.9.0 3.9.1 3.9.10 3.9.2 3.9.3 3.9.4 3.9.5 3.9.6 3.9.7 3.9.8 3.9.9
tutor / components / SearchFilter.php
tutor / components Last commit date
Constants 3 weeks ago Accordion.php 6 days ago Alert.php 6 days ago AttachmentCard.php 6 days ago Avatar.php 6 days ago Badge.php 6 days ago BaseComponent.php 3 weeks ago Button.php 6 days ago ConfirmationModal.php 6 days ago CourseFilter.php 6 days ago DateFilter.php 6 days ago DropdownFilter.php 6 days ago EmptyState.php 6 days ago FileUploader.php 6 days ago InputField.php 6 days ago Modal.php 6 days ago Nav.php 6 days ago Pagination.php 6 days ago Popover.php 6 days ago PreviewTrigger.php 6 days ago Progress.php 6 days ago SearchFilter.php 6 days ago Sorting.php 6 days ago StarRating.php 6 days ago StarRatingInput.php 6 days ago StatusSelect.php 6 days ago SvgIcon.php 6 days ago Table.php 6 days ago Tabs.php 6 days ago Tooltip.php 6 days ago WPEditor.php 6 days ago
SearchFilter.php
303 lines
1 <?php
2 /**
3 * SearchFilter Component Class.
4 *
5 * Responsible for rendering a search filter component
6 * that handles server-side filtering via search param.
7 *
8 * @package Tutor\Components
9 * @author Themeum
10 * @link https://themeum.com
11 * @since 4.0.0
12 */
13
14 namespace Tutor\Components;
15
16 use Tutor\Components\Constants\Size;
17 use Tutor\Components\Constants\Color;
18 use TUTOR\Icon;
19 use TUTOR\Input;
20
21 defined( 'ABSPATH' ) || exit;
22
23 /**
24 * Class SearchFilter
25 *
26 * Example Usage:
27 * ```php
28 * // Minimal search form (uses current URL, param name = 'search')
29 * SearchFilter::make()
30 * ->render();
31 *
32 * // With custom placeholder and input name
33 * SearchFilter::make()
34 * ->placeholder( 'Search students...' )
35 * ->input_name( 'student_search' )
36 * ->render();
37 *
38 * // With explicit action URL and hidden inputs to preserve context
39 * SearchFilter::make()
40 * ->action( admin_url( 'admin.php?page=tutor-students' ) )
41 * ->input_name( 'search' )
42 * ->hidden_inputs( array( 'type' => 'enrolled', 'course_id' => $course_id ) )
43 * ->render();
44 *
45 * // Small-size search field
46 * SearchFilter::make()
47 * ->placeholder( 'Search...' )
48 * ->size( Size::SMALL )
49 * ->render();
50 *
51 * // Large-size search field
52 * SearchFilter::make()
53 * ->placeholder( 'Search courses...' )
54 * ->size( Size::LARGE )
55 * ->render();
56 *
57 * // Custom form ID (useful when multiple search forms exist on the same page)
58 * SearchFilter::make()
59 * ->form_id( 'announcement-search-form' )
60 * ->placeholder( 'Search announcements...' )
61 * ->render();
62 *
63 * // POST method (e.g., for AJAX-backed searches)
64 * SearchFilter::make()
65 * ->input_name( 'q' )
66 * ->method( 'POST' )
67 * ->render();
68 *
69 * // Retrieve HTML without echoing
70 * $html = SearchFilter::make()->placeholder( 'Find a course...' )->get();
71 * ```
72 *
73 * @since 4.0.0
74 */
75 class SearchFilter extends BaseComponent {
76
77 /**
78 * Form ID
79 *
80 * @var string
81 */
82 protected $form_id = 'tutor-search-filter-form';
83
84 /**
85 * Search Placeholder
86 *
87 * @var string
88 */
89 protected $placeholder;
90
91 /**
92 * Form Action URL
93 *
94 * @var string
95 */
96 protected $action_url;
97
98 /**
99 * Search Input Name
100 *
101 * @var string
102 */
103 protected $input_name = 'search';
104
105 /**
106 * Additional hidden inputs
107 *
108 * @var array
109 */
110 protected $hidden_inputs = array();
111
112 /**
113 * Input Size
114 *
115 * @var string
116 */
117 protected $size = Size::MEDIUM;
118
119 /**
120 * Form Method
121 *
122 * @var string
123 */
124 protected $method = 'GET';
125
126
127 /**
128 * Set form ID
129 *
130 * @param string $form_id form ID.
131 *
132 * @return self
133 */
134 public function form_id( string $form_id ): self {
135 $this->form_id = $form_id;
136 return $this;
137 }
138
139 /**
140 * Set placeholder
141 *
142 * @param string $placeholder placeholder.
143 *
144 * @return self
145 */
146 public function placeholder( string $placeholder ): self {
147 $this->placeholder = $placeholder;
148 return $this;
149 }
150
151 /**
152 * Set action URL
153 *
154 * @param string $url action URL.
155 *
156 * @return self
157 */
158 public function action( string $url ): self {
159 $this->action_url = $url;
160 return $this;
161 }
162
163 /**
164 * Set input name
165 *
166 * @param string $name input name.
167 *
168 * @return self
169 */
170 public function input_name( string $name ): self {
171 $this->input_name = $name;
172 return $this;
173 }
174
175 /**
176 * Add hidden inputs
177 *
178 * @param array $inputs Input array.
179 *
180 * @return self
181 */
182 public function hidden_inputs( array $inputs ): self {
183 $this->hidden_inputs = array_merge( $this->hidden_inputs, $inputs );
184 return $this;
185 }
186
187 /**
188 * Set size of the input
189 *
190 * @param string $size size of the input.
191 *
192 * @return self
193 */
194 public function size( string $size ): self {
195 $this->size = $size;
196 return $this;
197 }
198
199 /**
200 * Set form method
201 *
202 * @param string $method form method.
203 *
204 * @return self
205 */
206 public function method( string $method ): self {
207 $this->method = $method;
208 return $this;
209 }
210
211
212 /**
213 * Get component content
214 *
215 * @return string
216 */
217 public function get(): string {
218 $form_id = $this->form_id;
219 $placeholder = $this->placeholder ?? __( 'Search...', 'tutor' );
220 $current_url = $this->action_url ?? '';
221 $input_name = $this->input_name;
222 $search_value = Input::get( $input_name, '' );
223 $size = Size::SMALL === $this->size ? 'tutor-input-sm' : ( Size::LARGE === $this->size ? 'tutor-input-lg' : '' );
224 $icon_size = Size::SMALL === $this->size ? 16 : ( Size::LARGE === $this->size ? 24 : 20 );
225 $method = $this->method;
226
227 if ( empty( $current_url ) ) {
228 // Fallback to current URL with preserved query args if not provided.
229 global $wp;
230 $current_url = add_query_arg( $_GET, home_url( $wp->request ) );
231 }
232
233 $clear_url = add_query_arg(
234 array_merge(
235 $this->hidden_inputs,
236 array( 'paged' => 1 )
237 ),
238 remove_query_arg( $input_name, $current_url )
239 );
240
241 $clear_action = 'GET' === strtoupper( $method )
242 ? 'window.location.href = ' . wp_json_encode( $clear_url )
243 : "setValue('" . esc_js( $input_name ) . "', ''); \$el.closest('form').submit();";
244
245 $this->attributes = array_merge(
246 array(
247 'action' => esc_url( $current_url ),
248 'method' => $method,
249 'id' => $form_id,
250 'x-data' => "tutorForm({ id: '" . esc_attr( $form_id ) . "', mode: 'onSubmit' })",
251 'x-bind' => 'getFormBindings()',
252 '@submit' => 'handleSubmit((data) => { $el.submit(); })($event)',
253 ),
254 $this->attributes
255 );
256
257 ob_start();
258 ?>
259 <form <?php $this->render_attributes(); // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped ?>>
260 <input type="hidden" name="paged" value="1">
261
262 <?php foreach ( $this->hidden_inputs as $name => $value ) : ?>
263 <input type="hidden" name="<?php echo esc_attr( $name ); ?>" value="<?php echo esc_attr( $value ); ?>">
264 <?php endforeach; ?>
265
266 <div class="tutor-input-field">
267 <div class="tutor-input-wrapper">
268 <div class="tutor-input-content tutor-input-content-left">
269 <?php
270 SvgIcon::make()
271 ->name( Icon::SEARCH_2 )
272 ->size( $icon_size )
273 ->color( Color::IDLE )
274 ->render();
275 ?>
276 </div>
277 <input
278 type="search"
279 name="<?php echo esc_attr( $input_name ); ?>"
280 placeholder="<?php echo esc_attr( $placeholder ); ?>"
281 class="tutor-input <?php echo esc_attr( $size ); ?> tutor-input-content-left tutor-input-content-clear"
282 x-bind="register('<?php echo esc_attr( $input_name ); ?>')"
283 x-init="$nextTick(() => setValue('<?php echo esc_attr( $input_name ); ?>', '<?php echo esc_attr( $search_value ); ?>'))"
284 />
285
286 <button
287 type="button"
288 class="tutor-input-clear-button"
289 x-show="values.<?php echo esc_attr( $input_name ); ?> && String(values.<?php echo esc_attr( $input_name ); ?>).length > 0"
290 x-cloak
291 aria-label="<?php esc_attr_e( 'Clear search', 'tutor' ); ?>"
292 @click="<?php echo esc_attr( $clear_action ); ?>"
293 >
294 <?php SvgIcon::make()->name( Icon::CROSS )->size( 16 )->render(); ?>
295 </button>
296 </div>
297 </div>
298 </form>
299 <?php
300 return ob_get_clean();
301 }
302 }
303