Ninja Tables – WP Data Table Plugin for WordPress - Version 2.3.0

Version Description

( Date: August 02, 2018 ) * Fixed bug for rendering multiple table in a single page * Fix bug for column width and header text alignment * Fix bug for table not rendering issue

Download this release

Release Info

Developer techjewel
Plugin Icon 128x128 Ninja Tables – WP Data Table Plugin for WordPress
Version 2.3.0
Comparing to
See all releases

Code changes from version 2.2.6 to 2.3.0

admin/NinjaTablesAdmin.php CHANGED
@@ -2,6 +2,7 @@
2
  /*
3
  * Do Not USE namespace because The Pro Add-On Used this Class
4
  */
 
5
  use NinjaTable\TableDrivers\NinjaFooTable;
6
  use NinjaTables\Classes\NinjaTablesTablePressMigration;
7
  use NinjaTables\Classes\NinjaTablesUltimateTableMigration;
@@ -15,1664 +16,1619 @@ use NinjaTables\Classes\NinjaTablesUltimateTableMigration;
15
  * @package ninja-tables
16
  * @subpackage ninja-tables/admin
17
  */
18
- class NinjaTablesAdmin
19
- {
20
- /**
21
- * The ID of this plugin.
22
- *
23
- * @since 1.0.0
24
- * @access private
25
- * @var string $plugin_name The ID of this plugin.
26
- */
27
- private $plugin_name;
28
-
29
- /**
30
- * Custom Post Type Name
31
- *
32
- * @since 1.0.0
33
- * @access private
34
- * @var string $cpt_name .
35
- */
36
- private $cpt_name;
37
-
38
- /**
39
- * The version of this plugin.
40
- *
41
- * @since 1.0.0
42
- * @access private
43
- * @var string $version The current version of this plugin.
44
- */
45
- private $version;
46
-
47
- /**
48
- * Initialize the class and set its properties.
49
- *
50
- * @since 1.0.0
51
- *
52
- * @param string $plugin_name The name of this plugin.
53
- * @param string $version The version of this plugin.
54
- */
55
- public function __construct($plugin_name = 'ninja-tables', $version = NINJA_TABLES_VERSION)
56
- {
57
- $this->plugin_name = $plugin_name;
58
- $this->version = $version;
59
- $this->cpt_name = 'ninja-table';
60
- }
61
-
62
- /**
63
- * Register form post types
64
- *
65
- * @return void
66
- */
67
- public function register_post_type()
68
- {
69
- register_post_type($this->cpt_name, array(
70
- 'label' => __('Ninja Tables', 'ninja-tables'),
71
- 'public' => false,
72
- 'show_ui' => true,
73
- 'show_in_menu' => false,
74
- 'capability_type' => 'post',
75
- 'hierarchical' => false,
76
- 'query_var' => false,
77
- 'supports' => array('title'),
78
- 'labels' => array(
79
- 'name' => __('Ninja Tables', 'ninja-tables'),
80
- 'singular_name' => __('Table', 'ninja-tables'),
81
- 'menu_name' => __('Ninja Tables', 'ninja-tables'),
82
- 'add_new' => __('Add Table', 'ninja-tables'),
83
- 'add_new_item' => __('Add New Table', 'ninja-tables'),
84
- 'edit' => __('Edit', 'ninja-tables'),
85
- 'edit_item' => __('Edit Table', 'ninja-tables'),
86
- 'new_item' => __('New Table', 'ninja-tables'),
87
- 'view' => __('View Table', 'ninja-tables'),
88
- 'view_item' => __('View Table', 'ninja-tables'),
89
- 'search_items' => __('Search Table', 'ninja-tables'),
90
- 'not_found' => __('No Table Found', 'ninja-tables'),
91
- 'not_found_in_trash' => __('No Table Found in Trash', 'ninja-tables'),
92
- 'parent' => __('Parent Table', 'ninja-tables'),
93
- ),
94
- ));
95
- }
96
-
97
-
98
- /**
99
- * Adds a settings page link to a menu
100
- *
101
- * @link https://codex.wordpress.org/Administration_Menus
102
- * @since 1.0.0
103
- * @return void
104
- */
105
- public function add_menu()
106
- {
107
- global $submenu;
108
- $capability = ninja_table_admin_role();
109
-
110
- // Continue only if the current user has
111
- // the capability to manage ninja tables
112
- if (!$capability) {
113
- return;
114
- }
115
-
116
- // Top-level page
117
- $menuName = __('NinjaTables', 'ninja-tables');
118
- if (defined('NINJATABLESPRO')) {
119
- $menuName .= ' Pro';
120
- }
121
-
122
- add_menu_page(
123
- $menuName,
124
- $menuName,
125
- $capability,
126
- 'ninja_tables',
127
- array($this, 'main_page'),
128
- ninja_table_get_icon_url(),
129
- 25
130
- );
131
-
132
- $submenu['ninja_tables']['all_tables'] = array(
133
- __('All Tables', 'ninja-tables'),
134
- $capability,
135
- 'admin.php?page=ninja_tables#/',
136
- );
137
-
138
- $submenu['ninja_tables']['tools'] = array(
139
- __('Tools', 'ninja-tables'),
140
- $capability,
141
- 'admin.php?page=ninja_tables#/tools',
142
- '',
143
- 'ninja_table_tools_menu'
144
- );
145
-
146
- $submenu['ninja_tables']['import'] = array(
147
- __('Import a Table', 'ninja-tables'),
148
- $capability,
149
- 'admin.php?page=ninja_tables#/tools',
150
- '',
151
- 'ninja_table_import_menu'
152
- );
153
-
154
- if (!defined('NINJATABLESPRO')) {
155
- $submenu['ninja_tables']['upgrade_pro'] = array(
156
- __('<span style="color:#f39c12;">Get Pro</span>', 'ninja-tables'),
157
- $capability,
158
- 'https://wpmanageninja.com/downloads/ninja-tables-pro-add-on/?utm_source=ninja-tables&utm_medium=wp&utm_campaign=wp_plugin&utm_term=upgrade_menu',
159
- '',
160
- 'ninja_table_upgrade_menu'
161
- );
162
- } else if(defined('NINJATABLESPRO_SORTABLE')) {
163
- $license = get_option('_ninjatables_pro_license_status');
164
- if ($license != 'valid') {
165
- $submenu['ninja_tables']['activate_license'] = array(
166
- '<span style="color:#f39c12;">Activate License</span>',
167
- $capability,
168
- 'admin.php?page=ninja_tables#/tools?active_menu=license',
169
- '',
170
- 'ninja_table_license_menu'
171
- );
172
- }
173
- }
174
-
175
- $submenu['ninja_tables']['help'] = array(
176
- __('Help', 'ninja-tables'),
177
- $capability,
178
- 'admin.php?page=ninja_tables#/help'
179
- );
180
- }
181
-
182
- public function main_page()
183
- {
184
- $this->enqueue_data_tables_scripts();
185
-
186
- include(plugin_dir_path(__FILE__).'partials/wp_data_tables_display.php');
187
- }
188
-
189
- /**
190
- * Register the stylesheets for the admin area.
191
- *
192
- * @since 1.0.0
193
- */
194
- public function enqueue_styles()
195
- {
196
- $vendorSrc = plugin_dir_url(__DIR__)."assets/css/ninja-tables-vendor.css";
197
-
198
- if (is_rtl()) {
199
- $vendorSrc = plugin_dir_url(__DIR__)."assets/css/ninja-tables-vendor-rtl.css";
200
- }
201
 
202
- wp_enqueue_style(
203
- $this->plugin_name.'-vendor',
204
- $vendorSrc,
205
- [],
206
- $this->version,
207
- 'all'
208
- );
209
-
210
- wp_enqueue_style(
211
- $this->plugin_name,
212
- plugin_dir_url(__DIR__)."assets/css/ninja-tables-admin.css",
213
- array(),
214
- $this->version,
215
- 'all'
216
- );
217
- }
218
-
219
- /**
220
- * Register the JavaScript for the admin area.
221
- *
222
- * @since 1.0.0
223
- */
224
- public function enqueue_scripts()
225
- {
226
- if (function_exists('wp_enqueue_editor')) {
227
- wp_enqueue_editor();
228
- wp_enqueue_media();
229
- }
 
 
 
 
 
230
 
231
- wp_enqueue_script(
232
- $this->plugin_name,
233
- plugin_dir_url(__DIR__)."assets/js/ninja-tables-admin.js",
234
- array('jquery'),
235
- $this->version,
236
- false
237
- );
238
 
239
- $fluentUrl = admin_url('plugin-install.php?s=FluentForm&tab=search&type=term');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
240
 
241
- $isInstalled = defined('FLUENTFORM') || defined('NINJATABLESPRO');
242
- $dismissed = false;
243
- $dismissedTime = get_option('_ninja_tables_plugin_suggest_dismiss');
244
 
245
- if ($dismissedTime) {
246
- if ((time() - intval($dismissedTime)) < 518400) {
247
- $dismissed = true;
248
- }
249
- } else {
250
- $dismissed = true;
251
- update_option('_ninja_tables_plugin_suggest_dismiss', time() - 345600);
252
- }
253
-
254
- wp_localize_script($this->plugin_name, 'ninja_table_admin', array(
255
- 'img_url' => plugin_dir_url(__DIR__)."assets/img/",
256
- 'fluentform_url' => $fluentUrl,
257
- 'fluent_wp_url' => 'https://wordpress.org/plugins/fluentform/',
258
- 'dismissed' => $dismissed,
259
- 'isInstalled' => $isInstalled,
260
- 'hasPro' => defined('NINJATABLESPRO'),
261
- 'hasSortable' => defined('NINJATABLESPRO_SORTABLE'),
262
- 'ace_path_url' => plugin_dir_url(__DIR__)."assets/libs/ace",
263
- 'upgradeGuide' => 'https://wpmanageninja.com/r/docs/ninja-tables/how-to-install-and-upgrade/#upgrade',
264
- 'hasValidLicense' => get_option('_ninjatables_pro_license_status'),
265
- 'i18n' => \NinjaTables\Classes\I18nStrings::getStrings(),
266
- 'preview_required_scripts' => [
267
- plugin_dir_url(__DIR__)."assets/css/ninjatables-public.css",
268
- plugin_dir_url(__DIR__)."public/libs/footable/js/footable.min.js",
269
- ]
270
- ));
271
-
272
- // Elementor plugin have a bug where they throw error to parse #url, and I really don't know why they want to parse
273
- // other plugin's page's uri. They should fix it.
274
- // For now I am de-registering their script in ninja-table admin pages.
275
- wp_deregister_script('elementor-admin-app');
276
- }
277
-
278
- public function enqueue_data_tables_scripts()
279
- {
280
- $this->enqueue_scripts();
281
- $this->enqueue_styles();
282
- }
283
-
284
- public function ajax_routes()
285
- {
286
- if (!ninja_table_admin_role()) {
287
- return;
288
- }
289
 
290
- $valid_routes = array(
291
- 'get-all-tables' => 'getAllTables',
292
- 'store-a-table' => 'storeTable',
293
- 'delete-a-table' => 'deleteTable',
294
- 'import-table' => 'importTable',
295
- 'import-table-from-plugin' => 'importTableFromPlugin',
296
- 'get-tables-from-plugin' => 'getTablesFromPlugin',
297
- 'update-table-settings' => 'updateTableSettings',
298
- 'get-table-settings' => 'getTableSettings',
299
- 'get-table-data' => 'getTableData',
300
- 'store-table-data' => 'storeData',
301
- 'edit-data' => 'editData',
302
- 'delete-data' => 'deleteData',
303
- 'upload-data' => 'uploadData',
304
- 'duplicate-table' => 'duplicateTable',
305
- 'export-data' => 'exportData',
306
- 'dismiss_fluent_suggest' => 'dismissPluginSuggest',
307
- 'save_custom_css' => 'saveCustomCSS',
308
- 'get_access_roles' => 'getAccessRoles',
309
- 'get_table_preview_html' => 'getTablePreviewHtml'
310
- );
311
-
312
- $requested_route = $_REQUEST['target_action'];
313
- if (isset($valid_routes[$requested_route])) {
314
- $this->{$valid_routes[$requested_route]}();
315
- }
 
 
316
 
317
- wp_die();
318
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
319
 
320
- public function getAllTables()
321
- {
322
- $perPage = intval($_REQUEST['per_page']) ?: 10;
 
323
 
324
- $currentPage = intval($_GET['page']);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
325
 
326
- $skip = $perPage * ($currentPage - 1);
 
327
 
328
- $args = array(
329
- 'posts_per_page' => $perPage,
330
- 'offset' => $skip,
331
- 'orderby' => 'date',
332
- 'order' => 'DESC',
333
- 'post_type' => $this->cpt_name,
334
- 'post_status' => 'any',
335
 
336
- );
337
 
338
- if (isset($_REQUEST['search']) && $_REQUEST['search']) {
339
- $args['s'] = sanitize_text_field($_REQUEST['search']);
340
- }
 
 
 
 
341
 
342
- $tables = get_posts($args);
343
 
344
- foreach ($tables as $table) {
345
- $table->preview_url = site_url('?ninjatable_preview='.$table->ID);
346
- }
347
 
348
- $total = wp_count_posts('ninja-table');
349
- $total = intval($total->publish);
350
- $lastPage = ceil($total / $perPage);
351
-
352
- wp_send_json(array(
353
- 'total' => $total,
354
- 'per_page' => $perPage,
355
- 'current_page' => $currentPage,
356
- 'last_page' => ($lastPage) ? $lastPage : 1,
357
- 'data' => $tables,
358
- ), 200);
359
- }
360
-
361
- public function storeTable()
362
- {
363
- if (!$_REQUEST['post_title']) {
364
- wp_send_json_error(array(
365
- 'message' => __('The name field is required.', 'ninja-tables')
366
- ), 423);
367
- }
368
 
369
- $postId = intval($_REQUEST['tableId']);
370
-
371
- $attributes = array(
372
- 'post_title' => sanitize_text_field($_REQUEST['post_title']),
373
- 'post_content' => wp_kses_post($_REQUEST['post_content']),
374
- 'post_type' => $this->cpt_name,
375
- 'post_status' => 'publish'
376
- );
377
-
378
- if (!$postId) {
379
- $postId = wp_insert_post($attributes);
380
-
381
- wp_send_json(array(
382
- 'message' => __('Successfully added table.', 'ninja-tables'),
383
- 'table_id' => $postId
384
- ), 200);
385
- } else {
386
- $attributes['ID'] = $postId;
387
- wp_update_post($attributes);
388
-
389
- wp_send_json(array(
390
- 'message' => __('Successfully updated table.',
391
- 'ninja-tables'),
392
- 'table_id' => $postId
393
- ), 200);
394
- }
395
- }
396
-
397
- public function importTable()
398
- {
399
- $format = $_REQUEST['format'];
400
-
401
- if ($format == 'csv') {
402
- $this->uploadTableCsv();
403
- } elseif ($format == 'json') {
404
- $this->uploadTableJson();
405
- } elseif ($format == 'ninjaJson') {
406
- $this->uploadTableNinjaJson();
407
- }
408
 
409
- wp_send_json(array(
410
- 'message' => __('No appropriate driver found for the import format.',
411
- 'ninja-tables')
412
- ), 423);
413
- }
414
-
415
-
416
- public function saveCustomCSS()
417
- {
418
- $tableId = intval($_REQUEST['table_id']);
419
- $css = $_REQUEST['custom_css'];
420
- $css = wp_strip_all_tags($css);
421
- update_post_meta($tableId, '_ninja_tables_custom_css', $css);
422
-
423
- wp_send_json_success(array(
424
- 'message' => 'Custom CSS successfully saved'
425
- ), 200);
426
- }
427
-
428
- private function tablePressImport()
429
- {
430
- try {
431
- $tableId = intval($_REQUEST['tableId']);
432
-
433
- $table = get_post($tableId);
434
- update_post_meta($tableId, '_imported_to_ninja_table', 'yes');
435
- $ninjaTableId = $this->createTable(array(
436
- 'post_author' => intval($table->post_author),
437
- 'post_title' => sanitize_text_field('[Table Press] '.$table->post_title),
438
- 'post_content' => wp_kses_post($table->post_excerpt),
439
- 'post_status' => $table->post_status,
440
- 'post_type' => $this->cpt_name,
441
- ));
442
-
443
- $rows = json_decode($table->post_content, true);
444
-
445
- $tableSettings = get_post_meta($table->ID, '_tablepress_table_options', true);
446
-
447
- $tableSettings = json_decode($tableSettings, true);
448
-
449
- if ($tableSettings['table_head']) {
450
- $header = [];
451
- $headerRow = array_values(array_shift($rows));
452
- foreach ($headerRow as $index => $item) {
453
- $header['ninja_column_'.($index + 1)] = $item;
454
- }
455
- } else {
456
- $header = array();
457
- $columnCount = count(array_pop(array_reverse($rows)));
458
-
459
- for ($i = 0; $i < $columnCount; $i++) {
460
- $headerName = 'Ninja Column '.($i + 1);
461
- $headerKey = 'ninja_column_'.($i + 1);
462
- $header[$headerKey] = $headerName;
463
- }
464
- }
465
 
466
- $rows = array_reverse($rows);
 
 
 
 
 
 
 
467
 
468
- $this->storeTableConfigWhenImporting($ninjaTableId, $header);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
469
 
470
- $this->insertDataToTable($ninjaTableId, $rows, $header);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
471
 
472
- $message = __('Successfully imported '
473
- .$table->post_title.
474
- ' table from Table Press Plugin. Please go to all tables and review your table.'
475
- );
476
- } catch (Exception $exception) {
477
- $message = __('Sorry, we could not import the table.', 'ninja-tables');
478
- }
479
 
480
- wp_send_json(array(
481
- 'message' => $message
482
- ), 200);
483
- }
484
-
485
- private function getTablesFromPlugin()
486
- {
487
- $plugin = sanitize_text_field($_REQUEST['plugin']);
488
- $libraryClass = false;
489
-
490
- if ($plugin == 'UltimateTables') {
491
- $libraryClass = new NinjaTablesUltimateTableMigration();
492
- } else if ($plugin == 'TablePress') {
493
- $libraryClass = new NinjaTablesTablePressMigration();
494
- } else if ($plugin == 'supsystic') {
495
- $libraryClass = new \NinjaTables\Classes\NinjaTablesSupsysticTableMigration();
496
- } else {
497
- return false;
498
- }
499
- $tables = $libraryClass->getTables();
500
-
501
- wp_send_json(array(
502
- 'tables' => $tables
503
- ), 200);
504
- }
505
-
506
-
507
-
508
-
509
- private function importTableFromPlugin()
510
- {
511
- $plugin = esc_attr($_REQUEST['plugin']);
512
- $tableId = intval($_REQUEST['tableId']);
513
-
514
- if ($plugin == 'UltimateTables') {
515
- $libraryClass = new NinjaTablesUltimateTableMigration();
516
- } else if ($plugin == 'TablePress') {
517
- $libraryClass = new NinjaTablesTablePressMigration();
518
- } else if ($plugin == 'supsystic') {
519
- $libraryClass = new \NinjaTables\Classes\NinjaTablesSupsysticTableMigration();
520
- } else {
521
- return false;
522
- }
523
 
524
- $tableId = $libraryClass->migrateTable($tableId);
525
- if (is_wp_error($tableId)) {
526
- wp_send_json_error(array(
527
- 'message' => $tableId->get_error_message()
528
- ), 423);
529
- }
530
 
531
- $message = __(
532
- 'Successfully imported. Please go to all tables and review your newly imported table.',
533
- 'ninja-tables'
534
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
535
 
536
- wp_send_json_success(array(
537
- 'message' => $message,
538
- 'tableId' => $tableId
539
- ), 200);
540
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
541
 
542
- private function formatHeader($header)
543
- {
544
- $data = array();
545
 
546
- $column_counter = 1;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
547
 
548
- foreach ($header as $item) {
549
- $item = trim(strip_tags($item));
550
 
551
- // We'll slugify only if item is printable characters.
552
- // Otherwise we'll generate custom key for the item.
553
- // Printable chars as in ASCII printable chars.
554
- // Ref: http://www.catonmat.net/blog/my-favorite-regex/
555
- $key = !preg_match('/[^ -~]/', $item) ? $this->url_slug($item) : null;
556
 
557
- $key = sanitize_title($key, 'ninja_column_'.$column_counter);
 
558
 
559
- $counter = 1;
560
- while (isset($data[$key])) {
561
- $key .= '_'.$counter;
562
- $counter++;
563
- }
564
- $data[$key] = $item;
565
 
566
- $column_counter++;
567
- }
568
 
569
- return $data;
570
- }
 
 
 
 
571
 
572
- private function uploadTableCsv()
573
- {
574
- $tmpName = $_FILES['file']['tmp_name'];
575
 
576
- $reader = \League\Csv\Reader::createFromPath($tmpName)->fetchAll();
 
577
 
578
- $header = array_shift($reader);
579
- $reader = array_reverse($reader);
580
 
581
- foreach ($reader as &$item) {
582
- // We have to convert everything to utf-8
583
- foreach ($item as &$entry) {
584
- $entry = mb_convert_encoding($entry, 'UTF-8');
585
- }
586
- }
587
 
588
- $tableId = $this->createTable();
 
589
 
590
- $header = $this->formatHeader($header);
 
 
 
 
 
591
 
592
- $this->storeTableConfigWhenImporting($tableId, $header);
593
 
594
- $this->insertDataToTable($tableId, $reader, $header);
595
 
596
- wp_send_json(array(
597
- 'message' => __('Successfully added a table.', 'ninja-tables'),
598
- 'tableId' => $tableId
599
- ));
600
- }
601
 
602
- private function uploadTableJson()
603
- {
604
- $tableId = $this->createTable();
605
 
606
- $tmpName = $_FILES['file']['tmp_name'];
 
 
 
 
607
 
608
- $content = json_decode(file_get_contents($tmpName), true);
 
609
 
610
- $header = array_keys(array_pop(array_reverse($content)));
611
 
612
- $this->storeTableConfigWhenImporting($tableId, $header);
613
 
614
- $this->insertDataToTable($tableId, $content, $header);
615
 
616
- wp_send_json(array(
617
- 'message' => __('Successfully added a table.', 'ninja-tables'),
618
- 'tableId' => $tableId
619
- ));
620
- }
621
 
622
- private function uploadTableNinjaJson()
623
- {
624
- $tmpName = $_FILES['file']['tmp_name'];
625
 
626
- $content = json_decode(file_get_contents($tmpName), true);
 
 
 
 
627
 
628
- // validation
629
- if (!$content['post'] || !$content['columns'] || !$content['settings']) {
630
- wp_send_json(array(
631
- 'message' => __('You have a faulty JSON file. Please export a new one.',
632
- 'ninja-tables')
633
- ), 423);
634
- }
635
 
636
- $tableAttributes = array(
637
- 'post_title' => sanitize_title($content['post']['post_title']),
638
- 'post_content' => wp_kses_post($content['post']['post_content']),
639
- 'post_type' => $this->cpt_name,
640
- 'post_status' => 'publish'
641
- );
642
 
643
- $tableId = $this->createTable($tableAttributes);
 
 
 
 
 
 
644
 
645
- update_post_meta($tableId, '_ninja_table_columns', $content['columns']);
 
 
 
 
 
646
 
647
- update_post_meta($tableId, '_ninja_table_settings', $content['settings']);
648
 
649
- if ($rows = $content['rows']) {
650
- $header = [];
651
 
652
- foreach ($content['columns'] as $column) {
653
- $header[$column['key']] = $column['name'];
654
- }
655
 
656
- $this->insertDataToTable($tableId, $rows, $header);
657
- }
658
 
659
- wp_send_json(array(
660
- 'message' => __('Successfully added a table.', 'ninja-tables'),
661
- 'tableId' => $tableId
662
- ));
663
- }
664
-
665
- private function createTable($data = null)
666
- {
667
- return wp_insert_post($data
668
- ? $data
669
- : array(
670
- 'post_title' => __('Temporary table name', 'ninja-tables'),
671
- 'post_content' => __('Temporary table description',
672
- 'ninja-tables'),
673
- 'post_type' => $this->cpt_name,
674
- 'post_status' => 'publish'
675
- ));
676
- }
677
-
678
- private function storeTableConfigWhenImporting($tableId, $header)
679
- {
680
- // ninja_table_columns
681
- $ninjaTableColumns = array();
682
-
683
- foreach ($header as $key => $name) {
684
- $ninjaTableColumns[] = array(
685
- 'key' => $key,
686
- 'name' => $name,
687
- 'breakpoints' => ''
688
- );
689
- }
690
 
691
- update_post_meta($tableId, '_ninja_table_columns', $ninjaTableColumns);
692
-
693
- // ninja_table_settings
694
- $ninjaTableSettings = ninja_table_get_table_settings($tableId, 'admin');
695
-
696
- update_post_meta($tableId, '_ninja_table_settings', $ninjaTableSettings);
697
-
698
- ninjaTablesClearTableDataCache($tableId);
699
- }
700
-
701
- private function insertDataToTable($tableId, $values, $header)
702
- {
703
- $header = array_keys($header);
704
- $time = current_time('mysql');
705
- $headerCount = count($header);
706
-
707
- foreach ($values as $item) {
708
- if ($headerCount == count($item)) {
709
- $itemTemp = array_combine($header, $item);
710
- } else {
711
- // The item can have less/more entry than the header has.
712
- // We have to ensure that the header and values match.
713
- $itemTemp = array_combine(
714
- $header,
715
- // We'll get the appropriate values by merging Array1 & Array2
716
- array_merge(
717
- // Array1 = Only the entries that the header has.
718
- array_intersect_key($item, array_fill_keys(array_values($header), null)),
719
- // Array2 = The remaining header entries will be blank.
720
- array_fill_keys(array_diff(array_values($header), array_keys($item)), null)
721
- )
722
- );
723
- }
724
 
725
- $data = array(
726
- 'table_id' => $tableId,
727
- 'attribute' => 'value',
728
- 'value' => json_encode($itemTemp),
729
- 'created_at' => $time,
730
- 'updated_at' => $time
731
- );
732
 
733
- ninja_tables_DbTable()->insert($data);
734
- }
735
- }
736
-
737
- public function getTableSettings()
738
- {
739
- $tableID = intval($_REQUEST['table_id']);
740
- $table = get_post($tableID);
741
- $tableColumns = ninja_table_get_table_columns($tableID, 'admin');
742
-
743
- $tableSettings = ninja_table_get_table_settings($tableID, 'admin');
744
- $table->custom_css = get_post_meta($tableID, '_ninja_tables_custom_css', true);
745
-
746
- wp_send_json(array(
747
- 'columns' => $tableColumns,
748
- 'settings' => $tableSettings,
749
- 'table' => $table,
750
- 'preview_url' => site_url('?ninjatable_preview='.$tableID),
751
- ), 200);
752
- }
753
-
754
- public function updateTableSettings()
755
- {
756
- $tableId = intval($_REQUEST['table_id']);
757
-
758
- $tableColumns = array();
759
-
760
- if (isset($_REQUEST['columns'])) {
761
- $rawColumns = $_REQUEST['columns'];
762
- if ($rawColumns && is_array($rawColumns)) {
763
- foreach ($rawColumns as $column) {
764
- foreach ($column as $column_index => $column_value) {
765
- if ($column_index == 'header_html_content' || $column_index == 'selections') {
766
- $column[$column_index] = wp_kses_post($column_value);
767
- } else {
768
- $column[$column_index] = sanitize_text_field($column_value);
769
- }
770
- }
771
- $tableColumns[] = $column;
772
- }
773
- update_post_meta($tableId, '_ninja_table_columns', $tableColumns);
774
- }
775
- }
776
 
777
- $formattedTablePreference = array();
 
 
778
 
779
- if (isset($_REQUEST['table_settings'])) {
780
- $tablePreference = $_REQUEST['table_settings'];
781
- if ($tablePreference && is_array($tablePreference)) {
782
- foreach ($tablePreference as $key => $tab_pref) {
783
- if ($tab_pref == 'false') {
784
- $tab_pref = false;
785
- }
786
 
787
- if ($tab_pref == 'true') {
788
- $tab_pref = true;
789
- }
790
 
791
- if (is_array($tab_pref)) {
792
- $tab_pref = array_map('sanitize_text_field', $tab_pref);
793
- } else {
794
- $tab_pref = sanitize_text_field($tab_pref);
795
- }
796
 
797
- $formattedTablePreference[$key] = $tab_pref;
798
- }
799
 
800
- update_post_meta($tableId, '_ninja_table_settings', $formattedTablePreference);
801
- }
802
- }
803
 
804
- ninjaTablesClearTableDataCache($tableId);
805
-
806
- wp_send_json(array(
807
- 'message' => __('Successfully updated configuration.', 'ninja-tables'),
808
- 'columns' => $tableColumns,
809
- 'settings' => $formattedTablePreference
810
- ), 200);
811
- }
812
-
813
- public function getTable()
814
- {
815
- $tableId = intval($_REQUEST['id']);
816
- $table = get_post($tableId);
817
-
818
- wp_send_json(array(
819
- 'data' => $table
820
- ), 200);
821
- }
822
-
823
- public function deleteTable()
824
- {
825
- $tableId = intval($_REQUEST['table_id']);
826
-
827
- if (get_post_type($tableId) != $this->cpt_name) {
828
- wp_send_json(array(
829
- 'message' => __('Invalid Table to Delete', 'ninja-tables')
830
- ), 300);
831
- }
 
 
 
 
 
 
832
 
 
 
 
 
833
 
834
- wp_delete_post($tableId, true);
835
- // Delete the post metas
836
- delete_post_meta($tableId, '_ninja_table_columns');
837
- delete_post_meta($tableId, '_ninja_table_settings');
838
- delete_post_meta($tableId, '_ninja_table_cache_object');
839
- // now delete the data
840
- try {
841
- ninja_tables_DbTable()->where('table_id', $tableId)->delete();
842
- } catch (Exception $e) {
843
- //
844
- }
845
 
846
- wp_send_json(array(
847
- 'message' => __('Successfully deleted the table.', 'ninja-tables')
848
- ), 200);
849
- }
 
 
 
850
 
851
- public function getTableData()
852
- {
853
- $perPage = intval($_REQUEST['per_page']) ?: 10;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
854
 
855
- $currentPage = isset($_GET['page']) ? intval($_GET['page']) : 1;
 
 
856
 
857
- $skip = $perPage * ($currentPage - 1);
 
 
 
858
 
859
- $tableId = intval($_REQUEST['table_id']);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
860
 
861
- $search = esc_attr($_REQUEST['search']);
 
862
 
863
- list($orderByField, $orderByType) = $this->getTableSortingParams($tableId);
864
 
865
- $query = ninja_tables_DbTable()->where('table_id', $tableId);
866
 
867
- if ($search) {
868
- $query->search($search, array('value'));
869
- }
870
 
871
- $data = $query->take($perPage)
872
- ->skip($skip)
873
- ->orderBy($orderByField, $orderByType)
874
- ->get();
875
 
876
- $total = ninja_tables_DbTable()->where('table_id', $tableId)->count();
877
 
878
- $response = array();
879
 
880
- foreach ($data as $item) {
881
- $response[] = array(
882
- 'id' => $item->id,
883
- 'position' => property_exists($item, 'position') ? $item->position : null,
884
- 'values' => json_decode($item->value, true)
885
- );
886
- }
887
 
888
- wp_send_json(array(
889
- 'total' => $total,
890
- 'per_page' => $perPage,
891
- 'current_page' => $currentPage,
892
- 'last_page' => ceil($total / $perPage),
893
- 'data' => $response
894
- ), 200);
895
- }
896
-
897
- /**
898
- * Get the order by field and order by type values.
899
- *
900
- * @param $tableId
901
- * @param null $tableSettings
902
- * @return array
903
- */
904
- protected function getTableSortingParams($tableId, $tableSettings = null)
905
- {
906
- $tableSettings = $tableSettings ?: ninja_table_get_table_settings($tableId, 'admin');
907
-
908
- $orderByField = 'id';
909
- $orderByType = 'DESC';
910
-
911
- if (isset($tableSettings['sorting_type'])) {
912
- if ($tableSettings['sorting_type'] === 'manual_sort') {
913
- $orderByField = 'position';
914
- $orderByType = 'ASC';
915
- } elseif ($tableSettings['sorting_type'] === 'by_created_at') {
916
- $orderByField = 'id';
917
- if ($tableSettings['default_sorting'] === 'new_first') {
918
- $orderByType = 'DESC';
919
- } else {
920
- $orderByType = 'ASC';
921
- }
922
- }
923
- }
924
 
925
- return [$orderByField, $orderByType];
926
- }
927
 
928
- public function storeData()
929
- {
930
- $tableId = intval($_REQUEST['table_id']);
931
- $row = $_REQUEST['row'];
932
- $formattedRow = array();
933
 
934
- foreach ($row as $key => $item) {
935
- $formattedRow[$key] = wp_unslash($item);
936
- }
 
 
 
 
937
 
938
- $attributes = array(
939
- 'table_id' => $tableId,
940
- 'attribute' => 'value',
941
- 'value' => json_encode($formattedRow, true),
942
- 'updated_at' => date('Y-m-d H:i:s')
943
- );
 
 
944
 
945
- if ($id = intval($_REQUEST['id'])) {
946
- ninja_tables_DbTable()->where('id', $id)->update($attributes);
947
- } else {
948
- $attributes['created_at'] = date('Y-m-d H:i:s');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
949
 
950
- $attributes = apply_filters('ninja_tables_item_attributes', $attributes);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
951
 
952
- $id = $insertId = ninja_tables_DbTable()->insert($attributes);
953
- }
954
 
955
- $item = ninja_tables_DbTable()->find($id);
956
 
957
- ninjaTablesClearTableDataCache($tableId);
958
 
959
- wp_send_json(array(
960
- 'message' => __('Successfully saved the data.', 'ninja-tables'),
961
- 'item' => array(
962
- 'id' => $item->id,
963
- 'values' => $formattedRow,
964
- 'row' => json_decode($item->value),
965
- 'position' => property_exists($item, 'position') ? $item->position : null
966
- )
967
- ), 200);
968
- }
969
 
970
- public function deleteData()
971
- {
972
- $tableId = intval($_REQUEST['table_id']);
973
 
974
- $id = $_REQUEST['id'];
975
 
976
- $ids = is_array($id) ? $id : array($id);
 
 
 
977
 
978
- $ids = array_map(function ($item) {
979
- return intval($item);
980
- }, $ids);
981
 
982
- ninja_tables_DbTable()->where('table_id', $tableId)->whereIn('id', $ids)->delete();
983
 
984
- ninjaTablesClearTableDataCache($tableId);
 
985
 
986
- wp_send_json(array(
987
- 'message' => __('Successfully deleted data.', 'ninja-tables')
988
- ), 200);
989
- }
 
 
990
 
991
- public function uploadData()
992
- {
993
- $tableId = intval($_REQUEST['table_id']);
994
- $tmpName = $_FILES['file']['tmp_name'];
995
 
996
- $reader = \League\Csv\Reader::createFromPath($tmpName)->fetchAll();
 
 
 
 
 
 
 
997
 
998
- $csvHeader = array_shift($reader);
999
- $csvHeader = array_map('esc_attr', $csvHeader);
 
 
 
1000
 
1001
- $config = get_post_meta($tableId, '_ninja_table_columns', true);
1002
- if (!$config) {
1003
- wp_send_json(array(
1004
- 'message' => __('Please set table configuration.', 'ninja-tables')
1005
- ), 423);
1006
- }
1007
 
1008
- $header = array();
 
 
 
 
1009
 
1010
- foreach ($csvHeader as $item) {
1011
- foreach ($config as $column) {
1012
- $item = esc_attr($item);
1013
- if ($item == $column['key'] || $item == $column['name']) {
1014
- $header[] = $column['key'];
1015
- }
1016
- }
1017
- }
1018
 
1019
- if (count($header) != count($config)) {
1020
- wp_send_json(array(
1021
- 'message' => __('Please use the provided CSV header structure.', 'ninja-tables')
1022
- ), 423);
1023
- }
 
 
 
1024
 
1025
- $data = array();
1026
- $time = current_time('mysql');
1027
 
1028
- foreach ($reader as $item) {
1029
- // If item has any ascii entry we'll convert it to utf-8
1030
- foreach ($item as &$entry) {
1031
- $entry = mb_convert_encoding($entry, 'UTF-8');
1032
- }
1033
 
1034
- $itemTemp = array_combine($header, $item);
1035
 
1036
- array_push($data, array(
1037
- 'table_id' => $tableId,
1038
- 'attribute' => 'value',
1039
- 'value' => json_encode($itemTemp),
1040
- 'created_at' => $time,
1041
- 'updated_at' => $time
1042
- ));
1043
- }
1044
 
1045
- $replace = $_REQUEST['replace'] === 'true';
1046
 
1047
- if ($replace) {
1048
- ninja_tables_DbTable()->where('table_id', $tableId)->delete();
1049
- }
 
1050
 
1051
- $data = apply_filters('ninja_tables_import_table_data', $data, $tableId);
 
1052
 
1053
- ninja_tables_DbTable()->batch_insert($data);
1054
 
1055
- ninjaTablesClearTableDataCache($tableId);
1056
 
1057
- wp_send_json(array(
1058
- 'message' => __('Successfully uploaded data.', 'ninja-tables')
1059
- ));
1060
- }
1061
 
1062
- public function exportData()
1063
- {
1064
- $format = esc_attr($_REQUEST['format']);
1065
 
1066
- $tableId = intval($_REQUEST['table_id']);
1067
 
1068
- $tableTitle = get_the_title($tableId);
1069
-
1070
- $fileName = sanitize_title($tableTitle, date('Y-m-d-H-i-s'), 'preview');
1071
-
1072
- $tableColumns = ninja_table_get_table_columns($tableId, 'admin');
1073
 
1074
- $tableSettings = ninja_table_get_table_settings($tableId, 'admin');
1075
 
1076
- list($orderByField, $orderByType) = $this->getTableSortingParams($tableId, $tableSettings);
1077
 
1078
- $data = ninja_tables_DbTable()->where('table_id', $tableId)->orderBy($orderByField, $orderByType)->get();
1079
 
1080
- if ($format == 'csv') {
 
 
1081
 
1082
- $header = array();
1083
 
1084
- foreach ($tableColumns as $item) {
1085
- $header[$item['key']] = $item['name'];
1086
- }
1087
 
1088
- $exportData = array();
 
 
1089
 
1090
- foreach ($data as $item) {
1091
- $temp = array();
1092
- $item = json_decode($item->value, true);
1093
 
1094
- foreach ($header as $accessor => $name) {
1095
- $temp[] = $item[$accessor];
1096
- }
1097
 
1098
- array_push($exportData, $temp);
1099
- }
 
1100
 
1101
- $this->exportAsCSV(array_values($header), $exportData, $fileName.'.csv');
1102
- } elseif ($format == 'json') {
1103
- $table = get_post($tableId);
 
 
 
1104
 
1105
- $tableItems = array_map(function ($item) {
1106
- return json_decode($item->value, true);
1107
- }, $data);
1108
 
1109
- $exportData = array(
1110
- 'post' => $table,
1111
- 'columns' => $tableColumns,
1112
- 'settings' => $tableSettings,
1113
- 'rows' => $tableItems
1114
- );
1115
 
1116
- $this->exportAsJSON($exportData, $fileName.'.json');
1117
- }
1118
- }
 
 
 
 
 
1119
 
1120
- private function exportAsCSV($header, $data, $fileName = null)
1121
- {
1122
- $fileName = $fileName ?: 'export-data-'.date('d-m-Y');
1123
 
1124
- $writer = \League\Csv\Writer::createFromFileObject(new SplTempFileObject());
1125
- $writer->setDelimiter(",");
1126
- $writer->setNewline("\r\n");
1127
- $writer->insertOne($header);
1128
- $writer->insertAll($data);
1129
- $writer->output($fileName.'.csv');
1130
- die();
1131
- }
1132
 
1133
- private function exportAsJSON($data, $fileName = null)
1134
- {
1135
- $fileName = $fileName ?: 'export-data-'.date('d-m-Y').'.json';
1136
 
1137
- header('Content-disposition: attachment; filename='.$fileName);
1138
 
1139
- header('Content-type: application/json');
 
1140
 
1141
- echo json_encode($data);
 
 
 
 
 
 
 
1142
 
1143
- die();
1144
- }
 
 
 
1145
 
1146
- public function add_tabales_to_editor()
1147
- {
1148
- if (user_can_richedit()) {
1149
- $pages_with_editor_button = array('post.php', 'post-new.php');
1150
- foreach ($pages_with_editor_button as $editor_page) {
1151
- add_action("load-{$editor_page}", array($this, 'init_ninja_mce_buttons'));
1152
- }
1153
- }
1154
- }
1155
-
1156
- public function init_ninja_mce_buttons()
1157
- {
1158
- add_filter("mce_external_plugins", array($this, 'ninja_table_add_button'));
1159
- add_filter('mce_buttons', array($this, 'ninja_table_register_button'));
1160
- add_action('admin_footer', array($this, 'pushNinjaTablesToEditorFooter'));
1161
- }
1162
-
1163
- public function pushNinjaTablesToEditorFooter()
1164
- {
1165
- $tables = $this->getAllTablesForMce();
1166
- ?>
1167
  <script type="text/javascript">
1168
  window.ninja_tables_tiny_mce = {
1169
- label: '<?php _e('Select a Table to insert', 'ninja-tables') ?>',
1170
- title: '<?php _e('Insert Ninja Tables Shortcode', 'ninja-tables') ?>',
1171
- select_error: '<?php _e('Please select a table'); ?>',
1172
- insert_text: '<?php _e('Insert Shortcode', 'ninja-tables'); ?>',
1173
- tables: <?php echo json_encode($tables);?>
1174
  }
1175
  </script>
1176
- <?php
1177
- }
1178
-
1179
- private function getAllTablesForMce()
1180
- {
1181
- $args = array(
1182
- 'posts_per_page' => -1,
1183
- 'orderby' => 'date',
1184
- 'order' => 'DESC',
1185
- 'post_type' => $this->cpt_name,
1186
- 'post_status' => 'any'
1187
- );
1188
-
1189
- $tables = get_posts($args);
1190
- $formatted = array();
1191
- $formatted[] = array(
1192
- 'text' => __('Select a Table', 'ninja-tables'),
1193
- 'value' => ''
1194
- );
1195
-
1196
- foreach ($tables as $table) {
1197
- $formatted[] = array(
1198
- 'text' => $table->post_title,
1199
- 'value' => $table->ID
1200
- );
1201
- }
1202
 
1203
- return $formatted;
1204
- }
1205
-
1206
- /**
1207
- * add a button to Tiny MCE editor
1208
- *
1209
- * @param $plugin_array
1210
- *
1211
- * @return mixed
1212
- */
1213
- public function ninja_table_add_button($plugin_array)
1214
- {
1215
- $plugin_array['ninja_table'] = NINJA_TABLES_DIR_URL.'assets/js/ninja-table-tinymce-button.js';
1216
-
1217
- return $plugin_array;
1218
- }
1219
-
1220
- /**
1221
- * register a button to Tiny MCE editor
1222
- *
1223
- * @param $buttons
1224
- *
1225
- * @return mixed
1226
- */
1227
- public function ninja_table_register_button($buttons)
1228
- {
1229
- array_push($buttons, 'ninja_table');
1230
-
1231
- return $buttons;
1232
- }
1233
-
1234
- public function dismissPluginSuggest()
1235
- {
1236
- update_option('_ninja_tables_plugin_suggest_dismiss', time());
1237
- }
1238
-
1239
- private function url_slug($str, $options = array())
1240
- {
1241
- // Make sure string is in UTF-8 and strip invalid UTF-8 characters
1242
- $str = mb_convert_encoding((string)$str, 'UTF-8', mb_list_encodings());
1243
-
1244
- $defaults = array(
1245
- 'delimiter' => '_',
1246
- 'limit' => null,
1247
- 'lowercase' => true,
1248
- 'replacements' => array(),
1249
- 'transliterate' => true,
1250
- );
1251
-
1252
- // Merge options
1253
- $options = array_merge($defaults, $options);
1254
-
1255
- $char_map = array(
1256
- // Latin
1257
- 'À' => 'A',
1258
- 'Á' => 'A',
1259
- 'Â' => 'A',
1260
- 'Ã' => 'A',
1261
- 'Ä' => 'A',
1262
- 'Å' => 'A',
1263
- 'Æ' => 'AE',
1264
- 'Ç' => 'C',
1265
- 'È' => 'E',
1266
- 'É' => 'E',
1267
- 'Ê' => 'E',
1268
- 'Ë' => 'E',
1269
- 'Ì' => 'I',
1270
- 'Í' => 'I',
1271
- 'Î' => 'I',
1272
- 'Ï' => 'I',
1273
- 'Ð' => 'D',
1274
- 'Ñ' => 'N',
1275
- 'Ò' => 'O',
1276
- 'Ó' => 'O',
1277
- 'Ô' => 'O',
1278
- 'Õ' => 'O',
1279
- 'Ö' => 'O',
1280
- 'Ő' => 'O',
1281
- 'Ø' => 'O',
1282
- 'Ù' => 'U',
1283
- 'Ú' => 'U',
1284
- 'Û' => 'U',
1285
- 'Ü' => 'U',
1286
- 'Ű' => 'U',
1287
- 'Ý' => 'Y',
1288
- 'Þ' => 'TH',
1289
- 'ß' => 'ss',
1290
- 'à' => 'a',
1291
- 'á' => 'a',
1292
- 'â' => 'a',
1293
- 'ã' => 'a',
1294
- 'ä' => 'a',
1295
- 'å' => 'a',
1296
- 'æ' => 'ae',
1297
- 'ç' => 'c',
1298
- 'è' => 'e',
1299
- 'é' => 'e',
1300
- 'ê' => 'e',
1301
- 'ë' => 'e',
1302
- 'ì' => 'i',
1303
- 'í' => 'i',
1304
- 'î' => 'i',
1305
- 'ï' => 'i',
1306
- 'ð' => 'd',
1307
- 'ñ' => 'n',
1308
- 'ò' => 'o',
1309
- 'ó' => 'o',
1310
- 'ô' => 'o',
1311
- 'õ' => 'o',
1312
- 'ö' => 'o',
1313
- 'ő' => 'o',
1314
- 'ø' => 'o',
1315
- 'ù' => 'u',
1316
- 'ú' => 'u',
1317
- 'û' => 'u',
1318
- 'ü' => 'u',
1319
- 'ű' => 'u',
1320
- 'ý' => 'y',
1321
- 'þ' => 'th',
1322
- 'ÿ' => 'y',
1323
- // Latin symbols
1324
- '©' => '(c)',
1325
- // Greek
1326
- 'Α' => 'A',
1327
- 'Β' => 'B',
1328
- 'Γ' => 'G',
1329
- 'Δ' => 'D',
1330
- 'Ε' => 'E',
1331
- 'Ζ' => 'Z',
1332
- 'Η' => 'H',
1333
- 'Θ' => '8',
1334
- 'Ι' => 'I',
1335
- 'Κ' => 'K',
1336
- 'Λ' => 'L',
1337
- 'Μ' => 'M',
1338
- 'Ν' => 'N',
1339
- 'Ξ' => '3',
1340
- 'Ο' => 'O',
1341
- 'Π' => 'P',
1342
- 'Ρ' => 'R',
1343
- 'Σ' => 'S',
1344
- 'Τ' => 'T',
1345
- 'Υ' => 'Y',
1346
- 'Φ' => 'F',
1347
- 'Χ' => 'X',
1348
- 'Ψ' => 'PS',
1349
- 'Ω' => 'W',
1350
- 'Ά' => 'A',
1351
- 'Έ' => 'E',
1352
- 'Ί' => 'I',
1353
- 'Ό' => 'O',
1354
- 'Ύ' => 'Y',
1355
- 'Ή' => 'H',
1356
- 'Ώ' => 'W',
1357
- 'Ϊ' => 'I',
1358
- 'Ϋ' => 'Y',
1359
- 'α' => 'a',
1360
- 'β' => 'b',
1361
- 'γ' => 'g',
1362
- 'δ' => 'd',
1363
- 'ε' => 'e',
1364
- 'ζ' => 'z',
1365
- 'η' => 'h',
1366
- 'θ' => '8',
1367
- 'ι' => 'i',
1368
- 'κ' => 'k',
1369
- 'λ' => 'l',
1370
- 'μ' => 'm',
1371
- 'ν' => 'n',
1372
- 'ξ' => '3',
1373
- 'ο' => 'o',
1374
- 'π' => 'p',
1375
- 'ρ' => 'r',
1376
- 'σ' => 's',
1377
- 'τ' => 't',
1378
- 'υ' => 'y',
1379
- 'φ' => 'f',
1380
- 'χ' => 'x',
1381
- 'ψ' => 'ps',
1382
- 'ω' => 'w',
1383
- 'ά' => 'a',
1384
- 'έ' => 'e',
1385
- 'ί' => 'i',
1386
- 'ό' => 'o',
1387
- 'ύ' => 'y',
1388
- 'ή' => 'h',
1389
- 'ώ' => 'w',
1390
- 'ς' => 's',
1391
- 'ϊ' => 'i',
1392
- 'ΰ' => 'y',
1393
- 'ϋ' => 'y',
1394
- 'ΐ' => 'i',
1395
- // Turkish
1396
- 'Ş' => 'S',
1397
- 'İ' => 'I',
1398
- 'Ç' => 'C',
1399
- 'Ü' => 'U',
1400
- 'Ö' => 'O',
1401
- 'Ğ' => 'G',
1402
- 'ş' => 's',
1403
- 'ı' => 'i',
1404
- 'ç' => 'c',
1405
- 'ü' => 'u',
1406
- 'ö' => 'o',
1407
- 'ğ' => 'g',
1408
- // Russian
1409
- 'А' => 'A',
1410
- 'Б' => 'B',
1411
- 'В' => 'V',
1412
- 'Г' => 'G',
1413
- 'Д' => 'D',
1414
- 'Е' => 'E',
1415
- 'Ё' => 'Yo',
1416
- 'Ж' => 'Zh',
1417
- 'З' => 'Z',
1418
- 'И' => 'I',
1419
- 'Й' => 'J',
1420
- 'К' => 'K',
1421
- 'Л' => 'L',
1422
- 'М' => 'M',
1423
- 'Н' => 'N',
1424
- 'О' => 'O',
1425
- 'П' => 'P',
1426
- 'Р' => 'R',
1427
- 'С' => 'S',
1428
- 'Т' => 'T',
1429
- 'У' => 'U',
1430
- 'Ф' => 'F',
1431
- 'Х' => 'H',
1432
- 'Ц' => 'C',
1433
- 'Ч' => 'Ch',
1434
- 'Ш' => 'Sh',
1435
- 'Щ' => 'Sh',
1436
- 'Ъ' => '',
1437
- 'Ы' => 'Y',
1438
- 'Ь' => '',
1439
- 'Э' => 'E',
1440
- 'Ю' => 'Yu',
1441
- 'Я' => 'Ya',
1442
- 'а' => 'a',
1443
- 'б' => 'b',
1444
- 'в' => 'v',
1445
- 'г' => 'g',
1446
- 'д' => 'd',
1447
- 'е' => 'e',
1448
- 'ё' => 'yo',
1449
- 'ж' => 'zh',
1450
- 'з' => 'z',
1451
- 'и' => 'i',
1452
- 'й' => 'j',
1453
- 'к' => 'k',
1454
- 'л' => 'l',
1455
- 'м' => 'm',
1456
- 'н' => 'n',
1457
- 'о' => 'o',
1458
- 'п' => 'p',
1459
- 'р' => 'r',
1460
- 'с' => 's',
1461
- 'т' => 't',
1462
- 'у' => 'u',
1463
- 'ф' => 'f',
1464
- 'х' => 'h',
1465
- 'ц' => 'c',
1466
- 'ч' => 'ch',
1467
- 'ш' => 'sh',
1468
- 'щ' => 'sh',
1469
- 'ъ' => '',
1470
- 'ы' => 'y',
1471
- 'ь' => '',
1472
- 'э' => 'e',
1473
- 'ю' => 'yu',
1474
- 'я' => 'ya',
1475
- // Ukrainian
1476
- 'Є' => 'Ye',
1477
- 'І' => 'I',
1478
- 'Ї' => 'Yi',
1479
- 'Ґ' => 'G',
1480
- 'є' => 'ye',
1481
- 'і' => 'i',
1482
- 'ї' => 'yi',
1483
- 'ґ' => 'g',
1484
- // Czech
1485
- 'Č' => 'C',
1486
- 'Ď' => 'D',
1487
- 'Ě' => 'E',
1488
- 'Ň' => 'N',
1489
- 'Ř' => 'R',
1490
- 'Š' => 'S',
1491
- 'Ť' => 'T',
1492
- 'Ů' => 'U',
1493
- 'Ž' => 'Z',
1494
- 'č' => 'c',
1495
- 'ď' => 'd',
1496
- 'ě' => 'e',
1497
- 'ň' => 'n',
1498
- 'ř' => 'r',
1499
- 'š' => 's',
1500
- 'ť' => 't',
1501
- 'ů' => 'u',
1502
- 'ž' => 'z',
1503
- // Polish
1504
- 'Ą' => 'A',
1505
- 'Ć' => 'C',
1506
- 'Ę' => 'e',
1507
- 'Ł' => 'L',
1508
- 'Ń' => 'N',
1509
- 'Ó' => 'o',
1510
- 'Ś' => 'S',
1511
- 'Ź' => 'Z',
1512
- 'Ż' => 'Z',
1513
- 'ą' => 'a',
1514
- 'ć' => 'c',
1515
- 'ę' => 'e',
1516
- 'ł' => 'l',
1517
- 'ń' => 'n',
1518
- 'ó' => 'o',
1519
- 'ś' => 's',
1520
- 'ź' => 'z',
1521
- 'ż' => 'z',
1522
- // Latvian
1523
- 'Ā' => 'A',
1524
- 'Č' => 'C',
1525
- 'Ē' => 'E',
1526
- 'Ģ' => 'G',
1527
- 'Ī' => 'i',
1528
- 'Ķ' => 'k',
1529
- 'Ļ' => 'L',
1530
- 'Ņ' => 'N',
1531
- 'Š' => 'S',
1532
- 'Ū' => 'u',
1533
- 'Ž' => 'Z',
1534
- 'ā' => 'a',
1535
- 'č' => 'c',
1536
- 'ē' => 'e',
1537
- 'ģ' => 'g',
1538
- 'ī' => 'i',
1539
- 'ķ' => 'k',
1540
- 'ļ' => 'l',
1541
- 'ņ' => 'n',
1542
- 'š' => 's',
1543
- 'ū' => 'u',
1544
- 'ž' => 'z',
1545
- );
1546
-
1547
- // Make custom replacements
1548
- $str = preg_replace(array_keys($options['replacements']), $options['replacements'], $str);
1549
-
1550
- // Transliterate characters to ASCII
1551
- if ($options['transliterate']) {
1552
- $str = str_replace(array_keys($char_map), $char_map, $str);
1553
- }
1554
 
1555
- // Replace non-alphanumeric characters with our delimiter
1556
- $str = preg_replace('/[^\p{L}\p{Nd}]+/u', $options['delimiter'], $str);
1557
-
1558
- // Remove duplicate delimiters
1559
- $str = preg_replace('/('.preg_quote($options['delimiter'], '/').'){2,}/', '$1', $str);
1560
-
1561
- // Truncate slug to max. characters
1562
- $str = mb_substr($str, 0, ($options['limit'] ? $options['limit'] : mb_strlen($str, 'UTF-8')), 'UTF-8');
1563
-
1564
- // Remove delimiter from ends
1565
- $str = trim($str, $options['delimiter']);
1566
-
1567
- return $options['lowercase'] ? mb_strtolower($str, 'UTF-8') : $str;
1568
- }
1569
-
1570
- /**
1571
- * Save a flag if the a post/page/cpt have [ninja_tables] shortcode
1572
- *
1573
- * @param int $post_id
1574
- *
1575
- * @return void
1576
- */
1577
- public function saveNinjaTableFlagOnShortCode($post_id)
1578
- {
1579
- if (isset($_POST['post_content'])) {
1580
- $post_content = $_POST['post_content'];
1581
- } else {
1582
- $post = get_post($post_id);
1583
- $post_content = $post->post_content;
1584
- }
1585
- if (has_shortcode($post_content, 'ninja_tables')) {
1586
- update_post_meta($post_id, '_has_ninja_tables', 1);
1587
- } else if (get_post_meta($post_id, '_has_ninja_tables', true)) {
1588
- update_post_meta($post_id, '_has_ninja_tables', 0);
1589
- }
1590
- }
1591
 
1592
- public function duplicateTable()
1593
- {
1594
- $oldPostId = intval($_REQUEST['tableId']);
1595
 
1596
- $post = get_post($oldPostId);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1597
 
1598
- // Duplicate table itself.
1599
- $attributes = array(
1600
- 'post_title' => $post->post_title . '( Duplicate )',
1601
- 'post_content' => $post->post_content,
1602
- 'post_type' => $post->post_type,
1603
- 'post_status' => 'publish'
1604
- );
 
 
 
 
 
 
 
 
 
 
 
 
 
1605
 
1606
- $newPostId = wp_insert_post($attributes);
 
1607
 
1608
- global $wpdb;
1609
 
1610
- // Duplicate table settings.
1611
- $postMetaTable = $wpdb->prefix.'postmeta';
 
 
 
 
 
1612
 
1613
- $sql = "INSERT INTO $postMetaTable (`post_id`, `meta_key`, `meta_value`)";
1614
- $sql .= " SELECT $newPostId, `meta_key`, `meta_value` FROM $postMetaTable WHERE `post_id` = $oldPostId";
1615
 
1616
- $wpdb->query($sql);
1617
 
1618
- // Duplicate table rows.
1619
- $itemsTable = $wpdb->prefix.ninja_tables_db_table_name();
1620
-
1621
- $sql = "INSERT INTO $itemsTable (`position`, `table_id`, `attribute`, `value`, `created_at`, `updated_at`)";
1622
- $sql .= " SELECT `position`, $newPostId, `attribute`, `value`, `created_at`, `updated_at` FROM $itemsTable";
1623
- $sql .= " WHERE `table_id` = $oldPostId";
1624
-
1625
- $wpdb->query($sql);
1626
-
1627
- wp_send_json_success(array(
1628
- 'message' => __('Successfully duplicated table.', 'ninja-tables'),
1629
- 'table_id' => $newPostId
1630
- ), 200);
1631
- }
1632
-
1633
-
1634
- public function getAccessRoles() {
1635
- $roles = get_editable_roles();
1636
- $formatted = array();
1637
- $excludedRoles = array('subscriber', 'administrator');
1638
- foreach ($roles as $key => $role) {
1639
- if(!in_array($key, $excludedRoles)) {
1640
- $formatted[] = array(
1641
- 'name' => $role['name'],
1642
- 'key' => $key
1643
- );
1644
- }
1645
- }
1646
-
1647
- $capability = get_option('_ninja_tables_permission');
1648
 
1649
- if (is_string($capability)) {
1650
- $capability = [];
1651
- }
1652
-
1653
- wp_send_json(array(
1654
- 'capability' => $capability,
1655
- 'roles' => $formatted
1656
- ), 200);
1657
- }
1658
-
1659
- public function getTablePreviewHtml() {
1660
- // sleep(3);
1661
- $tableId = intval($_REQUEST['table_id']);
1662
- $tableColumns = ninja_table_get_table_columns($tableId, 'public');
1663
- $tableSettings = ninja_table_get_table_settings($tableId, 'public');
1664
-
1665
- $formattedColumns = [];
1666
- foreach ($tableColumns as $index => $column) {
1667
- $formattedColumns[] = NinjaFooTable::getFormattedColumn( $column, $index, $tableSettings, true,
1668
- 'by_created_at' );
1669
- }
1670
- $formatted_data = ninjaTablesGetTablesDataByID( $tableId, $tableSettings['default_sorting'], true, 25 );
1671
- echo self::loadView( 'public/views/table_inner_html', array(
1672
- 'table_columns' => $formattedColumns,
1673
- 'table_rows' => $formatted_data
1674
- ) );
1675
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1676
 
1677
  private static function loadView( $file, $data ) {
1678
  $file = NINJA_TABLES_DIR_PATH . $file . '.php';
@@ -1682,4 +1638,29 @@ class NinjaTablesAdmin
1682
 
1683
  return ob_get_clean();
1684
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1685
  }
2
  /*
3
  * Do Not USE namespace because The Pro Add-On Used this Class
4
  */
5
+
6
  use NinjaTable\TableDrivers\NinjaFooTable;
7
  use NinjaTables\Classes\NinjaTablesTablePressMigration;
8
  use NinjaTables\Classes\NinjaTablesUltimateTableMigration;
16
  * @package ninja-tables
17
  * @subpackage ninja-tables/admin
18
  */
19
+ class NinjaTablesAdmin {
20
+ /**
21
+ * The ID of this plugin.
22
+ *
23
+ * @since 1.0.0
24
+ * @access private
25
+ * @var string $plugin_name The ID of this plugin.
26
+ */
27
+ private $plugin_name;
28
+
29
+ /**
30
+ * Custom Post Type Name
31
+ *
32
+ * @since 1.0.0
33
+ * @access private
34
+ * @var string $cpt_name .
35
+ */
36
+ private $cpt_name;
37
+
38
+ /**
39
+ * The version of this plugin.
40
+ *
41
+ * @since 1.0.0
42
+ * @access private
43
+ * @var string $version The current version of this plugin.
44
+ */
45
+ private $version;
46
+
47
+ /**
48
+ * Initialize the class and set its properties.
49
+ *
50
+ * @since 1.0.0
51
+ *
52
+ * @param string $plugin_name The name of this plugin.
53
+ * @param string $version The version of this plugin.
54
+ */
55
+ public function __construct( $plugin_name = 'ninja-tables', $version = NINJA_TABLES_VERSION ) {
56
+ $this->plugin_name = $plugin_name;
57
+ $this->version = $version;
58
+ $this->cpt_name = 'ninja-table';
59
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
60
 
61
+ /**
62
+ * Register form post types
63
+ *
64
+ * @return void
65
+ */
66
+ public function register_post_type() {
67
+ register_post_type( $this->cpt_name, array(
68
+ 'label' => __( 'Ninja Tables', 'ninja-tables' ),
69
+ 'public' => false,
70
+ 'show_ui' => true,
71
+ 'show_in_menu' => false,
72
+ 'capability_type' => 'post',
73
+ 'hierarchical' => false,
74
+ 'query_var' => false,
75
+ 'supports' => array( 'title' ),
76
+ 'labels' => array(
77
+ 'name' => __( 'Ninja Tables', 'ninja-tables' ),
78
+ 'singular_name' => __( 'Table', 'ninja-tables' ),
79
+ 'menu_name' => __( 'Ninja Tables', 'ninja-tables' ),
80
+ 'add_new' => __( 'Add Table', 'ninja-tables' ),
81
+ 'add_new_item' => __( 'Add New Table', 'ninja-tables' ),
82
+ 'edit' => __( 'Edit', 'ninja-tables' ),
83
+ 'edit_item' => __( 'Edit Table', 'ninja-tables' ),
84
+ 'new_item' => __( 'New Table', 'ninja-tables' ),
85
+ 'view' => __( 'View Table', 'ninja-tables' ),
86
+ 'view_item' => __( 'View Table', 'ninja-tables' ),
87
+ 'search_items' => __( 'Search Table', 'ninja-tables' ),
88
+ 'not_found' => __( 'No Table Found', 'ninja-tables' ),
89
+ 'not_found_in_trash' => __( 'No Table Found in Trash', 'ninja-tables' ),
90
+ 'parent' => __( 'Parent Table', 'ninja-tables' ),
91
+ ),
92
+ ) );
93
+ }
94
 
 
 
 
 
 
 
 
95
 
96
+ /**
97
+ * Adds a settings page link to a menu
98
+ *
99
+ * @link https://codex.wordpress.org/Administration_Menus
100
+ * @since 1.0.0
101
+ * @return void
102
+ */
103
+ public function add_menu() {
104
+ global $submenu;
105
+ $capability = ninja_table_admin_role();
106
+
107
+ // Continue only if the current user has
108
+ // the capability to manage ninja tables
109
+ if ( ! $capability ) {
110
+ return;
111
+ }
112
+
113
+ // Top-level page
114
+ $menuName = __( 'NinjaTables', 'ninja-tables' );
115
+ if ( defined( 'NINJATABLESPRO' ) ) {
116
+ $menuName .= ' Pro';
117
+ }
118
+
119
+ add_menu_page(
120
+ $menuName,
121
+ $menuName,
122
+ $capability,
123
+ 'ninja_tables',
124
+ array( $this, 'main_page' ),
125
+ ninja_table_get_icon_url(),
126
+ 25
127
+ );
128
+
129
+ $submenu['ninja_tables']['all_tables'] = array(
130
+ __( 'All Tables', 'ninja-tables' ),
131
+ $capability,
132
+ 'admin.php?page=ninja_tables#/',
133
+ );
134
+
135
+ $submenu['ninja_tables']['tools'] = array(
136
+ __( 'Tools', 'ninja-tables' ),
137
+ $capability,
138
+ 'admin.php?page=ninja_tables#/tools',
139
+ '',
140
+ 'ninja_table_tools_menu'
141
+ );
142
+
143
+ $submenu['ninja_tables']['import'] = array(
144
+ __( 'Import a Table', 'ninja-tables' ),
145
+ $capability,
146
+ 'admin.php?page=ninja_tables#/tools',
147
+ '',
148
+ 'ninja_table_import_menu'
149
+ );
150
+
151
+ if ( ! defined( 'NINJATABLESPRO' ) ) {
152
+ $submenu['ninja_tables']['upgrade_pro'] = array(
153
+ __( '<span style="color:#f39c12;">Get Pro</span>', 'ninja-tables' ),
154
+ $capability,
155
+ 'https://wpmanageninja.com/downloads/ninja-tables-pro-add-on/?utm_source=ninja-tables&utm_medium=wp&utm_campaign=wp_plugin&utm_term=upgrade_menu',
156
+ '',
157
+ 'ninja_table_upgrade_menu'
158
+ );
159
+ } elseif ( defined( 'NINJATABLESPRO_SORTABLE' ) ) {
160
+ $license = get_option( '_ninjatables_pro_license_status' );
161
+ if ( $license != 'valid' ) {
162
+ $submenu['ninja_tables']['activate_license'] = array(
163
+ '<span style="color:#f39c12;">Activate License</span>',
164
+ $capability,
165
+ 'admin.php?page=ninja_tables#/tools?active_menu=license',
166
+ '',
167
+ 'ninja_table_license_menu'
168
+ );
169
+ }
170
+ }
171
+
172
+ $submenu['ninja_tables']['help'] = array(
173
+ __( 'Help', 'ninja-tables' ),
174
+ $capability,
175
+ 'admin.php?page=ninja_tables#/help'
176
+ );
177
+ }
178
 
179
+ public function main_page() {
180
+ $this->enqueue_data_tables_scripts();
 
181
 
182
+ include( plugin_dir_path( __FILE__ ) . 'partials/wp_data_tables_display.php' );
183
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
184
 
185
+ /**
186
+ * Register the stylesheets for the admin area.
187
+ *
188
+ * @since 1.0.0
189
+ */
190
+ public function enqueue_styles() {
191
+ $vendorSrc = plugin_dir_url( __DIR__ ) . "assets/css/ninja-tables-vendor.css";
192
+
193
+ if ( is_rtl() ) {
194
+ $vendorSrc = plugin_dir_url( __DIR__ ) . "assets/css/ninja-tables-vendor-rtl.css";
195
+ }
196
+
197
+ wp_enqueue_style(
198
+ $this->plugin_name . '-vendor',
199
+ $vendorSrc,
200
+ [],
201
+ $this->version,
202
+ 'all'
203
+ );
204
+
205
+ wp_enqueue_style(
206
+ $this->plugin_name,
207
+ plugin_dir_url( __DIR__ ) . "assets/css/ninja-tables-admin.css",
208
+ array(),
209
+ $this->version,
210
+ 'all'
211
+ );
212
+ }
213
 
214
+ /**
215
+ * Register the JavaScript for the admin area.
216
+ *
217
+ * @since 1.0.0
218
+ */
219
+ public function enqueue_scripts() {
220
+ if ( function_exists( 'wp_enqueue_editor' ) ) {
221
+ wp_enqueue_editor();
222
+ wp_enqueue_media();
223
+ }
224
+
225
+ wp_enqueue_script(
226
+ $this->plugin_name,
227
+ plugin_dir_url( __DIR__ ) . "assets/js/ninja-tables-admin.js",
228
+ array( 'jquery' ),
229
+ $this->version,
230
+ false
231
+ );
232
+
233
+ $fluentUrl = admin_url( 'plugin-install.php?s=FluentForm&tab=search&type=term' );
234
+
235
+ $isInstalled = defined( 'FLUENTFORM' ) || defined( 'NINJATABLESPRO' );
236
+ $dismissed = false;
237
+ $dismissedTime = get_option( '_ninja_tables_plugin_suggest_dismiss' );
238
+
239
+ if ( $dismissedTime ) {
240
+ if ( ( time() - intval( $dismissedTime ) ) < 518400 ) {
241
+ $dismissed = true;
242
+ }
243
+ } else {
244
+ $dismissed = true;
245
+ update_option( '_ninja_tables_plugin_suggest_dismiss', time() - 345600 );
246
+ }
247
+
248
+ wp_localize_script( $this->plugin_name, 'ninja_table_admin', array(
249
+ 'img_url' => plugin_dir_url( __DIR__ ) . "assets/img/",
250
+ 'fluentform_url' => $fluentUrl,
251
+ 'fluent_wp_url' => 'https://wordpress.org/plugins/fluentform/',
252
+ 'dismissed' => $dismissed,
253
+ 'isInstalled' => $isInstalled,
254
+ 'hasPro' => defined( 'NINJATABLESPRO' ),
255
+ 'hasSortable' => defined( 'NINJATABLESPRO_SORTABLE' ),
256
+ 'ace_path_url' => plugin_dir_url( __DIR__ ) . "assets/libs/ace",
257
+ 'upgradeGuide' => 'https://wpmanageninja.com/r/docs/ninja-tables/how-to-install-and-upgrade/#upgrade',
258
+ 'hasValidLicense' => get_option( '_ninjatables_pro_license_status' ),
259
+ 'i18n' => \NinjaTables\Classes\I18nStrings::getStrings(),
260
+ 'preview_required_scripts' => [
261
+ plugin_dir_url( __DIR__ ) . "assets/css/ninjatables-public.css",
262
+ plugin_dir_url( __DIR__ ) . "public/libs/footable/js/footable.min.js",
263
+ ]
264
+ ) );
265
+
266
+ // Elementor plugin have a bug where they throw error to parse #url, and I really don't know why they want to parse
267
+ // other plugin's page's uri. They should fix it.
268
+ // For now I am de-registering their script in ninja-table admin pages.
269
+ wp_deregister_script( 'elementor-admin-app' );
270
+ }
271
 
272
+ public function enqueue_data_tables_scripts() {
273
+ $this->enqueue_scripts();
274
+ $this->enqueue_styles();
275
+ }
276
 
277
+ public function ajax_routes() {
278
+ if ( ! ninja_table_admin_role() ) {
279
+ return;
280
+ }
281
+
282
+ $valid_routes = array(
283
+ 'get-all-tables' => 'getAllTables',
284
+ 'store-a-table' => 'storeTable',
285
+ 'delete-a-table' => 'deleteTable',
286
+ 'import-table' => 'importTable',
287
+ 'import-table-from-plugin' => 'importTableFromPlugin',
288
+ 'get-tables-from-plugin' => 'getTablesFromPlugin',
289
+ 'update-table-settings' => 'updateTableSettings',
290
+ 'get-table-settings' => 'getTableSettings',
291
+ 'get-table-data' => 'getTableData',
292
+ 'store-table-data' => 'storeData',
293
+ 'edit-data' => 'editData',
294
+ 'delete-data' => 'deleteData',
295
+ 'upload-data' => 'uploadData',
296
+ 'duplicate-table' => 'duplicateTable',
297
+ 'export-data' => 'exportData',
298
+ 'dismiss_fluent_suggest' => 'dismissPluginSuggest',
299
+ 'save_custom_css' => 'saveCustomCSS',
300
+ 'get_access_roles' => 'getAccessRoles',
301
+ 'get_table_preview_html' => 'getTablePreviewHtml'
302
+ );
303
+
304
+ $requested_route = $_REQUEST['target_action'];
305
+ if ( isset( $valid_routes[ $requested_route ] ) ) {
306
+ $this->{$valid_routes[ $requested_route ]}();
307
+ }
308
+
309
+ wp_die();
310
+ }
311
 
312
+ public function getAllTables() {
313
+ $perPage = intval( $_REQUEST['per_page'] ) ?: 10;
314
 
315
+ $currentPage = intval( $_GET['page'] );
 
 
 
 
 
 
316
 
317
+ $skip = $perPage * ( $currentPage - 1 );
318
 
319
+ $args = array(
320
+ 'posts_per_page' => $perPage,
321
+ 'offset' => $skip,
322
+ 'orderby' => 'date',
323
+ 'order' => 'DESC',
324
+ 'post_type' => $this->cpt_name,
325
+ 'post_status' => 'any',
326
 
327
+ );
328
 
329
+ if ( isset( $_REQUEST['search'] ) && $_REQUEST['search'] ) {
330
+ $args['s'] = sanitize_text_field( $_REQUEST['search'] );
331
+ }
332
 
333
+ $tables = get_posts( $args );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
334
 
335
+ foreach ( $tables as $table ) {
336
+ $table->preview_url = site_url( '?ninjatable_preview=' . $table->ID );
337
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
338
 
339
+ $total = wp_count_posts( 'ninja-table' );
340
+ $total = intval( $total->publish );
341
+ $lastPage = ceil( $total / $perPage );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
342
 
343
+ wp_send_json( array(
344
+ 'total' => $total,
345
+ 'per_page' => $perPage,
346
+ 'current_page' => $currentPage,
347
+ 'last_page' => ( $lastPage ) ? $lastPage : 1,
348
+ 'data' => $tables,
349
+ ), 200 );
350
+ }
351
 
352
+ public function storeTable() {
353
+ if ( ! $_REQUEST['post_title'] ) {
354
+ wp_send_json_error( array(
355
+ 'message' => __( 'The name field is required.', 'ninja-tables' )
356
+ ), 423 );
357
+ }
358
+
359
+ $postId = intval( $_REQUEST['tableId'] );
360
+
361
+ $attributes = array(
362
+ 'post_title' => sanitize_text_field( $_REQUEST['post_title'] ),
363
+ 'post_content' => wp_kses_post( $_REQUEST['post_content'] ),
364
+ 'post_type' => $this->cpt_name,
365
+ 'post_status' => 'publish'
366
+ );
367
+
368
+ if ( ! $postId ) {
369
+ $postId = wp_insert_post( $attributes );
370
+
371
+ wp_send_json( array(
372
+ 'message' => __( 'Successfully added table.', 'ninja-tables' ),
373
+ 'table_id' => $postId
374
+ ), 200 );
375
+ } else {
376
+ $attributes['ID'] = $postId;
377
+ wp_update_post( $attributes );
378
+
379
+ wp_send_json( array(
380
+ 'message' => __( 'Successfully updated table.',
381
+ 'ninja-tables' ),
382
+ 'table_id' => $postId
383
+ ), 200 );
384
+ }
385
+ }
386
 
387
+ public function importTable() {
388
+ $format = $_REQUEST['format'];
389
+
390
+ if ( $format == 'csv' ) {
391
+ $this->uploadTableCsv();
392
+ } elseif ( $format == 'json' ) {
393
+ $this->uploadTableJson();
394
+ } elseif ( $format == 'ninjaJson' ) {
395
+ $this->uploadTableNinjaJson();
396
+ }
397
+
398
+ wp_send_json( array(
399
+ 'message' => __( 'No appropriate driver found for the import format.',
400
+ 'ninja-tables' )
401
+ ), 423 );
402
+ }
403
 
 
 
 
 
 
 
 
404
 
405
+ public function saveCustomCSS() {
406
+ $tableId = intval( $_REQUEST['table_id'] );
407
+ $css = $_REQUEST['custom_css'];
408
+ $css = wp_strip_all_tags( $css );
409
+ update_post_meta( $tableId, '_ninja_tables_custom_css', $css );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
410
 
411
+ wp_send_json_success( array(
412
+ 'message' => 'Custom CSS successfully saved'
413
+ ), 200 );
414
+ }
 
 
415
 
416
+ private function tablePressImport() {
417
+ try {
418
+ $tableId = intval( $_REQUEST['tableId'] );
419
+
420
+ $table = get_post( $tableId );
421
+ update_post_meta( $tableId, '_imported_to_ninja_table', 'yes' );
422
+ $ninjaTableId = $this->createTable( array(
423
+ 'post_author' => intval( $table->post_author ),
424
+ 'post_title' => sanitize_text_field( '[Table Press] ' . $table->post_title ),
425
+ 'post_content' => wp_kses_post( $table->post_excerpt ),
426
+ 'post_status' => $table->post_status,
427
+ 'post_type' => $this->cpt_name,
428
+ ) );
429
+
430
+ $rows = json_decode( $table->post_content, true );
431
+
432
+ $tableSettings = get_post_meta( $table->ID, '_tablepress_table_options', true );
433
+
434
+ $tableSettings = json_decode( $tableSettings, true );
435
+
436
+ if ( $tableSettings['table_head'] ) {
437
+ $header = [];
438
+ $headerRow = array_values( array_shift( $rows ) );
439
+ foreach ( $headerRow as $index => $item ) {
440
+ $header[ 'ninja_column_' . ( $index + 1 ) ] = $item;
441
+ }
442
+ } else {
443
+ $header = array();
444
+ $columnCount = count( array_pop( array_reverse( $rows ) ) );
445
+
446
+ for ( $i = 0; $i < $columnCount; $i ++ ) {
447
+ $headerName = 'Ninja Column ' . ( $i + 1 );
448
+ $headerKey = 'ninja_column_' . ( $i + 1 );
449
+ $header[ $headerKey ] = $headerName;
450
+ }
451
+ }
452
+
453
+ $rows = array_reverse( $rows );
454
+
455
+ $this->storeTableConfigWhenImporting( $ninjaTableId, $header );
456
+
457
+ $this->insertDataToTable( $ninjaTableId, $rows, $header );
458
+
459
+ $message = __( 'Successfully imported '
460
+ . $table->post_title .
461
+ ' table from Table Press Plugin. Please go to all tables and review your table.'
462
+ );
463
+ } catch ( Exception $exception ) {
464
+ $message = __( 'Sorry, we could not import the table.', 'ninja-tables' );
465
+ }
466
+
467
+ wp_send_json( array(
468
+ 'message' => $message
469
+ ), 200 );
470
+ }
471
 
472
+ private function getTablesFromPlugin() {
473
+ $plugin = sanitize_text_field( $_REQUEST['plugin'] );
474
+ $libraryClass = false;
475
+
476
+ if ( $plugin == 'UltimateTables' ) {
477
+ $libraryClass = new NinjaTablesUltimateTableMigration();
478
+ } elseif ( $plugin == 'TablePress' ) {
479
+ $libraryClass = new NinjaTablesTablePressMigration();
480
+ } elseif ( $plugin == 'supsystic' ) {
481
+ $libraryClass = new \NinjaTables\Classes\NinjaTablesSupsysticTableMigration();
482
+ } else {
483
+ return false;
484
+ }
485
+ $tables = $libraryClass->getTables();
486
+
487
+ wp_send_json( array(
488
+ 'tables' => $tables
489
+ ), 200 );
490
+ }
491
 
 
 
 
492
 
493
+ private function importTableFromPlugin() {
494
+ $plugin = esc_attr( $_REQUEST['plugin'] );
495
+ $tableId = intval( $_REQUEST['tableId'] );
496
+
497
+ if ( $plugin == 'UltimateTables' ) {
498
+ $libraryClass = new NinjaTablesUltimateTableMigration();
499
+ } elseif ( $plugin == 'TablePress' ) {
500
+ $libraryClass = new NinjaTablesTablePressMigration();
501
+ } elseif ( $plugin == 'supsystic' ) {
502
+ $libraryClass = new \NinjaTables\Classes\NinjaTablesSupsysticTableMigration();
503
+ } else {
504
+ return false;
505
+ }
506
+
507
+ $tableId = $libraryClass->migrateTable( $tableId );
508
+ if ( is_wp_error( $tableId ) ) {
509
+ wp_send_json_error( array(
510
+ 'message' => $tableId->get_error_message()
511
+ ), 423 );
512
+ }
513
+
514
+ $message = __(
515
+ 'Successfully imported. Please go to all tables and review your newly imported table.',
516
+ 'ninja-tables'
517
+ );
518
+
519
+ wp_send_json_success( array(
520
+ 'message' => $message,
521
+ 'tableId' => $tableId
522
+ ), 200 );
523
+ }
524
 
525
+ private function formatHeader( $header ) {
526
+ $data = array();
527
 
528
+ $column_counter = 1;
 
 
 
 
529
 
530
+ foreach ( $header as $item ) {
531
+ $item = trim( strip_tags( $item ) );
532
 
533
+ // We'll slugify only if item is printable characters.
534
+ // Otherwise we'll generate custom key for the item.
535
+ // Printable chars as in ASCII printable chars.
536
+ // Ref: http://www.catonmat.net/blog/my-favorite-regex/
537
+ $key = ! preg_match( '/[^ -~]/', $item ) ? $this->url_slug( $item ) : null;
 
538
 
539
+ $key = sanitize_title( $key, 'ninja_column_' . $column_counter );
 
540
 
541
+ $counter = 1;
542
+ while ( isset( $data[ $key ] ) ) {
543
+ $key .= '_' . $counter;
544
+ $counter ++;
545
+ }
546
+ $data[ $key ] = $item;
547
 
548
+ $column_counter ++;
549
+ }
 
550
 
551
+ return $data;
552
+ }
553
 
554
+ private function uploadTableCsv() {
555
+ $tmpName = $_FILES['file']['tmp_name'];
556
 
557
+ $reader = \League\Csv\Reader::createFromPath( $tmpName )->fetchAll();
 
 
 
 
 
558
 
559
+ $header = array_shift( $reader );
560
+ $reader = array_reverse( $reader );
561
 
562
+ foreach ( $reader as &$item ) {
563
+ // We have to convert everything to utf-8
564
+ foreach ( $item as &$entry ) {
565
+ $entry = mb_convert_encoding( $entry, 'UTF-8' );
566
+ }
567
+ }
568
 
569
+ $tableId = $this->createTable();
570
 
571
+ $header = $this->formatHeader( $header );
572
 
573
+ $this->storeTableConfigWhenImporting( $tableId, $header );
 
 
 
 
574
 
575
+ $this->insertDataToTable( $tableId, $reader, $header );
 
 
576
 
577
+ wp_send_json( array(
578
+ 'message' => __( 'Successfully added a table.', 'ninja-tables' ),
579
+ 'tableId' => $tableId
580
+ ) );
581
+ }
582
 
583
+ private function uploadTableJson() {
584
+ $tableId = $this->createTable();
585
 
586
+ $tmpName = $_FILES['file']['tmp_name'];
587
 
588
+ $content = json_decode( file_get_contents( $tmpName ), true );
589
 
590
+ $header = array_keys( array_pop( array_reverse( $content ) ) );
591
 
592
+ $this->storeTableConfigWhenImporting( $tableId, $header );
 
 
 
 
593
 
594
+ $this->insertDataToTable( $tableId, $content, $header );
 
 
595
 
596
+ wp_send_json( array(
597
+ 'message' => __( 'Successfully added a table.', 'ninja-tables' ),
598
+ 'tableId' => $tableId
599
+ ) );
600
+ }
601
 
602
+ private function uploadTableNinjaJson() {
603
+ $tmpName = $_FILES['file']['tmp_name'];
 
 
 
 
 
604
 
605
+ $content = json_decode( file_get_contents( $tmpName ), true );
 
 
 
 
 
606
 
607
+ // validation
608
+ if ( ! $content['post'] || ! $content['columns'] || ! $content['settings'] ) {
609
+ wp_send_json( array(
610
+ 'message' => __( 'You have a faulty JSON file. Please export a new one.',
611
+ 'ninja-tables' )
612
+ ), 423 );
613
+ }
614
 
615
+ $tableAttributes = array(
616
+ 'post_title' => sanitize_title( $content['post']['post_title'] ),
617
+ 'post_content' => wp_kses_post( $content['post']['post_content'] ),
618
+ 'post_type' => $this->cpt_name,
619
+ 'post_status' => 'publish'
620
+ );
621
 
622
+ $tableId = $this->createTable( $tableAttributes );
623
 
624
+ update_post_meta( $tableId, '_ninja_table_columns', $content['columns'] );
 
625
 
626
+ update_post_meta( $tableId, '_ninja_table_settings', $content['settings'] );
 
 
627
 
628
+ if ( $rows = $content['rows'] ) {
629
+ $header = [];
630
 
631
+ foreach ( $content['columns'] as $column ) {
632
+ $header[ $column['key'] ] = $column['name'];
633
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
634
 
635
+ $this->insertDataToTable( $tableId, $rows, $header );
636
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
637
 
638
+ wp_send_json( array(
639
+ 'message' => __( 'Successfully added a table.', 'ninja-tables' ),
640
+ 'tableId' => $tableId
641
+ ) );
642
+ }
 
 
643
 
644
+ private function createTable( $data = null ) {
645
+ return wp_insert_post( $data
646
+ ? $data
647
+ : array(
648
+ 'post_title' => __( 'Temporary table name', 'ninja-tables' ),
649
+ 'post_content' => __( 'Temporary table description',
650
+ 'ninja-tables' ),
651
+ 'post_type' => $this->cpt_name,
652
+ 'post_status' => 'publish'
653
+ ) );
654
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
655
 
656
+ private function storeTableConfigWhenImporting( $tableId, $header ) {
657
+ // ninja_table_columns
658
+ $ninjaTableColumns = array();
659
 
660
+ foreach ( $header as $key => $name ) {
661
+ $ninjaTableColumns[] = array(
662
+ 'key' => $key,
663
+ 'name' => $name,
664
+ 'breakpoints' => ''
665
+ );
666
+ }
667
 
668
+ update_post_meta( $tableId, '_ninja_table_columns', $ninjaTableColumns );
 
 
669
 
670
+ // ninja_table_settings
671
+ $ninjaTableSettings = ninja_table_get_table_settings( $tableId, 'admin' );
 
 
 
672
 
673
+ update_post_meta( $tableId, '_ninja_table_settings', $ninjaTableSettings );
 
674
 
675
+ ninjaTablesClearTableDataCache( $tableId );
676
+ }
 
677
 
678
+ private function insertDataToTable( $tableId, $values, $header ) {
679
+ $header = array_keys( $header );
680
+ $time = current_time( 'mysql' );
681
+ $headerCount = count( $header );
682
+
683
+ foreach ( $values as $item ) {
684
+ if ( $headerCount == count( $item ) ) {
685
+ $itemTemp = array_combine( $header, $item );
686
+ } else {
687
+ // The item can have less/more entry than the header has.
688
+ // We have to ensure that the header and values match.
689
+ $itemTemp = array_combine(
690
+ $header,
691
+ // We'll get the appropriate values by merging Array1 & Array2
692
+ array_merge(
693
+ // Array1 = Only the entries that the header has.
694
+ array_intersect_key( $item, array_fill_keys( array_values( $header ), null ) ),
695
+ // Array2 = The remaining header entries will be blank.
696
+ array_fill_keys( array_diff( array_values( $header ), array_keys( $item ) ), null )
697
+ )
698
+ );
699
+ }
700
+
701
+ $data = array(
702
+ 'table_id' => $tableId,
703
+ 'attribute' => 'value',
704
+ 'value' => json_encode( $itemTemp ),
705
+ 'created_at' => $time,
706
+ 'updated_at' => $time
707
+ );
708
+
709
+ ninja_tables_DbTable()->insert( $data );
710
+ }
711
+ }
712
 
713
+ public function getTableSettings() {
714
+ $tableID = intval( $_REQUEST['table_id'] );
715
+ $table = get_post( $tableID );
716
+ $tableColumns = ninja_table_get_table_columns( $tableID, 'admin' );
717
 
718
+ $tableSettings = ninja_table_get_table_settings( $tableID, 'admin' );
719
+ $table->custom_css = get_post_meta( $tableID, '_ninja_tables_custom_css', true );
 
 
 
 
 
 
 
 
 
720
 
721
+ wp_send_json( array(
722
+ 'columns' => $tableColumns,
723
+ 'settings' => $tableSettings,
724
+ 'table' => $table,
725
+ 'preview_url' => site_url( '?ninjatable_preview=' . $tableID ),
726
+ ), 200 );
727
+ }
728
 
729
+ public function updateTableSettings() {
730
+ $tableId = intval( $_REQUEST['table_id'] );
731
+
732
+ $tableColumns = array();
733
+
734
+ if ( isset( $_REQUEST['columns'] ) ) {
735
+ $rawColumns = $_REQUEST['columns'];
736
+ if ( $rawColumns && is_array( $rawColumns ) ) {
737
+ foreach ( $rawColumns as $column ) {
738
+ foreach ( $column as $column_index => $column_value ) {
739
+ if ( $column_index == 'header_html_content' || $column_index == 'selections' ) {
740
+ $column[ $column_index ] = wp_kses_post( $column_value );
741
+ } else {
742
+ $column[ $column_index ] = sanitize_text_field( $column_value );
743
+ }
744
+ }
745
+ $tableColumns[] = $column;
746
+ }
747
+ update_post_meta( $tableId, '_ninja_table_columns', $tableColumns );
748
+ }
749
+ }
750
+
751
+ $formattedTablePreference = array();
752
+
753
+ if ( isset( $_REQUEST['table_settings'] ) ) {
754
+ $tablePreference = $_REQUEST['table_settings'];
755
+ if ( $tablePreference && is_array( $tablePreference ) ) {
756
+ foreach ( $tablePreference as $key => $tab_pref ) {
757
+ if ( $tab_pref == 'false' ) {
758
+ $tab_pref = false;
759
+ }
760
+
761
+ if ( $tab_pref == 'true' ) {
762
+ $tab_pref = true;
763
+ }
764
+
765
+ if ( is_array( $tab_pref ) ) {
766
+ $tab_pref = array_map( 'sanitize_text_field', $tab_pref );
767
+ } else {
768
+ $tab_pref = sanitize_text_field( $tab_pref );
769
+ }
770
+
771
+ $formattedTablePreference[ $key ] = $tab_pref;
772
+ }
773
+
774
+ update_post_meta( $tableId, '_ninja_table_settings', $formattedTablePreference );
775
+ }
776
+ }
777
+
778
+ ninjaTablesClearTableDataCache( $tableId );
779
+
780
+ wp_send_json( array(
781
+ 'message' => __( 'Successfully updated configuration.', 'ninja-tables' ),
782
+ 'columns' => $tableColumns,
783
+ 'settings' => $formattedTablePreference
784
+ ), 200 );
785
+ }
786
 
787
+ public function getTable() {
788
+ $tableId = intval( $_REQUEST['id'] );
789
+ $table = get_post( $tableId );
790
 
791
+ wp_send_json( array(
792
+ 'data' => $table
793
+ ), 200 );
794
+ }
795
 
796
+ public function deleteTable() {
797
+ $tableId = intval( $_REQUEST['table_id'] );
798
+
799
+ if ( get_post_type( $tableId ) != $this->cpt_name ) {
800
+ wp_send_json( array(
801
+ 'message' => __( 'Invalid Table to Delete', 'ninja-tables' )
802
+ ), 300 );
803
+ }
804
+
805
+
806
+ wp_delete_post( $tableId, true );
807
+ // Delete the post metas
808
+ delete_post_meta( $tableId, '_ninja_table_columns' );
809
+ delete_post_meta( $tableId, '_ninja_table_settings' );
810
+ delete_post_meta( $tableId, '_ninja_table_cache_object' );
811
+ // now delete the data
812
+ try {
813
+ ninja_tables_DbTable()->where( 'table_id', $tableId )->delete();
814
+ } catch ( Exception $e ) {
815
+ //
816
+ }
817
+
818
+ wp_send_json( array(
819
+ 'message' => __( 'Successfully deleted the table.', 'ninja-tables' )
820
+ ), 200 );
821
+ }
822
 
823
+ public function getTableData() {
824
+ $perPage = intval( $_REQUEST['per_page'] ) ?: 10;
825
 
826
+ $currentPage = isset( $_GET['page'] ) ? intval( $_GET['page'] ) : 1;
827
 
828
+ $skip = $perPage * ( $currentPage - 1 );
829
 
830
+ $tableId = intval( $_REQUEST['table_id'] );
 
 
831
 
832
+ $search = esc_attr( $_REQUEST['search'] );
 
 
 
833
 
834
+ list( $orderByField, $orderByType ) = $this->getTableSortingParams( $tableId );
835
 
836
+ $query = ninja_tables_DbTable()->where( 'table_id', $tableId );
837
 
838
+ if ( $search ) {
839
+ $query->search( $search, array( 'value' ) );
840
+ }
 
 
 
 
841
 
842
+ $data = $query->take( $perPage )
843
+ ->skip( $skip )
844
+ ->orderBy( $orderByField, $orderByType )
845
+ ->get();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
846
 
847
+ $total = ninja_tables_DbTable()->where( 'table_id', $tableId )->count();
 
848
 
849
+ $response = array();
 
 
 
 
850
 
851
+ foreach ( $data as $item ) {
852
+ $response[] = array(
853
+ 'id' => $item->id,
854
+ 'position' => property_exists( $item, 'position' ) ? $item->position : null,
855
+ 'values' => json_decode( $item->value, true )
856
+ );
857
+ }
858
 
859
+ wp_send_json( array(
860
+ 'total' => $total,
861
+ 'per_page' => $perPage,
862
+ 'current_page' => $currentPage,
863
+ 'last_page' => ceil( $total / $perPage ),
864
+ 'data' => $response
865
+ ), 200 );
866
+ }
867
 
868
+ /**
869
+ * Get the order by field and order by type values.
870
+ *
871
+ * @param $tableId
872
+ * @param null $tableSettings
873
+ *
874
+ * @return array
875
+ */
876
+ protected function getTableSortingParams( $tableId, $tableSettings = null ) {
877
+ $tableSettings = $tableSettings ?: ninja_table_get_table_settings( $tableId, 'admin' );
878
+
879
+ $orderByField = 'id';
880
+ $orderByType = 'DESC';
881
+
882
+ if ( isset( $tableSettings['sorting_type'] ) ) {
883
+ if ( $tableSettings['sorting_type'] === 'manual_sort' ) {
884
+ $this->migrateDatabaseIfNeeded();
885
+ $orderByField = 'position';
886
+ $orderByType = 'ASC';
887
+ } elseif ( $tableSettings['sorting_type'] === 'by_created_at' ) {
888
+ $orderByField = 'id';
889
+ if ( $tableSettings['default_sorting'] === 'new_first' ) {
890
+ $orderByType = 'DESC';
891
+ } else {
892
+ $orderByType = 'ASC';
893
+ }
894
+ }
895
+ }
896
+
897
+ return [ $orderByField, $orderByType ];
898
+ }
899
 
900
+ public function storeData() {
901
+ $tableId = intval( $_REQUEST['table_id'] );
902
+ $row = $_REQUEST['row'];
903
+ $formattedRow = array();
904
+
905
+ foreach ( $row as $key => $item ) {
906
+ $formattedRow[ $key ] = wp_unslash( $item );
907
+ }
908
+
909
+ $attributes = array(
910
+ 'table_id' => $tableId,
911
+ 'attribute' => 'value',
912
+ 'value' => json_encode( $formattedRow, true ),
913
+ 'updated_at' => date( 'Y-m-d H:i:s' )
914
+ );
915
+
916
+ if ( $id = intval( $_REQUEST['id'] ) ) {
917
+ ninja_tables_DbTable()->where( 'id', $id )->update( $attributes );
918
+ } else {
919
+ $attributes['created_at'] = date( 'Y-m-d H:i:s' );
920
+
921
+ $attributes = apply_filters( 'ninja_tables_item_attributes', $attributes );
922
+
923
+ $id = $insertId = ninja_tables_DbTable()->insert( $attributes );
924
+ }
925
+
926
+ $item = ninja_tables_DbTable()->find( $id );
927
+
928
+ ninjaTablesClearTableDataCache( $tableId );
929
+
930
+ wp_send_json( array(
931
+ 'message' => __( 'Successfully saved the data.', 'ninja-tables' ),
932
+ 'item' => array(
933
+ 'id' => $item->id,
934
+ 'values' => $formattedRow,
935
+ 'row' => json_decode( $item->value ),
936
+ 'position' => property_exists( $item, 'position' ) ? $item->position : null
937
+ )
938
+ ), 200 );
939
+ }
940
 
941
+ public function deleteData() {
942
+ $tableId = intval( $_REQUEST['table_id'] );
943
 
944
+ $id = $_REQUEST['id'];
945
 
946
+ $ids = is_array( $id ) ? $id : array( $id );
947
 
948
+ $ids = array_map( function ( $item ) {
949
+ return intval( $item );
950
+ }, $ids );
 
 
 
 
 
 
 
951
 
952
+ ninja_tables_DbTable()->where( 'table_id', $tableId )->whereIn( 'id', $ids )->delete();
 
 
953
 
954
+ ninjaTablesClearTableDataCache( $tableId );
955
 
956
+ wp_send_json( array(
957
+ 'message' => __( 'Successfully deleted data.', 'ninja-tables' )
958
+ ), 200 );
959
+ }
960
 
961
+ public function uploadData() {
962
+ $tableId = intval( $_REQUEST['table_id'] );
963
+ $tmpName = $_FILES['file']['tmp_name'];
964
 
965
+ $reader = \League\Csv\Reader::createFromPath( $tmpName )->fetchAll();
966
 
967
+ $csvHeader = array_shift( $reader );
968
+ $csvHeader = array_map( 'esc_attr', $csvHeader );
969
 
970
+ $config = get_post_meta( $tableId, '_ninja_table_columns', true );
971
+ if ( ! $config ) {
972
+ wp_send_json( array(
973
+ 'message' => __( 'Please set table configuration.', 'ninja-tables' )
974
+ ), 423 );
975
+ }
976
 
977
+ $header = array();
 
 
 
978
 
979
+ foreach ( $csvHeader as $item ) {
980
+ foreach ( $config as $column ) {
981
+ $item = esc_attr( $item );
982
+ if ( $item == $column['key'] || $item == $column['name'] ) {
983
+ $header[] = $column['key'];
984
+ }
985
+ }
986
+ }
987
 
988
+ if ( count( $header ) != count( $config ) ) {
989
+ wp_send_json( array(
990
+ 'message' => __( 'Please use the provided CSV header structure.', 'ninja-tables' )
991
+ ), 423 );
992
+ }
993
 
994
+ $data = array();
995
+ $time = current_time( 'mysql' );
 
 
 
 
996
 
997
+ foreach ( $reader as $item ) {
998
+ // If item has any ascii entry we'll convert it to utf-8
999
+ foreach ( $item as &$entry ) {
1000
+ $entry = mb_convert_encoding( $entry, 'UTF-8' );
1001
+ }
1002
 
1003
+ $itemTemp = array_combine( $header, $item );
 
 
 
 
 
 
 
1004
 
1005
+ array_push( $data, array(
1006
+ 'table_id' => $tableId,
1007
+ 'attribute' => 'value',
1008
+ 'value' => json_encode( $itemTemp ),
1009
+ 'created_at' => $time,
1010
+ 'updated_at' => $time
1011
+ ) );
1012
+ }
1013
 
1014
+ $replace = $_REQUEST['replace'] === 'true';
 
1015
 
1016
+ if ( $replace ) {
1017
+ ninja_tables_DbTable()->where( 'table_id', $tableId )->delete();
1018
+ }
 
 
1019
 
1020
+ $data = apply_filters( 'ninja_tables_import_table_data', $data, $tableId );
1021
 
1022
+ ninja_tables_DbTable()->batch_insert( $data );
 
 
 
 
 
 
 
1023
 
1024
+ ninjaTablesClearTableDataCache( $tableId );
1025
 
1026
+ wp_send_json( array(
1027
+ 'message' => __( 'Successfully uploaded data.', 'ninja-tables' )
1028
+ ) );
1029
+ }
1030
 
1031
+ public function exportData() {
1032
+ $format = esc_attr( $_REQUEST['format'] );
1033
 
1034
+ $tableId = intval( $_REQUEST['table_id'] );
1035
 
1036
+ $tableTitle = get_the_title( $tableId );
1037
 
1038
+ $fileName = sanitize_title( $tableTitle, date( 'Y-m-d-H-i-s' ), 'preview' );
 
 
 
1039
 
1040
+ $tableColumns = ninja_table_get_table_columns( $tableId, 'admin' );
 
 
1041
 
1042
+ $tableSettings = ninja_table_get_table_settings( $tableId, 'admin' );
1043
 
1044
+ list( $orderByField, $orderByType ) = $this->getTableSortingParams( $tableId, $tableSettings );
 
 
 
 
1045
 
1046
+ $data = ninja_tables_DbTable()->where( 'table_id', $tableId )->orderBy( $orderByField, $orderByType )->get();
1047
 
1048
+ if ( $format == 'csv' ) {
1049
 
1050
+ $header = array();
1051
 
1052
+ foreach ( $tableColumns as $item ) {
1053
+ $header[ $item['key'] ] = $item['name'];
1054
+ }
1055
 
1056
+ $exportData = array();
1057
 
1058
+ foreach ( $data as $item ) {
1059
+ $temp = array();
1060
+ $item = json_decode( $item->value, true );
1061
 
1062
+ foreach ( $header as $accessor => $name ) {
1063
+ $temp[] = $item[ $accessor ];
1064
+ }
1065
 
1066
+ array_push( $exportData, $temp );
1067
+ }
 
1068
 
1069
+ $this->exportAsCSV( array_values( $header ), $exportData, $fileName . '.csv' );
1070
+ } elseif ( $format == 'json' ) {
1071
+ $table = get_post( $tableId );
1072
 
1073
+ $tableItems = array_map( function ( $item ) {
1074
+ return json_decode( $item->value, true );
1075
+ }, $data );
1076
 
1077
+ $exportData = array(
1078
+ 'post' => $table,
1079
+ 'columns' => $tableColumns,
1080
+ 'settings' => $tableSettings,
1081
+ 'rows' => $tableItems
1082
+ );
1083
 
1084
+ $this->exportAsJSON( $exportData, $fileName . '.json' );
1085
+ }
1086
+ }
1087
 
1088
+ private function exportAsCSV( $header, $data, $fileName = null ) {
1089
+ $fileName = $fileName ?: 'export-data-' . date( 'd-m-Y' );
 
 
 
 
1090
 
1091
+ $writer = \League\Csv\Writer::createFromFileObject( new SplTempFileObject() );
1092
+ $writer->setDelimiter( "," );
1093
+ $writer->setNewline( "\r\n" );
1094
+ $writer->insertOne( $header );
1095
+ $writer->insertAll( $data );
1096
+ $writer->output( $fileName . '.csv' );
1097
+ die();
1098
+ }
1099
 
1100
+ private function exportAsJSON( $data, $fileName = null ) {
1101
+ $fileName = $fileName ?: 'export-data-' . date( 'd-m-Y' ) . '.json';
 
1102
 
1103
+ header( 'Content-disposition: attachment; filename=' . $fileName );
 
 
 
 
 
 
 
1104
 
1105
+ header( 'Content-type: application/json' );
 
 
1106
 
1107
+ echo json_encode( $data );
1108
 
1109
+ die();
1110
+ }
1111
 
1112
+ public function add_tabales_to_editor() {
1113
+ if ( user_can_richedit() ) {
1114
+ $pages_with_editor_button = array( 'post.php', 'post-new.php' );
1115
+ foreach ( $pages_with_editor_button as $editor_page ) {
1116
+ add_action( "load-{$editor_page}", array( $this, 'init_ninja_mce_buttons' ) );
1117
+ }
1118
+ }
1119
+ }
1120
 
1121
+ public function init_ninja_mce_buttons() {
1122
+ add_filter( "mce_external_plugins", array( $this, 'ninja_table_add_button' ) );
1123
+ add_filter( 'mce_buttons', array( $this, 'ninja_table_register_button' ) );
1124
+ add_action( 'admin_footer', array( $this, 'pushNinjaTablesToEditorFooter' ) );
1125
+ }
1126
 
1127
+ public function pushNinjaTablesToEditorFooter() {
1128
+ $tables = $this->getAllTablesForMce();
1129
+ ?>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1130
  <script type="text/javascript">
1131
  window.ninja_tables_tiny_mce = {
1132
+ label: '<?php _e( 'Select a Table to insert', 'ninja-tables' ) ?>',
1133
+ title: '<?php _e( 'Insert Ninja Tables Shortcode', 'ninja-tables' ) ?>',
1134
+ select_error: '<?php _e( 'Please select a table' ); ?>',
1135
+ insert_text: '<?php _e( 'Insert Shortcode', 'ninja-tables' ); ?>',
1136
+ tables: <?php echo json_encode( $tables );?>
1137
  }
1138
  </script>
1139
+ <?php
1140
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1141
 
1142
+ private function getAllTablesForMce() {
1143
+ $args = array(
1144
+ 'posts_per_page' => - 1,
1145
+ 'orderby' => 'date',
1146
+ 'order' => 'DESC',
1147
+ 'post_type' => $this->cpt_name,
1148
+ 'post_status' => 'any'
1149
+ );
1150
+
1151
+ $tables = get_posts( $args );
1152
+ $formatted = array();
1153
+ $formatted[] = array(
1154
+ 'text' => __( 'Select a Table', 'ninja-tables' ),
1155
+ 'value' => ''
1156
+ );
1157
+
1158
+ foreach ( $tables as $table ) {
1159
+ $formatted[] = array(
1160
+ 'text' => $table->post_title,
1161
+ 'value' => $table->ID
1162
+ );
1163
+ }
1164
+
1165
+ return $formatted;
1166
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1167
 
1168
+ /**
1169
+ * add a button to Tiny MCE editor
1170
+ *
1171
+ * @param $plugin_array
1172
+ *
1173
+ * @return mixed
1174
+ */
1175
+ public function ninja_table_add_button( $plugin_array ) {
1176
+ $plugin_array['ninja_table'] = NINJA_TABLES_DIR_URL . 'assets/js/ninja-table-tinymce-button.js';
1177
+
1178
+ return $plugin_array;
1179
+ }
1180
+
1181
+ /**
1182
+ * register a button to Tiny MCE editor
1183
+ *
1184
+ * @param $buttons
1185
+ *
1186
+ * @return mixed
1187
+ */
1188
+ public function ninja_table_register_button( $buttons ) {
1189
+ array_push( $buttons, 'ninja_table' );
1190
+
1191
+ return $buttons;
1192
+ }
 
 
 
 
 
 
 
 
 
 
 
1193
 
1194
+ public function dismissPluginSuggest() {
1195
+ update_option( '_ninja_tables_plugin_suggest_dismiss', time() );
1196
+ }
1197
 
1198
+ private function url_slug( $str, $options = array() ) {
1199
+ // Make sure string is in UTF-8 and strip invalid UTF-8 characters
1200
+ $str = mb_convert_encoding( (string) $str, 'UTF-8', mb_list_encodings() );
1201
+
1202
+ $defaults = array(
1203
+ 'delimiter' => '_',
1204
+ 'limit' => null,
1205
+ 'lowercase' => true,
1206
+ 'replacements' => array(),
1207
+ 'transliterate' => true,
1208
+ );
1209
+
1210
+ // Merge options
1211
+ $options = array_merge( $defaults, $options );
1212
+
1213
+ $char_map = array(
1214
+ // Latin
1215
+ 'À' => 'A',
1216
+ 'Á' => 'A',
1217
+ 'Â' => 'A',
1218
+ 'Ã' => 'A',
1219
+ 'Ä' => 'A',
1220
+ 'Å' => 'A',
1221
+ 'Æ' => 'AE',
1222
+ 'Ç' => 'C',
1223
+ 'È' => 'E',
1224
+ 'É' => 'E',
1225
+ 'Ê' => 'E',
1226
+ 'Ë' => 'E',
1227
+ 'Ì' => 'I',
1228
+ 'Í' => 'I',
1229
+ 'Î' => 'I',
1230
+ 'Ï' => 'I',
1231
+ 'Ð' => 'D',
1232
+ 'Ñ' => 'N',
1233
+ 'Ò' => 'O',
1234
+ 'Ó' => 'O',
1235
+ 'Ô' => 'O',
1236
+ 'Õ' => 'O',
1237
+ 'Ö' => 'O',
1238
+ 'Ő' => 'O',
1239
+ 'Ø' => 'O',
1240
+ 'Ù' => 'U',
1241
+ 'Ú' => 'U',
1242
+ 'Û' => 'U',
1243
+ 'Ü' => 'U',
1244
+ 'Ű' => 'U',
1245
+ 'Ý' => 'Y',
1246
+ 'Þ' => 'TH',
1247
+ 'ß' => 'ss',
1248
+ 'à' => 'a',
1249
+ 'á' => 'a',
1250
+ 'â' => 'a',
1251
+ 'ã' => 'a',
1252
+ 'ä' => 'a',
1253
+ 'å' => 'a',
1254
+ 'æ' => 'ae',
1255
+ 'ç' => 'c',
1256
+ 'è' => 'e',
1257
+ 'é' => 'e',
1258
+ 'ê' => 'e',
1259
+ 'ë' => 'e',
1260
+ 'ì' => 'i',
1261
+ 'í' => 'i',
1262
+ 'î' => 'i',
1263
+ 'ï' => 'i',
1264
+ 'ð' => 'd',
1265
+ 'ñ' => 'n',
1266
+ 'ò' => 'o',
1267
+ 'ó' => 'o',
1268
+ 'ô' => 'o',
1269
+ 'õ' => 'o',
1270
+ 'ö' => 'o',
1271
+ 'ő' => 'o',
1272
+ 'ø' => 'o',
1273
+ 'ù' => 'u',
1274
+ 'ú' => 'u',
1275
+ 'û' => 'u',
1276
+ 'ü' => 'u',
1277
+ 'ű' => 'u',
1278
+ 'ý' => 'y',
1279
+ 'þ' => 'th',
1280
+ 'ÿ' => 'y',
1281
+ // Latin symbols
1282
+ '©' => '(c)',
1283
+ // Greek
1284
+ 'Α' => 'A',
1285
+ 'Β' => 'B',
1286
+ 'Γ' => 'G',
1287
+ 'Δ' => 'D',
1288
+ 'Ε' => 'E',
1289
+ 'Ζ' => 'Z',
1290
+ 'Η' => 'H',
1291
+ 'Θ' => '8',
1292
+ 'Ι' => 'I',
1293
+ 'Κ' => 'K',
1294
+ 'Λ' => 'L',
1295
+ 'Μ' => 'M',
1296
+ 'Ν' => 'N',
1297
+ 'Ξ' => '3',
1298
+ 'Ο' => 'O',
1299
+ 'Π' => 'P',
1300
+ 'Ρ' => 'R',
1301
+ 'Σ' => 'S',
1302
+ 'Τ' => 'T',
1303
+ 'Υ' => 'Y',
1304
+ 'Φ' => 'F',
1305
+ 'Χ' => 'X',
1306
+ 'Ψ' => 'PS',
1307
+ 'Ω' => 'W',
1308
+ 'Ά' => 'A',
1309
+ 'Έ' => 'E',
1310
+ 'Ί' => 'I',
1311
+ 'Ό' => 'O',
1312
+ 'Ύ' => 'Y',
1313
+ 'Ή' => 'H',
1314
+ 'Ώ' => 'W',
1315
+ 'Ϊ' => 'I',
1316
+ 'Ϋ' => 'Y',
1317
+ 'α' => 'a',
1318
+ 'β' => 'b',
1319
+ 'γ' => 'g',
1320
+ 'δ' => 'd',
1321
+ 'ε' => 'e',
1322
+ 'ζ' => 'z',
1323
+ 'η' => 'h',
1324
+ 'θ' => '8',
1325
+ 'ι' => 'i',
1326
+ 'κ' => 'k',
1327
+ 'λ' => 'l',
1328
+ 'μ' => 'm',
1329
+ 'ν' => 'n',
1330
+ 'ξ' => '3',
1331
+ 'ο' => 'o',
1332
+ 'π' => 'p',
1333
+ 'ρ' => 'r',
1334
+ 'σ' => 's',
1335
+ 'τ' => 't',
1336
+ 'υ' => 'y',
1337
+ 'φ' => 'f',
1338
+ 'χ' => 'x',
1339
+ 'ψ' => 'ps',
1340
+ 'ω' => 'w',
1341
+ 'ά' => 'a',
1342
+ 'έ' => 'e',
1343
+ 'ί' => 'i',
1344
+ 'ό' => 'o',
1345
+ 'ύ' => 'y',
1346
+ 'ή' => 'h',
1347
+ 'ώ' => 'w',
1348
+ 'ς' => 's',
1349
+ 'ϊ' => 'i',
1350
+ 'ΰ' => 'y',
1351
+ 'ϋ' => 'y',
1352
+ 'ΐ' => 'i',
1353
+ // Turkish
1354
+ 'Ş' => 'S',
1355
+ 'İ' => 'I',
1356
+ 'Ç' => 'C',
1357
+ 'Ü' => 'U',
1358
+ 'Ö' => 'O',
1359
+ 'Ğ' => 'G',
1360
+ 'ş' => 's',
1361
+ 'ı' => 'i',
1362
+ 'ç' => 'c',
1363
+ 'ü' => 'u',
1364
+ 'ö' => 'o',
1365
+ 'ğ' => 'g',
1366
+ // Russian
1367
+ 'А' => 'A',
1368
+ 'Б' => 'B',
1369
+ 'В' => 'V',
1370
+ 'Г' => 'G',
1371
+ 'Д' => 'D',
1372
+ 'Е' => 'E',
1373
+ 'Ё' => 'Yo',
1374
+ 'Ж' => 'Zh',
1375
+ 'З' => 'Z',
1376
+ 'И' => 'I',
1377
+ 'Й' => 'J',
1378
+ 'К' => 'K',
1379
+ 'Л' => 'L',
1380
+ 'М' => 'M',
1381
+ 'Н' => 'N',
1382
+ 'О' => 'O',
1383
+ 'П' => 'P',
1384
+ 'Р' => 'R',
1385
+ 'С' => 'S',
1386
+ 'Т' => 'T',
1387
+ 'У' => 'U',
1388
+ 'Ф' => 'F',
1389
+ 'Х' => 'H',
1390
+ 'Ц' => 'C',
1391
+ 'Ч' => 'Ch',
1392
+ 'Ш' => 'Sh',
1393
+ 'Щ' => 'Sh',
1394
+ 'Ъ' => '',
1395
+ 'Ы' => 'Y',
1396
+ 'Ь' => '',
1397
+ 'Э' => 'E',
1398
+ 'Ю' => 'Yu',
1399
+ 'Я' => 'Ya',
1400
+ 'а' => 'a',
1401
+ 'б' => 'b',
1402
+ 'в' => 'v',
1403
+ 'г' => 'g',
1404
+ 'д' => 'd',
1405
+ 'е' => 'e',
1406
+ 'ё' => 'yo',
1407
+ 'ж' => 'zh',
1408
+ 'з' => 'z',
1409
+ 'и' => 'i',
1410
+ 'й' => 'j',
1411
+ 'к' => 'k',
1412
+ 'л' => 'l',
1413
+ 'м' => 'm',
1414
+ 'н' => 'n',
1415
+ 'о' => 'o',
1416
+ 'п' => 'p',
1417
+ 'р' => 'r',
1418
+ 'с' => 's',
1419
+ 'т' => 't',
1420
+ 'у' => 'u',
1421
+ 'ф' => 'f',
1422
+ 'х' => 'h',
1423
+ 'ц' => 'c',
1424
+ 'ч' => 'ch',
1425
+ 'ш' => 'sh',
1426
+ 'щ' => 'sh',
1427
+ 'ъ' => '',
1428
+ 'ы' => 'y',
1429
+ 'ь' => '',
1430
+ 'э' => 'e',
1431
+ 'ю' => 'yu',
1432
+ 'я' => 'ya',
1433
+ // Ukrainian
1434
+ 'Є' => 'Ye',
1435
+ 'І' => 'I',
1436
+ 'Ї' => 'Yi',
1437
+ 'Ґ' => 'G',
1438
+ 'є' => 'ye',
1439
+ 'і' => 'i',
1440
+ 'ї' => 'yi',
1441
+ 'ґ' => 'g',
1442
+ // Czech
1443
+ 'Č' => 'C',
1444
+ 'Ď' => 'D',
1445
+ 'Ě' => 'E',
1446
+ 'Ň' => 'N',
1447
+ 'Ř' => 'R',
1448
+ 'Š' => 'S',
1449
+ 'Ť' => 'T',
1450
+ 'Ů' => 'U',
1451
+ 'Ž' => 'Z',
1452
+ 'č' => 'c',
1453
+ 'ď' => 'd',
1454
+ 'ě' => 'e',
1455
+ 'ň' => 'n',
1456
+ 'ř' => 'r',
1457
+ 'š' => 's',
1458
+ 'ť' => 't',
1459
+ 'ů' => 'u',
1460
+ 'ž' => 'z',
1461
+ // Polish
1462
+ 'Ą' => 'A',
1463
+ 'Ć' => 'C',
1464
+ 'Ę' => 'e',
1465
+ 'Ł' => 'L',
1466
+ 'Ń' => 'N',
1467
+ 'Ó' => 'o',
1468
+ 'Ś' => 'S',
1469
+ 'Ź' => 'Z',
1470
+ 'Ż' => 'Z',
1471
+ 'ą' => 'a',
1472
+ 'ć' => 'c',
1473
+ 'ę' => 'e',
1474
+ 'ł' => 'l',
1475
+ 'ń' => 'n',
1476
+ 'ó' => 'o',
1477
+ 'ś' => 's',
1478
+ 'ź' => 'z',
1479
+ 'ż' => 'z',
1480
+ // Latvian
1481
+ 'Ā' => 'A',
1482
+ 'Č' => 'C',
1483
+ 'Ē' => 'E',
1484
+ 'Ģ' => 'G',
1485
+ 'Ī' => 'i',
1486
+ 'Ķ' => 'k',
1487
+ 'Ļ' => 'L',
1488
+ 'Ņ' => 'N',
1489
+ 'Š' => 'S',
1490
+ 'Ū' => 'u',
1491
+ 'Ž' => 'Z',
1492
+ 'ā' => 'a',
1493
+ 'č' => 'c',
1494
+ 'ē' => 'e',
1495
+ 'ģ' => 'g',
1496
+ 'ī' => 'i',
1497
+ 'ķ' => 'k',
1498
+ 'ļ' => 'l',
1499
+ 'ņ' => 'n',
1500
+ 'š' => 's',
1501
+ 'ū' => 'u',
1502
+ 'ž' => 'z',
1503
+ );
1504
+
1505
+ // Make custom replacements
1506
+ $str = preg_replace( array_keys( $options['replacements'] ), $options['replacements'], $str );
1507
+
1508
+ // Transliterate characters to ASCII
1509
+ if ( $options['transliterate'] ) {
1510
+ $str = str_replace( array_keys( $char_map ), $char_map, $str );
1511
+ }
1512
+
1513
+ // Replace non-alphanumeric characters with our delimiter
1514
+ $str = preg_replace( '/[^\p{L}\p{Nd}]+/u', $options['delimiter'], $str );
1515
+
1516
+ // Remove duplicate delimiters
1517
+ $str = preg_replace( '/(' . preg_quote( $options['delimiter'], '/' ) . '){2,}/', '$1', $str );
1518
+
1519
+ // Truncate slug to max. characters
1520
+ $str = mb_substr( $str, 0, ( $options['limit'] ? $options['limit'] : mb_strlen( $str, 'UTF-8' ) ), 'UTF-8' );
1521
+
1522
+ // Remove delimiter from ends
1523
+ $str = trim( $str, $options['delimiter'] );
1524
+
1525
+ return $options['lowercase'] ? mb_strtolower( $str, 'UTF-8' ) : $str;
1526
+ }
1527
 
1528
+ /**
1529
+ * Save a flag if the a post/page/cpt have [ninja_tables] shortcode
1530
+ *
1531
+ * @param int $post_id
1532
+ *
1533
+ * @return void
1534
+ */
1535
+ public function saveNinjaTableFlagOnShortCode( $post_id ) {
1536
+ if ( isset( $_POST['post_content'] ) ) {
1537
+ $post_content = $_POST['post_content'];
1538
+ } else {
1539
+ $post = get_post( $post_id );
1540
+ $post_content = $post->post_content;
1541
+ }
1542
+ if ( has_shortcode( $post_content, 'ninja_tables' ) ) {
1543
+ update_post_meta( $post_id, '_has_ninja_tables', 1 );
1544
+ } elseif ( get_post_meta( $post_id, '_has_ninja_tables', true ) ) {
1545
+ update_post_meta( $post_id, '_has_ninja_tables', 0 );
1546
+ }
1547
+ }
1548
 
1549
+ public function duplicateTable() {
1550
+ $oldPostId = intval( $_REQUEST['tableId'] );
1551
 
1552
+ $post = get_post( $oldPostId );
1553
 
1554
+ // Duplicate table itself.
1555
+ $attributes = array(
1556
+ 'post_title' => $post->post_title . '( Duplicate )',
1557
+ 'post_content' => $post->post_content,
1558
+ 'post_type' => $post->post_type,
1559
+ 'post_status' => 'publish'
1560
+ );
1561
 
1562
+ $newPostId = wp_insert_post( $attributes );
 
1563
 
1564
+ global $wpdb;
1565
 
1566
+ // Duplicate table settings.
1567
+ $postMetaTable = $wpdb->prefix . 'postmeta';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1568
 
1569
+ $sql = "INSERT INTO $postMetaTable (`post_id`, `meta_key`, `meta_value`)";
1570
+ $sql .= " SELECT $newPostId, `meta_key`, `meta_value` FROM $postMetaTable WHERE `post_id` = $oldPostId";
1571
+
1572
+ $wpdb->query( $sql );
1573
+
1574
+ // Duplicate table rows.
1575
+ $itemsTable = $wpdb->prefix . ninja_tables_db_table_name();
1576
+
1577
+ $sql = "INSERT INTO $itemsTable (`position`, `table_id`, `attribute`, `value`, `created_at`, `updated_at`)";
1578
+ $sql .= " SELECT `position`, $newPostId, `attribute`, `value`, `created_at`, `updated_at` FROM $itemsTable";
1579
+ $sql .= " WHERE `table_id` = $oldPostId";
1580
+
1581
+ $wpdb->query( $sql );
1582
+
1583
+ wp_send_json_success( array(
1584
+ 'message' => __( 'Successfully duplicated table.', 'ninja-tables' ),
1585
+ 'table_id' => $newPostId
1586
+ ), 200 );
1587
+ }
1588
+
1589
+
1590
+ public function getAccessRoles() {
1591
+ $roles = get_editable_roles();
1592
+ $formatted = array();
1593
+ $excludedRoles = array( 'subscriber', 'administrator' );
1594
+ foreach ( $roles as $key => $role ) {
1595
+ if ( ! in_array( $key, $excludedRoles ) ) {
1596
+ $formatted[] = array(
1597
+ 'name' => $role['name'],
1598
+ 'key' => $key
1599
+ );
1600
+ }
1601
+ }
1602
+
1603
+ $capability = get_option( '_ninja_tables_permission' );
1604
+
1605
+ if ( is_string( $capability ) ) {
1606
+ $capability = [];
1607
+ }
1608
+
1609
+ wp_send_json( array(
1610
+ 'capability' => $capability,
1611
+ 'roles' => $formatted
1612
+ ), 200 );
1613
+ }
1614
+
1615
+ public function getTablePreviewHtml() {
1616
+ // sleep(3);
1617
+ $tableId = intval( $_REQUEST['table_id'] );
1618
+ $tableColumns = ninja_table_get_table_columns( $tableId, 'public' );
1619
+ $tableSettings = ninja_table_get_table_settings( $tableId, 'public' );
1620
+
1621
+ $formattedColumns = [];
1622
+ foreach ( $tableColumns as $index => $column ) {
1623
+ $formattedColumns[] = NinjaFooTable::getFormattedColumn( $column, $index, $tableSettings, true,
1624
+ 'by_created_at' );
1625
+ }
1626
+ $formatted_data = ninjaTablesGetTablesDataByID( $tableId, $tableSettings['default_sorting'], true, 25 );
1627
+ echo self::loadView( 'public/views/table_inner_html', array(
1628
+ 'table_columns' => $formattedColumns,
1629
+ 'table_rows' => $formatted_data
1630
+ ) );
1631
+ }
1632
 
1633
  private static function loadView( $file, $data ) {
1634
  $file = NINJA_TABLES_DIR_PATH . $file . '.php';
1638
 
1639
  return ob_get_clean();
1640
  }
1641
+
1642
+ public function migrateDatabaseIfNeeded() {
1643
+ // If the database is already migrated for manual
1644
+ // sorting the option table would have a flag.
1645
+ $option = '_ninja_tables_sorting_migration';
1646
+ global $wpdb;
1647
+ $tableName = $wpdb->prefix.ninja_tables_db_table_name();
1648
+
1649
+ $row = $wpdb->get_row( "SELECT * FROM $tableName" );
1650
+
1651
+ if(!$row) {
1652
+ return;
1653
+ }
1654
+ if(property_exists($row, 'position')) {
1655
+ return;
1656
+ }
1657
+
1658
+ // Update the databse to hold the sorting position number.
1659
+ $sql = "ALTER TABLE $tableName ADD COLUMN `position` INT(11) AFTER `id`;";
1660
+
1661
+ $wpdb->query( $sql );
1662
+ // Keep a flag on the options table that the
1663
+ // db is migrated to use for manual sorting.
1664
+ add_option( $option, true );
1665
+ }
1666
  }
assets/js/{ninja-tables-footable.2.1.js → ninja-tables-footable.2.3.js} RENAMED
File without changes
assets/mix-manifest.json CHANGED
@@ -3,6 +3,6 @@
3
  "/css/ninjatables-public.css": "/css/ninjatables-public.css",
4
  "/css/ninja-tables-admin.css": "/css/ninja-tables-admin.css",
5
  "/css/ninja-tables-vendor.css": "/css/ninja-tables-vendor.css",
6
- "/js/ninja-tables-footable.2.1.js": "/js/ninja-tables-footable.2.1.js",
7
  "/js/ninja-table-tinymce-button.js": "/js/ninja-table-tinymce-button.js"
8
  }
3
  "/css/ninjatables-public.css": "/css/ninjatables-public.css",
4
  "/css/ninja-tables-admin.css": "/css/ninja-tables-admin.css",
5
  "/css/ninja-tables-vendor.css": "/css/ninja-tables-vendor.css",
6
+ "/js/ninja-tables-footable.2.3.js": "/js/ninja-tables-footable.2.3.js",
7
  "/js/ninja-table-tinymce-button.js": "/js/ninja-table-tinymce-button.js"
8
  }
includes/libs/TableDrivers/NinjaFooTable.php CHANGED
@@ -127,8 +127,55 @@ class NinjaFooTable {
127
  $customCss = array();
128
 
129
  foreach ( $columns as $index => $column ) {
130
- $formatted_column = static::getFormattedColumn( $column, $index, $settings, $globalSorting,
131
- $sortingType );
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
132
  $formatted_columns[] = apply_filters( 'ninja_table_column_attributes', $formatted_column, $column,
133
  $table_id, $tableArray );
134
  }
@@ -215,7 +262,7 @@ class NinjaFooTable {
215
  'render_type' => $renderType,
216
  'custom_css' => $customCss
217
  );
218
-
219
  self::addInlineVars( json_encode( $table_vars, true ), $table_id );
220
  $foo_table_attributes = self::getFootableAtrributes( $table_id );
221
  include 'views/ninja_foo_table.php';
@@ -359,13 +406,19 @@ class NinjaFooTable {
359
  add_action( 'wp_footer', function () use ( $vars, $table_id ) {
360
  ?>
361
  <script type="text/javascript">
 
 
 
 
362
  // The config storage should be an array since there
363
  // could be more than one shortcode for a table.
364
  var key = "ninja_footables_tables_<?php echo $table_id;?>";
365
  if (key in window) {
366
- window[key].push(<?php echo $vars ?>);
367
  } else {
368
- window[key] = [<?php echo $vars ?>];
 
 
369
  }
370
  </script>
371
  <?php
127
  $customCss = array();
128
 
129
  foreach ( $columns as $index => $column ) {
130
+
131
+ $columnType = self::getColumnType( $column );
132
+ $cssColumnName = 'ninja_column_' . $index;
133
+ $columnClasses = array( $cssColumnName );
134
+ if ( isset( $column['classes'] ) ) {
135
+ $userClasses = explode( ' ', $column['classes'] );
136
+ $columnClasses = array_unique( array_merge( $columnClasses, $userClasses ) );
137
+ }
138
+ $customCss[ $cssColumnName ] = array();
139
+ if ( $columnWidth = ArrayHelper::get( $column, 'width' ) ) {
140
+ $customCss[ $cssColumnName ]['width'] = $columnWidth . 'px';
141
+ }
142
+ if ( $textAlign = ArrayHelper::get( $column, 'textAlign' ) ) {
143
+ $customCss[ $cssColumnName ]['textAlign'] = $textAlign;
144
+ }
145
+ $columnTitle = $column['name'];
146
+ if ( ArrayHelper::get( $column, 'enable_html_content' ) == 'true' ) {
147
+ if ( $columnContent = ArrayHelper::get( $column, 'header_html_content' ) ) {
148
+ $columnTitle = do_shortcode( $columnContent );
149
+ }
150
+ }
151
+
152
+ $formatted_column = array(
153
+ 'name' => $column['key'],
154
+ 'title' => $columnTitle,
155
+ 'breakpoints' => $column['breakpoints'],
156
+ 'type' => $columnType,
157
+ 'sortable' => $globalSorting,
158
+ 'visible' => ( $column['breakpoints'] == 'hidden' ) ? false : true,
159
+ 'classes' => $columnClasses,
160
+ 'filterable' => ( isset( $column['unfilterable'] ) && $column['unfilterable'] == 'yes' ) ? false : true
161
+ );
162
+
163
+ if ( $columnType == 'date' ) {
164
+ wp_enqueue_script(
165
+ 'moment',
166
+ NINJA_TABLES_DIR_URL . "public/libs/moment/moment.min.js",
167
+ [],
168
+ '2.22.0',
169
+ true
170
+ );
171
+ $formatted_column['formatString'] = $column['dateFormat'] ?: 'MM/DD/YYYY';
172
+ }
173
+
174
+ if ( $sortingType == 'by_column' && $column['key'] == $settings['sorting_column'] ) {
175
+ $formatted_column['sorted'] = true;
176
+ $formatted_column['direction'] = $settings['sorting_column_by'];
177
+ }
178
+
179
  $formatted_columns[] = apply_filters( 'ninja_table_column_attributes', $formatted_column, $column,
180
  $table_id, $tableArray );
181
  }
262
  'render_type' => $renderType,
263
  'custom_css' => $customCss
264
  );
265
+
266
  self::addInlineVars( json_encode( $table_vars, true ), $table_id );
267
  $foo_table_attributes = self::getFootableAtrributes( $table_id );
268
  include 'views/ninja_foo_table.php';
406
  add_action( 'wp_footer', function () use ( $vars, $table_id ) {
407
  ?>
408
  <script type="text/javascript">
409
+ // The order of table shortcode given is important to render
410
+ // the tables. So, we'll calculate the proper position.
411
+ window['ninjaTablesPosition'] = 1 + (window['ninjaTablesPosition'] || 0);
412
+
413
  // The config storage should be an array since there
414
  // could be more than one shortcode for a table.
415
  var key = "ninja_footables_tables_<?php echo $table_id;?>";
416
  if (key in window) {
417
+ window[key][window['ninjaTablesPosition'] - 1] = <?php echo $vars ?>;
418
  } else {
419
+ window[key] = {
420
+ [window['ninjaTablesPosition'] - 1] : <?php echo $vars ?>
421
+ };
422
  }
423
  </script>
424
  <?php
ninja-tables.php CHANGED
@@ -15,7 +15,7 @@
15
  * Plugin Name: Ninja Tables
16
  * Plugin URI: https://wpmanageninja.com/ninja-tables/
17
  * Description: The Easiest & Fastest Responsive Table Plugin on WordPress. Multiple templates, drag-&-drop live table builder, multiple color scheme, and styles.
18
- * Version: 2.2.6
19
  * Author: WPManageNinja
20
  * Author URI: https://wpmanageninja.com/
21
  * License: GPL-2.0+
@@ -32,8 +32,8 @@ if (!defined('WPINC')) {
32
  define('NINJA_TABLES_DIR_URL', plugin_dir_url(__FILE__));
33
  define('NINJA_TABLES_DIR_PATH', plugin_dir_path(__FILE__));
34
  define('NINJA_TABLES_PUBLIC_DIR_URL', NINJA_TABLES_DIR_URL.'public/');
35
- define('NINJA_TABLES_VERSION', '2.2.6');
36
- define('NINJA_TABLES_ASSET_VERSION', '2.1');
37
 
38
  /**
39
  * The code that runs during plugin activation.
15
  * Plugin Name: Ninja Tables
16
  * Plugin URI: https://wpmanageninja.com/ninja-tables/
17
  * Description: The Easiest & Fastest Responsive Table Plugin on WordPress. Multiple templates, drag-&-drop live table builder, multiple color scheme, and styles.
18
+ * Version: 2.3.0
19
  * Author: WPManageNinja
20
  * Author URI: https://wpmanageninja.com/
21
  * License: GPL-2.0+
32
  define('NINJA_TABLES_DIR_URL', plugin_dir_url(__FILE__));
33
  define('NINJA_TABLES_DIR_PATH', plugin_dir_path(__FILE__));
34
  define('NINJA_TABLES_PUBLIC_DIR_URL', NINJA_TABLES_DIR_URL.'public/');
35
+ define('NINJA_TABLES_VERSION', '2.3.0');
36
+ define('NINJA_TABLES_ASSET_VERSION', '2.3');
37
 
38
  /**
39
  * The code that runs during plugin activation.
readme.txt CHANGED
@@ -1,11 +1,11 @@
1
  === Ninja Tables - Best Responsive Table Plugin for WordPress ===
2
  Contributors: techjewel, adreastrian
3
  Donate link: https://wpmanageninja.com/downloads/ninja-tables-pro-add-on/
4
- Tags: table, WordPress tables Plugin, wp tables, data tables, datatables plugin, tables plugin, tables from csv, responsive tables
5
  Requires at least: 4.5
6
  Requires PHP: 5.4 or greater
7
  Tested up to: 4.9.7
8
- Stable tag: 2.2.6
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
@@ -154,7 +154,13 @@ Yes, For that please check pro add one <a href="https://wpmanageninja.com/downlo
154
 
155
  == Changelog ==
156
 
157
- = 2.3.0 ( Date: August 01, 2018 )
 
 
 
 
 
 
158
  * It's a big update with lots of improvement
159
  * Added Design studio for table to colorize tables visually. Now you can change settings and see instance preview
160
  * Re-Arrange Table Config Components to make things easier.
@@ -165,12 +171,6 @@ Yes, For that please check pro add one <a href="https://wpmanageninja.com/downlo
165
  * Added Permission for User Role based. You can assign custom role now.
166
  * Fix few css bug for table cell text wrap issues ( Thanks to our users to report it )
167
 
168
- = 2.2.6 ( Date: June 10, 2018 )
169
- * Added Duplicate table feature ( Most wanted feature by our users )
170
- * Added CSS Box into the table editor, Now you can paste your css for a table.
171
- * Added feature to re-arrange the rows.
172
- * Now, You can add table row at the first / at the last / you can sort manually.
173
- * Overall Performance improvements
174
 
175
  = 2.1.1 ( Date: April 28, 2018 ) =
176
  * Fix Table sorting for HTML Elements
1
  === Ninja Tables - Best Responsive Table Plugin for WordPress ===
2
  Contributors: techjewel, adreastrian
3
  Donate link: https://wpmanageninja.com/downloads/ninja-tables-pro-add-on/
4
+ Tags: table, WordPress tables Plugin, wp tables, data tables, datatables plugin, tables plugin, responsive tables
5
  Requires at least: 4.5
6
  Requires PHP: 5.4 or greater
7
  Tested up to: 4.9.7
8
+ Stable tag: 2.3.0
9
  License: GPLv2 or later
10
  License URI: http://www.gnu.org/licenses/gpl-2.0.html
11
 
154
 
155
  == Changelog ==
156
 
157
+ = 2.3.0 ( Date: August 02, 2018 )
158
+ * Fixed bug for rendering multiple table in a single page
159
+ * Fix bug for column width and header text alignment
160
+ * Fix bug for table not rendering issue
161
+
162
+
163
+ = 2.2.6 ( Date: August 01, 2018 )
164
  * It's a big update with lots of improvement
165
  * Added Design studio for table to colorize tables visually. Now you can change settings and see instance preview
166
  * Re-Arrange Table Config Components to make things easier.
171
  * Added Permission for User Role based. You can assign custom role now.
172
  * Fix few css bug for table cell text wrap issues ( Thanks to our users to report it )
173
 
 
 
 
 
 
 
174
 
175
  = 2.1.1 ( Date: April 28, 2018 ) =
176
  * Fix Table sorting for HTML Elements