File: /home/honghock/www/wp-content/plugins/ninja-tables/app/Http/Controllers/ImportController.php
<?php
namespace NinjaTables\App\Http\Controllers;
use NinjaTables\App\App;
use NinjaTables\App\Traits\ImportTrait;
use NinjaTables\Database\Migrations\NinjaTablesSupsysticTableMigration;
use NinjaTables\Database\Migrations\NinjaTablesTablePressMigration;
use NinjaTables\Framework\Request\Request;
use NinjaTables\Framework\Support\Arr;
use NinjaTables\Framework\Support\Sanitizer;
use NinjaTables\App\Library\Csv\Reader;
use NinjaTables\App\Models\NinjaTableItem;
class ImportController extends Controller
{
use ImportTrait;
private $cpt_name = 'ninja-table';
private static $tableName = 'ninja_table_items';
public function tableBuilderImport(Request $request)
{
return $this->extracted($request->all());
}
public function defaultImport(Request $request)
{
$format = Sanitizer::sanitizeTextField(Arr::get($request->all(), 'format'));
$doUnicode = Sanitizer::sanitizeTextField(Arr::get($request->all(), 'do_unicode'));
if ($format == 'dragAndDrop') {
return $this->extracted($request->all());
} else {
if ( ! isset($_FILES['file'])) {
return $this->sendError([
'errors' => array(),
'message' => __('Please upload a file.', 'ninja-tables')
], 423);
}
$fileName = Sanitizer::sanitizeTextField(Arr::get($_FILES, 'file.name'));
$fileExtension = strtolower(pathinfo($fileName, PATHINFO_EXTENSION));
if ($fileExtension === 'csv' && $format == 'csv') {
$this->uploadTableCsv($doUnicode);
} elseif ($fileExtension === 'json' && $format == 'json') {
$this->uploadTableJson();
} elseif ($fileExtension === 'json' && $format == 'ninjaJson') {
$this->uploadTableNinjaJson();
}
$this->json([
'message' => __('No appropriate driver found for the import format.', 'ninja-tables')
], 423);
}
}
private function uploadTableCsv($doUnicode)
{
$mimes = array(
'text/csv',
'text/plain',
'application/csv',
'text/comma-separated-values',
'application/excel',
'application/vnd.ms-excel',
'application/vnd.msexcel',
'text/anytext',
'application/octet-stream',
'application/txt'
);
if ( ! in_array(Sanitizer::sanitizeTextField($_FILES['file']['type']), $mimes)) {
return $this->sendError([
'data' => [
'errors' => array(),
'message' => __('Please upload valid CSV', 'ninja-tables')
]
], 423);
}
$tmpName = Sanitizer::sanitizeTextField($_FILES['file']['tmp_name']);
$fileName = Sanitizer::sanitizeTextField($_FILES['file']['name']);
$data = file_get_contents($tmpName);
if ($doUnicode && $doUnicode == 'yes') {
$data = mb_convert_encoding($data, 'UTF-8', 'ISO-8859-1');
}
try {
$reader = Reader::createFromString($data)->fetchAll();
} catch (\Exception $exception) {
return $this->sendError([
'data' => [
'errors' => $exception->getMessage(),
'message' => __('Something is wrong when parsing the csv', 'ninja-tables')
]
], 423);
}
$header = array_shift($reader);
$tableId = $this->createTable(array(
'post_title' => $fileName,
'post_content' => '',
'post_type' => $this->cpt_name,
'post_status' => 'publish'
));
$header = ninja_table_format_header($header);
$this->storeTableConfigWhenImporting($tableId, $header);
ninjaTableInsertDataToTable($tableId, $reader, $header);
$this->json([
'message' => __('Successfully added a table.', 'ninja-tables'),
'tableId' => $tableId
], 200);
}
private function createTable($data = null)
{
return wp_insert_post(
$data
? $data
: array(
'post_title' => __('Temporary table name', 'ninja-tables'),
'post_content' => __(
'Temporary table description',
'ninja-tables'
),
'post_type' => $this->cpt_name,
'post_status' => 'publish'
)
);
}
private function storeTableConfigWhenImporting($tableId, $header)
{
$ninjaTableColumns = array();
foreach ($header as $key => $name) {
$ninjaTableColumns[] = array(
'key' => $key,
'name' => $name,
'breakpoints' => ''
);
}
update_post_meta($tableId, '_ninja_table_columns', $ninjaTableColumns);
$ninjaTableSettings = ninja_table_get_table_settings($tableId, 'admin');
update_post_meta($tableId, '_ninja_table_settings', $ninjaTableSettings);
ninjaTablesClearTableDataCache($tableId);
}
private function uploadTableJson()
{
$tableId = $this->createTable();
$tmpName = Sanitizer::sanitizeTextField($_FILES['file']['tmp_name']);
$content = json_decode(file_get_contents($tmpName), true);
$reverse_content = array_reverse($content);
$header = array_keys(array_pop($reverse_content));
$formattedHeader = array();
foreach ($header as $head) {
$formattedHeader[$head] = $head;
}
$this->storeTableConfigWhenImporting($tableId, $formattedHeader);
ninjaTableInsertDataToTable($tableId, $content, $formattedHeader);
$this->json([
'message' => __('Successfully added a table.', 'ninja-tables'),
'tableId' => $tableId
], 200);
}
private function uploadTableNinjaJson()
{
$tmpName = Sanitizer::sanitizeTextField($_FILES['file']['tmp_name']);
$parsedContent = file_get_contents($tmpName);
$content = json_decode($parsedContent, true);
if (json_last_error()) {
for ($i = 0; $i <= 31; ++$i) {
$parsedContent = str_replace(chr($i), "", $parsedContent);
}
$parsedContent = str_replace(chr(127), "", $parsedContent);
if (0 === strpos(bin2hex($parsedContent), 'efbbbf')) {
$parsedContent = substr($parsedContent, 3);
}
$content = json_decode($parsedContent, true);
}
// validation
if ( ! Arr::get($content, 'post') || ! Arr::get($content, 'columns') || ! Arr::get($content, 'settings')) {
$this->json([
'message' => __(
'Please upload a JSON file exported from Ninja Tables',
'ninja-tables'
)
], 423);
}
$tableAttributes = array(
'post_title' => Sanitizer::ksesPost($content['post']['post_title']),
'post_content' => wp_kses_post($content['post']['post_content']),
'post_type' => $this->cpt_name,
'post_status' => 'publish'
);
$tableId = $this->createTable($tableAttributes);
update_post_meta($tableId, '_ninja_table_columns', $content['columns']);
update_post_meta($tableId, '_ninja_table_settings', $content['settings']);
$metas = $content['metas'];
foreach ($metas as $meta_key => $meta_value) {
update_post_meta($tableId, $meta_key, $meta_value);
}
if ($rows = $content['rows']) {
$header = [];
foreach ($content['columns'] as $column) {
$header[$column['key']] = $column['name'];
}
ninjaTableInsertDataToTable($tableId, $rows, $header);
}
global $wpdb;
if (isset($content['original_rows']) && $originalRows = $content['original_rows']) {
foreach ($originalRows as $row) {
$row['table_id'] = $tableId;
$row['value'] = json_encode($row['value'], JSON_UNESCAPED_UNICODE);
$tableName = $wpdb->prefix . static::$tableName;
// $this->reset();
$wpdb->insert($tableName, $row, false);
}
}
$this->json([
'message' => __('Successfully added a table.', 'ninja-tables'),
'tableId' => $tableId
], 200);
}
public function getTablesFromOtherPlugin(Request $request)
{
$plugin = Sanitizer::sanitizeTextField(Arr::get($request->all(), 'plugin'));
if ($plugin == 'TablePress') {
$libraryClass = new NinjaTablesTablePressMigration();
} elseif ($plugin == 'supsystic') {
$libraryClass = new NinjaTablesSupsysticTableMigration();
} else {
return false;
}
$tables = $libraryClass->getTables();
$this->json([
'tables' => $tables
], 200);
}
public function importTableFromOtherPlugin(Request $request)
{
$plugin = Sanitizer::sanitizeTextField(Arr::get($request->all(), 'plugin'));
$tableId = intval(Arr::get($request->all(), 'tableId'));
if ($plugin == 'TablePress') {
$libraryClass = new NinjaTablesTablePressMigration();
} elseif ($plugin == 'supsystic') {
$libraryClass = new NinjaTablesSupsysticTableMigration();
} else {
return false;
}
$tableId = $libraryClass->migrateTable($tableId);
if (is_wp_error($tableId)) {
return $this->sendError([
'data' => [
'message' => 'Something Went Wrong When Migrating'
]
], 423);
}
$message = __(
'Successfully imported. Please go to all tables and review your newly imported table.',
'ninja-tables'
);
return $this->sendSuccess([
'data' => [
'message' => $message,
'tableId' => $tableId
]
], 200);
}
public function uploadCsvInExistingTable(Request $request)
{
global $wpdb;
$tableId = intval(Arr::get($request->all(), 'table_id'));
$tmpName = $_FILES['file']['tmp_name'];
$data = file_get_contents($tmpName);
if (Arr::get($request->all(), 'do_unicode') === 'yes') {
$data = mb_convert_encoding($data, 'UTF-8', 'ISO-8859-1');
}
try {
$reader = Reader::createFromString($data)->fetchAll();
} catch (\Exception $exception) {
return $this->sendError([
'data' => [
'errors' => $exception->getMessage(),
'message' => __('CSV File is not valid', 'ninja-tables')
]
], 423);
}
$csvHeader = array_shift($reader);
$csvHeader = array_map('esc_attr', $csvHeader);
$config = get_post_meta($tableId, '_ninja_table_columns', true);
if ( ! $config) {
return $this->json(array(
'message' => __('Please set table configuration first', 'ninja-tables')
), 423);
}
// Extract header keys to a plain array from the config.
$header = array_map(function ($item) {
return $item['key'];
}, $config);
// We are gonna allow to upload new data if the CSV
// has the same number of headers as the config.
if (count($header) != count($csvHeader)) {
return $this->sendError([
'data' => [
'message' => __('Please use the provided CSV header structure font face.', 'ninja-tables')
]
], 423);
}
$data = array();
$userId = get_current_user_id();
$timeStamp = time() - (count($reader) * 100);
foreach ($reader as $item) {
if (count($header) === count($item)) {
$itemTemp = array_combine($header, $item);
$itemTemp = ninja_tables_sanitize_array($itemTemp);
$data[] = array(
'table_id' => $tableId,
'attribute' => 'value',
'owner_id' => $userId,
'value' => json_encode($itemTemp, JSON_UNESCAPED_UNICODE),
'created_at' => date('Y-m-d H:i:s', $timeStamp),
'updated_at' => date('Y-m-d H:i:s')
);
} else {
error_log('Invalid data format in this row' . json_encode($item));
continue;
}
$timeStamp = $timeStamp + 100;
}
$replace = Arr::get($request->all(), 'replace') === 'true';
$app = App::getInstance();
$data = $app->applyFilters('ninja_tables_import_table_data', $data, $tableId);
if ($replace) {
NinjaTableItem::where('table_id', $tableId)->delete();
}
// We are gonna batch insert by small chunk so that we can avoid PHP
// memory issue or MYSQL max_allowed_packet issue for large data set.
$tableName = $wpdb->prefix . static::$tableName;
foreach (array_chunk($data, 3000) as $chunk) {
ninjtaTableBatchInsert($tableName, $chunk);
}
ninjaTablesClearTableDataCache($tableId);
return $this->json([
'data' => [
'message' => __('Successfully uploaded data.', 'ninja-tables')
]
]);
}
/**
* @param Request $request
*
* @return mixed
*/
public function extracted($data)
{
$fileName = 'Ninja-tables' . date('d-m-Y');
$url = sanitize_url(Arr::get($data, 'url', ''));
if ( ! empty($url)) {
$data = static::importFromURL($url);
} else {
$data = static::getData();
}
$data = ninja_tables_sanitize_array($data);
$tableId = $this->savedDragAndDropTable($data, $fileName);
return $this->sendSuccess([
'data' => [
'id' => $tableId
]
], 200);
}
}