PluginProbe
Download Manager Addons for Elementor / trunk
Download Manager Addons for Elementor vtrunk
trunk 1.0.5 1.2.3 1.2.5 1.3.0
wpdm-elementor / src / widgets / AllPackagesWidget.php

AllPackagesWidget.php in Download Manager Addons for Elementor trunk, at src/widgets/AllPackagesWidget.php

415 lines 14.0 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 namespace WPDM\Elementor\Widgets;
4
5 use Elementor\Controls_Manager;
6 use Elementor\Repeater;
7
8 /**
9 * All Packages Widget.
10 * Displays packages in a table/grid format with customizable columns.
11 */
12 class AllPackagesWidget extends BaseWidget
13 {
14 /**
15 * Expected settings keys for this widget.
16 */
17 private const SETTINGS_KEYS = [
18 'categories', 'orderby', 'order', 'items_per_page',
19 'table_columns', 'cols', 'colheads', 'jstable', 'login'
20 ];
21
22 /**
23 * Settings sanitization rules.
24 */
25 private const SANITIZERS = [
26 'orderby' => 'orderby',
27 'order' => 'order',
28 'items_per_page' => 'int',
29 'cols' => 'text',
30 'colheads' => 'text',
31 'jstable' => 'text',
32 'login' => 'text',
33 ];
34
35 /**
36 * Available WPDM data fields for table columns.
37 *
38 * @return array Field key => label pairs.
39 */
40 private function getDataFieldOptions(): array
41 {
42 return [
43 // Basic Info
44 'title' => __('Title', WPDM_ELEMENTOR),
45 'page_link' => __('Title with Link', WPDM_ELEMENTOR),
46 'description' => __('Description', WPDM_ELEMENTOR),
47 'excerpt' => __('Excerpt', WPDM_ELEMENTOR),
48
49 // Taxonomy
50 'categories' => __('Categories', WPDM_ELEMENTOR),
51 'tags' => __('Tags', WPDM_ELEMENTOR),
52
53 // Download
54 'download_link' => __('Download Button', WPDM_ELEMENTOR),
55 'download_url' => __('Download URL', WPDM_ELEMENTOR),
56 'download_count' => __('Download Count', WPDM_ELEMENTOR),
57
58 // File Info
59 'file_size' => __('File Size', WPDM_ELEMENTOR),
60 'file_count' => __('File Count', WPDM_ELEMENTOR),
61 'file_type' => __('File Type', WPDM_ELEMENTOR),
62 'version' => __('Version', WPDM_ELEMENTOR),
63
64 // Dates
65 'publish_date' => __('Publish Date', WPDM_ELEMENTOR),
66 'update_date' => __('Update Date', WPDM_ELEMENTOR),
67
68 // Media
69 'thumb' => __('Thumbnail', WPDM_ELEMENTOR),
70 'preview' => __('Preview', WPDM_ELEMENTOR),
71 'icon' => __('File Icon', WPDM_ELEMENTOR),
72
73 // Author
74 'author' => __('Author Name', WPDM_ELEMENTOR),
75 //'author_pic' => __('Author Picture', WPDM_ELEMENTOR),
76
77 // Stats
78 'view_count' => __('View Count', WPDM_ELEMENTOR),
79
80 ];
81 }
82
83 public function get_name()
84 {
85 return 'wpdm-all-packages';
86 }
87
88 public function get_title()
89 {
90 return __('Packages Table', WPDM_ELEMENTOR);
91 }
92
93 public function get_icon()
94 {
95 return 'eicon-table';
96 }
97
98 public function get_keywords(): array
99 {
100 return ['wpdm', 'download', 'table', 'packages', 'list', 'grid'];
101 }
102
103 protected function register_controls()
104 {
105 // Content Section - Query
106 $this->start_controls_section(
107 'query_section',
108 [
109 'label' => __('Query', WPDM_ELEMENTOR),
110 'tab' => Controls_Manager::TAB_CONTENT,
111 ]
112 );
113
114 $this->add_control(
115 'categories',
116 [
117 'label' => __('Filter by Categories', WPDM_ELEMENTOR),
118 'type' => Controls_Manager::SELECT2,
119 'multiple' => true,
120 'options' => $this->getCategoryOptions(),
121 'default' => []
122 ]
123 );
124
125 $this->add_control(
126 'orderby',
127 [
128 'label' => __('Order By', WPDM_ELEMENTOR),
129 'type' => Controls_Manager::SELECT,
130 'options' => [
131 'date' => __('Date', WPDM_ELEMENTOR),
132 'title' => __('Title', WPDM_ELEMENTOR),
133 'download_count' => __('Download Count', WPDM_ELEMENTOR),
134 'rand' => __('Random', WPDM_ELEMENTOR),
135 ],
136 'default' => 'date',
137 ]
138 );
139
140 $this->add_control(
141 'order',
142 [
143 'label' => __('Order', WPDM_ELEMENTOR),
144 'type' => Controls_Manager::CHOOSE,
145 'options' => [
146 'ASC' => ['title' => __('Ascending', WPDM_ELEMENTOR), 'icon' => 'eicon-arrow-up'],
147 'DESC' => ['title' => __('Descending', WPDM_ELEMENTOR), 'icon' => 'eicon-arrow-down']
148 ],
149 'default' => 'DESC',
150 'toggle' => false
151 ]
152 );
153
154 $this->add_control(
155 'items_per_page',
156 [
157 'label' => __('Items Per Page', WPDM_ELEMENTOR),
158 'type' => Controls_Manager::NUMBER,
159 'min' => 1,
160 'max' => 100,
161 'default' => 10
162 ]
163 );
164
165 $this->end_controls_section();
166
167 // Content Section - Table Columns
168 $this->start_controls_section(
169 'columns_section',
170 [
171 'label' => __('Table Columns', WPDM_ELEMENTOR),
172 'tab' => Controls_Manager::TAB_CONTENT,
173 ]
174 );
175
176 $repeater = new Repeater();
177
178 $repeater->add_control(
179 'column_heading',
180 [
181 'label' => __('Column Heading', WPDM_ELEMENTOR),
182 'type' => Controls_Manager::TEXT,
183 'default' => __('Column', WPDM_ELEMENTOR),
184 'label_block' => true,
185 ]
186 );
187
188 $repeater->add_control(
189 'column_fields',
190 [
191 'label' => __('Data Fields', WPDM_ELEMENTOR),
192 'type' => Controls_Manager::SELECT2,
193 'multiple' => true,
194 'options' => $this->getDataFieldOptions(),
195 'default' => ['title'],
196 'label_block' => true,
197 'description' => __('Select one or more fields to display in this column', WPDM_ELEMENTOR),
198 ]
199 );
200
201 $repeater->add_control(
202 'column_width',
203 [
204 'label' => __('Column Width', WPDM_ELEMENTOR),
205 'type' => Controls_Manager::TEXT,
206 'default' => '',
207 'placeholder' => __('e.g., 100px or 20%', WPDM_ELEMENTOR),
208 'description' => __('Leave empty for auto width', WPDM_ELEMENTOR),
209 ]
210 );
211
212 $repeater->add_control(
213 'column_align',
214 [
215 'label' => __('Text Align', WPDM_ELEMENTOR),
216 'type' => Controls_Manager::CHOOSE,
217 'options' => [
218 'left' => ['title' => __('Left', WPDM_ELEMENTOR), 'icon' => 'eicon-text-align-left'],
219 'center' => ['title' => __('Center', WPDM_ELEMENTOR), 'icon' => 'eicon-text-align-center'],
220 'right' => ['title' => __('Right', WPDM_ELEMENTOR), 'icon' => 'eicon-text-align-right'],
221 ],
222 'default' => 'left',
223 'toggle' => false,
224 ]
225 );
226
227 $this->add_control(
228 'table_columns',
229 [
230 'label' => __('Columns', WPDM_ELEMENTOR),
231 'type' => Controls_Manager::REPEATER,
232 'fields' => $repeater->get_controls(),
233 'default' => [
234 [
235 'column_heading' => __('Title', WPDM_ELEMENTOR),
236 'column_fields' => ['link'],
237 'column_width' => '',
238 'column_align' => 'left',
239 ],
240 [
241 'column_heading' => __('Categories', WPDM_ELEMENTOR),
242 'column_fields' => ['categories'],
243 'column_width' => '',
244 'column_align' => 'left',
245 ],
246 [
247 'column_heading' => __('Download', WPDM_ELEMENTOR),
248 'column_fields' => ['download_link'],
249 'column_width' => '120px',
250 'column_align' => 'center',
251 ],
252 ],
253 'title_field' => '{{{ column_heading }}}',
254 ]
255 );
256
257 $this->add_control(
258 'legacy_mode_divider',
259 [
260 'type' => Controls_Manager::DIVIDER,
261 ]
262 );
263
264 $this->add_control(
265 'use_legacy_mode',
266 [
267 'label' => __('Use Legacy Mode', WPDM_ELEMENTOR),
268 'type' => Controls_Manager::SWITCHER,
269 'label_on' => __('Yes', WPDM_ELEMENTOR),
270 'label_off' => __('No', WPDM_ELEMENTOR),
271 'return_value' => 'yes',
272 'default' => '',
273 'description' => __('Enable to use the old text-based column configuration', WPDM_ELEMENTOR),
274 ]
275 );
276
277 $this->add_control(
278 'cols',
279 [
280 'label' => __('Data Field Names (Legacy)', WPDM_ELEMENTOR),
281 'type' => Controls_Manager::TEXT,
282 'default' => 'title|categories',
283 'description' => __('Column separator: | Multiple fields per column: ,', WPDM_ELEMENTOR),
284 'condition' => [
285 'use_legacy_mode' => 'yes',
286 ],
287 ]
288 );
289
290 $this->add_control(
291 'colheads',
292 [
293 'label' => __('Column Headings (Legacy)', WPDM_ELEMENTOR),
294 'type' => Controls_Manager::TEXT,
295 'default' => 'Title|Categories',
296 'description' => __('e.g: Title|Categories|Download::100px', WPDM_ELEMENTOR),
297 'condition' => [
298 'use_legacy_mode' => 'yes',
299 ],
300 ]
301 );
302
303 $this->end_controls_section();
304
305 // Content Section - Table Options
306 $this->start_controls_section(
307 'options_section',
308 [
309 'label' => __('Table Options', WPDM_ELEMENTOR),
310 'tab' => Controls_Manager::TAB_CONTENT,
311 ]
312 );
313
314 $this->add_control(
315 'jstable',
316 [
317 'label' => __('Enable DataTable.js', WPDM_ELEMENTOR),
318 'type' => Controls_Manager::SWITCHER,
319 'label_on' => __('Yes', WPDM_ELEMENTOR),
320 'label_off' => __('No', WPDM_ELEMENTOR),
321 'return_value' => '1',
322 'default' => '',
323 'description' => __('Adds sorting, searching, and pagination features', WPDM_ELEMENTOR),
324 ]
325 );
326
327 $this->add_control(
328 'login',
329 [
330 'label' => __('Require Login', WPDM_ELEMENTOR),
331 'type' => Controls_Manager::SWITCHER,
332 'label_on' => __('Yes', WPDM_ELEMENTOR),
333 'label_off' => __('No', WPDM_ELEMENTOR),
334 'return_value' => '1',
335 'default' => '',
336 'description' => __('Only show table to logged-in users', WPDM_ELEMENTOR),
337 ]
338 );
339
340 $this->end_controls_section();
341 }
342
343 /**
344 * Convert repeater columns to legacy format for WPDM shortcode.
345 *
346 * @param array $columns Repeater columns data.
347 * @return array ['cols' => string, 'colheads' => string]
348 */
349 private function convertColumnsToLegacyFormat(array $columns): array
350 {
351 $cols = [];
352 $colheads = [];
353
354 foreach ($columns as $column) {
355 // Get fields for this column
356 $fields = $column['column_fields'] ?? ['title'];
357 if (!is_array($fields)) {
358 $fields = [$fields];
359 }
360 $cols[] = implode(',', $fields);
361
362 // Build column heading with optional width
363 $heading = $column['column_heading'] ?? 'Column';
364 $width = $column['column_width'] ?? '';
365
366 if (!empty($width)) {
367 $heading .= '::' . $width;
368 }
369 $colheads[] = $heading;
370 }
371
372 return [
373 'cols' => implode('|', $cols),
374 'colheads' => implode('|', $colheads),
375 ];
376 }
377
378 protected function render()
379 {
380 $settings = $this->getCleanSettings(self::SETTINGS_KEYS);
381 $settings = $this->sanitizeSettings($settings, self::SANITIZERS);
382
383 // Convert categories array to comma-separated string
384 if (isset($settings['categories']) && is_array($settings['categories'])) {
385 $settings['categories'] = implode(',', array_map('sanitize_text_field', $settings['categories']));
386 }
387
388 // Remove empty categories - ensure it's a string before checking
389 $categories = $settings['categories'] ?? '';
390 if (!is_string($categories) || empty(trim($categories))) {
391 unset($settings['categories']);
392 }
393
394 // Check if using new repeater mode or legacy mode
395 $use_legacy = !empty($settings['use_legacy_mode']) && $settings['use_legacy_mode'] === 'yes';
396
397 if (!$use_legacy && !empty($settings['table_columns'])) {
398 // Convert repeater data to legacy format for WPDM
399 $converted = $this->convertColumnsToLegacyFormat($settings['table_columns']);
400 $settings['cols'] = $converted['cols'];
401 $settings['colheads'] = $converted['colheads'];
402 }
403
404 // Remove non-shortcode settings
405 unset($settings['table_columns']);
406 unset($settings['use_legacy_mode']);
407
408 // Convert switcher values
409 $settings['jstable'] = !empty($settings['jstable']) ? '1' : '0';
410 $settings['login'] = !empty($settings['login']) ? '1' : '0';
411
412 echo WPDM()->package->shortCodes->allPackages($settings);
413 }
414 }
415