PluginProbe ʕ •ᴥ•ʔ
Tutor LMS – eLearning and online course solution / trunk
Tutor LMS – eLearning and online course solution vtrunk
4.0.7 4.0.6 4.0.5 4.0.4 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 / Sorting.php
tutor / components Last commit date
Constants 1 month ago Accordion.php 1 month ago Alert.php 1 month ago AttachmentCard.php 1 month ago Avatar.php 1 month ago Badge.php 1 month ago BaseComponent.php 1 month ago Button.php 1 month ago ConfirmationModal.php 1 month ago CourseFilter.php 1 month ago DateFilter.php 1 month ago DropdownFilter.php 1 month ago EmptyState.php 1 month ago FileUploader.php 1 month ago InputField.php 1 month ago Modal.php 1 month ago Nav.php 1 month ago Pagination.php 1 month ago Popover.php 1 month ago PreviewTrigger.php 1 month ago Progress.php 1 month ago SearchFilter.php 1 month ago Sorting.php 1 month ago StarRating.php 1 month ago StarRatingInput.php 1 month ago StatusSelect.php 1 month ago SvgIcon.php 1 month ago Table.php 1 month ago Tabs.php 1 month ago Tooltip.php 1 month ago WPEditor.php 1 month ago
Sorting.php
287 lines
1 <?php
2 /**
3 * Sorting Component Class.
4 *
5 * Responsible for rendering a sorting dropdown
6 * with ascending and descending options.
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\Helpers\QueryHelper;
17 use Tutor\Components\Constants\Positions;
18 use Tutor\Components\Constants\Color;
19 use Tutor\Components\Constants\Size;
20 use Tutor\Components\Popover;
21 use TUTOR\Icon;
22
23 defined( 'ABSPATH' ) || exit;
24
25 /**
26 * Class Sorting
27 *
28 * Example Usage:
29 * ```php
30 * // Minimal — URL query param driven, default labels
31 * Sorting::make()
32 * ->render();
33 *
34 * // Pre-set the active order from URL param
35 * Sorting::make()
36 * ->order( Input::get( 'order', 'DESC' ) )
37 * ->render();
38 *
39 * // Custom ascending/descending labels
40 * Sorting::make()
41 * ->order( 'DESC' )
42 * ->label_asc( __( 'Oldest', 'tutor' ) )
43 * ->label_desc( __( 'Newest', 'tutor' ) )
44 * ->render();
45 *
46 * // JavaScript callback on change (Alpine.js method)
47 * Sorting::make()
48 * ->order( 'DESC' )
49 * ->on_change( 'changeOrder' )
50 * ->bind_active_order( 'currentOrder' )
51 * ->render();
52 *
53 * // Cumulative filtering — preserve existing query params via base_url
54 * Sorting::make()
55 * ->order( Input::get( 'order', 'DESC' ) )
56 * ->base_url( remove_query_arg( 'current_page' ) )
57 * ->render();
58 *
59 * // Custom button size
60 * Sorting::make()
61 * ->order( 'ASC' )
62 * ->size( Size::SMALL )
63 * ->render();
64 *
65 * // Retrieve HTML without echoing
66 * $html = Sorting::make()->order( 'DESC' )->get();
67 * ```
68 *
69 * @since 4.0.0
70 */
71 class Sorting extends BaseComponent {
72
73 /**
74 * Order param
75 *
76 * @var string
77 */
78 protected $order = 'DESC';
79
80 /**
81 * Label for ascending order
82 *
83 * @var string
84 */
85 protected $label_asc;
86
87 /**
88 * Label for descending order
89 *
90 * @var string
91 */
92 protected $label_desc;
93
94 /**
95 * On change callback function name
96 *
97 * @var string
98 */
99 protected $on_change = '';
100
101 /**
102 * Alpine.js variable name for active state
103 *
104 * @var string
105 */
106 protected $active_order = '';
107
108 /**
109 * Base URL for building sort links (preserves other query params when set).
110 *
111 * @var string
112 */
113 protected $base_url = '';
114
115 /**
116 * Component size
117 *
118 * @var string
119 */
120 protected $size = Size::X_SMALL;
121
122 /**
123 * Constructor
124 */
125 public function __construct() {
126 $this->label_asc = __( 'Oldest First', 'tutor' );
127 $this->label_desc = __( 'Newest First', 'tutor' );
128 }
129
130 /**
131 * Set order
132 *
133 * @param string $order order.
134 *
135 * @return self
136 */
137 public function order( string $order ): self {
138 $this->order = QueryHelper::get_valid_sort_order( $order );
139 return $this;
140 }
141
142 /**
143 * Set label for ascending order
144 *
145 * @param string $label label.
146 *
147 * @return self
148 */
149 public function label_asc( string $label ): self {
150 $this->label_asc = $label;
151 return $this;
152 }
153
154 /**
155 * Set label for descending order
156 *
157 * @param string $label label.
158 *
159 * @return self
160 */
161 public function label_desc( string $label ): self {
162 $this->label_desc = $label;
163 return $this;
164 }
165
166 /**
167 * Set JS callback on change
168 *
169 * @param string $method_name JS method name.
170 *
171 * @return self
172 */
173 public function on_change( string $method_name ): self {
174 $this->on_change = $method_name;
175 return $this;
176 }
177
178 /**
179 * Set Alpine.js active state binding
180 *
181 * @param string $active_order Alpine variable name.
182 * @return self
183 */
184 public function bind_active_order( string $active_order ): self {
185 $this->active_order = $active_order;
186 return $this;
187 }
188
189 /**
190 * Set base URL for sort links so other query params are preserved (cumulative filtering).
191 *
192 * @param string $url Full current page URL including query string.
193 *
194 * @return self
195 */
196 public function base_url( string $url ): self {
197 $this->base_url = $url;
198 return $this;
199 }
200
201 /**
202 * Set component size
203 *
204 * @param string $size size.
205 *
206 * @return self
207 */
208 public function size( string $size ): self {
209 $this->size = $size;
210 return $this;
211 }
212
213 /**
214 * Get component content
215 *
216 * @return string
217 */
218 public function get(): string {
219 $orders = array(
220 'DESC' => $this->label_desc,
221 'ASC' => $this->label_asc,
222 );
223
224 $origin = Popover::TRANSFORM_ORIGIN_MAP[ Positions::BOTTOM_END ] ?? 'right.top';
225
226 ob_start();
227 ?>
228 <div
229 x-data="tutorPopover({
230 placement: 'bottom-end',
231 offset: 4,
232 })"
233 >
234 <button
235 type="button"
236 x-ref="trigger"
237 @click="toggle()"
238 class="tutor-btn tutor-btn-outline tutor-btn-<?php echo esc_attr( $this->size ); ?> tutor-btn-icon"
239 aria-label="<?php esc_attr_e( 'Open sorting options', 'tutor' ); ?>"
240 >
241 <?php
242 $sorting_icon = 'DESC' === $this->order ? Icon::ASCENDING : Icon::DESCENDING;
243 SvgIcon::make()->name( $sorting_icon )->size( 16 )->color( Color::SECONDARY )->render();
244 ?>
245 </button>
246
247 <div
248 x-ref="content"
249 x-show="open"
250 x-cloak
251 x-transition.<?php echo esc_attr( $origin ); ?>
252 @click.outside="handleClickOutside()"
253 class="tutor-popover"
254 >
255 <div class="tutor-popover-menu" style="min-width: 108px;">
256 <?php foreach ( $orders as $order => $label ) : ?>
257 <?php
258 $order_url = ! empty( $this->base_url ) ? add_query_arg( 'order', $order, $this->base_url ) : add_query_arg( 'order', $order );
259 ?>
260 <?php if ( $this->on_change ) : ?>
261 <button
262 type="button"
263 @click="<?php echo esc_js( $this->on_change ); ?>('<?php echo esc_attr( $order ); ?>'); hide()"
264 class="tutor-popover-menu-item <?php echo esc_attr( ! $this->active_order && $this->order === $order ? ' tutor-active' : '' ); ?>"
265 <?php if ( $this->active_order ) : ?>
266 :class="{ 'tutor-active': (<?php echo esc_attr( $this->active_order ); ?> || '') === '<?php echo esc_attr( $order ); ?>' }"
267 <?php endif; ?>
268 >
269 <?php echo esc_html( $label ); ?>
270 </button>
271 <?php else : ?>
272 <a
273 href="<?php echo esc_attr( $order_url ); ?>"
274 class="tutor-popover-menu-item <?php echo esc_attr( $this->order === $order ? ' tutor-active' : '' ); ?>"
275 >
276 <?php echo esc_html( $label ); ?>
277 </a>
278 <?php endif; ?>
279 <?php endforeach; ?>
280 </div>
281 </div>
282 </div>
283 <?php
284 return ob_get_clean();
285 }
286 }
287