expense_tracker-1.2.1/src/Form/ImportDataForm.php
src/Form/ImportDataForm.php
<?php
namespace Drupal\expense_tracker\Form;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\RedirectCommand;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Symfony\Component\HttpFoundation;
use Drupal\Core\Url;
use Drupal\file\Entity\File;
use Drupal\Component\Serialization\Json;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Drupal\Core\Render\Markup;
use Drupal\expense_tracker\Plugin\ExcelReader;
class ImportDataForm extends FormBase {
/**
* Returns a unique string identifying the form.
*
* @return string
* The unique string identifying the form.
*/
public function getFormId() {
return 'import_data_form';
}
/**
* Form constructor.
*
* @param array $form
* An associative array containing the structure of the form.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* The current state of the form.
*
* @return array
* The form structure.
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$route_name = \Drupal::routeMatch()->getRouteName();
$fields = array();
$import_data_to = 'et_transaction';
$form = array(
'#attributes' => array('enctype' => 'multipart/form-data'),
);
$form['wrapper'] = array(
'#type' => 'fieldset',
'#title' => $this->t('Import Transactions'),
'#attributes' => [
'id' => 'free-trial-wrapper'
],
);
$validators = array(
'file_validate_extensions' => array('json xml csv xlsx'),
);
$form['wrapper']['update_content'] = [
'#id' => 'update_content',
'#type' => 'checkbox',
'#title' => $this->t('Update '.$import_data_to.' if already exists'),
'#default_value' => '',
'#description' => $this->t('Update '.$import_data_to.' if the author already exists on the system'),
'#access' => false
];
$form['wrapper']['import_file'] = array(
'#type' => 'managed_file',
'#name' => 'import_file',
'#title' => t('File *'),
'#size' => 20,
'#description' => t('Json, csv, xlsx and xml format only.'),
'#upload_validators' => $validators,
'#upload_location' => 'public://temp-lms-files/import-files/',
);
$form['wrapper']['download_samples'] = [
'#type' => 'details',
'#title' => t('Download sample files'),
'#id' => 'sample-details',
];
$modulePath = \Drupal::service('module_handler')->getModule('expense_tracker')->getPath();
global $base_root, $base_path;
$valid_formats = array('xlsx', 'json', 'csv', 'xml');
foreach ($valid_formats as $valid_format) {
$file_path = $base_root . $base_path .\Drupal::service('extension.list.module')->getPath('expense_tracker') . "/assets/sample-files/".$import_data_to.'.'.$valid_format;
$markup = "Download sample {$import_data_to} <em>{$valid_format}</em> file from <a href='".$file_path."' download>here </a><br/>";
$form['wrapper']['download_samples']['download'.$valid_format] = [
'#type' => 'markup',
'#markup' => t($markup),
];
}
$form['wrapper']['actions']['#type'] = 'actions';
$form['wrapper']['actions']['submit'] = array(
'#type' => 'submit',
'#value' => $this->t('Submit'),
'#button_type' => 'primary',
);
$form_state->set('import_data_to', $import_data_to);
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
if ($form_state->getValue('import_file') == NULL) {
$form_state->setErrorByName('import_file', $this->t('Please upload the file'));
}
}
/**
* Form submit handler
* @param array &$form
* @param FormStateInterface $form_state
* @return [type]
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$import_data_to = $form_state->get('import_data_to');
if($import_data_to) {
// get the checkbox value if content update checked
$update_content = $form_state->getValue('update_content');
$values = $form_state->getValues();
$form_file = $form_state->getValue('import_file', 0);
if (isset($form_file[0]) && !empty($form_file[0])) {
$file = File::load($form_file[0]);
// $file->setPermanent();
$file->save();
$full_path = $file->get('uri')->value;
$file_name = basename($full_path);
$file_extension = pathinfo($full_path, PATHINFO_EXTENSION);
$file_extension = strtolower($file_extension);
$file_id = $file->get('fid')->value;
$file_data = array();
if(!file_exists($full_path) || !is_readable($full_path)) {
$this->messenger()->addError($this->t('File could not be uploaded.'));
} else {
$file_data = call_user_func(array($this, 'get_'.$file_extension.'_import_data'), $full_path);
if(isset($file_data['error'])) {
$this->messenger()->addError($this->t('Error Response: '.$file_data['message']));
}
}
$data = array();
$insert_count = 0;
$batch = array(
'title' => t('Update Records batch operation under progress'),
'operations' => array(),
'finished' => 'et_batch_finished_callback',
'progress_message' => t('Update success @current out of @total records.'),
'init_message' => t('Record update is starting.'),
);
$is_valid = false;
if(!empty($file_data) && isset($file_data[0])) {
if($file_extension == 'xlsx') {
$array_keys = $file_data[0];
} else if($file_extension == 'xml') {
$array_keys = array_keys($file_data[0]);
} else {
$array_keys = array_keys($file_data[0]);
// $array_keys = array_values($file_data[0]);
}
$is_valid = $this->validate_import_data($array_keys, $import_data_to);
if($is_valid) {
$batch = et_mapped_data($file_data, $batch, $import_data_to, $file_extension, $update_content);
batch_set($batch);
}
}
if(!$is_valid) {
\Drupal::messenger()->addMessage($this->t('Please enter a valid file'), 'error');
}
} else {
\Drupal::messenger()->addMessage($this->t('There was an error uploading file.'), 'error');
return;
}
}
}
// @TODO this function will ultimately replace the entire form with a message telling the user that their submission was successful and to check their email for Lavu app credentials
public function replaceForm(array &$form, FormStateInterface $form_state) {
}
/**
* Validate if the import data
* @param [type] $data
* @param [type] $import_data_to
* @return [type]
*/
public function validate_import_data($data, $import_data_to) {
$valid = false;
switch ($import_data_to) {
case 'et_transaction':
$valid_fields = array(
"title",
"amount",
"date",
"type",
"note",
);
break;
}
if (array_diff($data,$valid_fields) == array_diff($valid_fields,$data)) {
$valid = true;
}
return $valid;
}
/**
* Read xml data from the file
* @param [type] $full_path
* @return [type]
*/
function get_xml_import_data($full_path) {
$return_data = array();
try {
$items = new \SimpleXMLElement($full_path, 0, true);
$json = json_encode($items);
$result_data = json_decode($json, true);
} catch (\Exception $e) {
$result_data = array(
'error' => true,
'message' => $e->getMessage()
);
}
if(isset($result_data['element'])) {
// $return_data = array_column($result_data['element'], 'element');
$return_data = $result_data['element'];
}
return $return_data;
}
/**
* Read jon data from the file
* @param [type] $full_path
* @return [type]
*/
function get_json_import_data($full_path) {
try {
$file_contents = file_get_contents($full_path);
$result_data = Json::decode($file_contents);
if(!$result_data) {
$result_data = array(
'error' => true,
'message' => 'Invalid json file.'
);
}
} catch (\Exception $e) {
$result_data = array(
'error' => true,
'message' => $e->getMessage()
);
}
return $result_data;
}
/**
* Read csv data from the file
* @param [type] $full_path
* @return [type]
*/
function get_csv_import_data($full_path) {
try {
$csvData = file_get_contents($full_path);
$delimiter =',';
$header = NULL;
$data = array();
if (($handle = fopen($full_path, 'r')) !== FALSE ) {
$cleared = false;
while (($row = fgetcsv($handle, 1000, $delimiter)) !== FALSE)
{
if(!$cleared) {
$row = array_map('clear_text_ettransaction', $row);
$cleared = true;
}
if(!$header){
$header = $row;
}else{
$header = array_map('trim', $header);
$data[] = array_combine($header, $row);
}
}
fclose($handle);
$result_data = $data;
}
if(empty($data)) {
$result_data = array(
'error' => true,
'message' => 'Invalid json file.'
);
}
} catch (\Exception $e) {
$result_data = array(
'error' => true,
'message' => $e->getMessage()
);
}
return $result_data;
}
/**
* Read csv data from the file
* @param [type] $full_path
* @return [type]
*/
function get_xlsx_import_data($full_path) {
try {
if ($xlsx = ExcelReader::parse($full_path)) {
$sheetsCount = $xlsx->sheetsCount();
$result_data = $xlsx->rows();
} else {
echo ExcelReader::parseError();
}
} catch (\Exception $e) {
$result_data = array(
'error' => true,
'message' => $e->getMessage()
);
}
return $result_data;
}
}