Currently, I'm working on the eMarketing project. There import CSV file which data like 200k. Now, previous developer fetch 10k data in every bacth and using SQL transaction and first create a temporary table and then import data in subscribers table check unique email and mail list id with joining the temporary table. Then remove temporary table.
But, now I want to import CSV file directly subscribers without the temporary table.And must be check unique email and mail list id. How can I do that? Anyone, please help me.
Here is my controller code. This project creates by laravel framework 5.4*
public function import2($file, $customer, $system_job)
{
try {
$processed_count = 0;
$logger = $system_job->getLogger();
$logger->info(trans('messages.Start_importing_for_list_uid', ['uid' => $this->uid]));
// init the status
$system_job->updateStatus([
'status' => self::IMPORT_STATUS_RUNNING,
]);
// Read CSV files
list($headers, $availableFields, $lineCount, $results) = $this->readCsv($file);
// validate headers, check for required fields
// throw an exception in case of error
$this->validateCsvHeader($availableFields);
// update status, line count
$system_job->updateStatus(['total' => $lineCount]);
// process by batches
each_batch($results, config('app.import_batch_size'), true, function ($batch) use ($logger, $availableFields, &$customer, &$processed_count, &$system_job) {
// increment count
$processed_count += sizeof($batch);
// processing for every batch,
// using transaction to only commit at the end of the batch execution
DB::beginTransaction();
// create a temporary table containing the input subscribers
$tmpTable = table('__tmp_subscribers');
// @todo: hard-coded charset and COLLATE
$tmpFields = implode(',', array_map(function ($field) {
return "`{$field}` VARCHAR(255) CHARACTER SET utf8 COLLATE utf8_unicode_ci";
}, $availableFields));
DB::statement("DROP TABLE IF EXISTS {$tmpTable};
CREATE TABLE {$tmpTable}({$tmpFields});
CREATE INDEX _index_email_{$tmpTable} ON {$tmpTable}(`email`);");
// Insert subscriber fields from the batch to the temporary table
// extract only fields whose name matches TAG NAME of MailList
$data = collect($batch)->map(function ($r) use ($availableFields) {
$record = array_only($r, $availableFields);
if (!is_null($record['email'])) {
// replace the non-break space (not a normal space) as well as all other spaces
$record['email'] = strtolower(preg_replace('/[ \s*]*/', '', trim($record['email'])));
}
return $record;
})->toArray();
// make the import data table unique by email
$data = array_unique_by($data, function ($r) {
return $r['email'];
});
// validate amd remove invalid records
$data = array_where($data, function ($record) use ($logger) {
list($valid, $errors) = $this->validateCsvRecord($record);
if (!$valid) {
$logger->warning($record['email'].': '.implode(', ', $errors));
}
return $valid;
});
DB::table('__tmp_subscribers')->insert($data);
// Insert new subscribers from temp table to the main table
// Use SUBSTRING(MD5(UUID()), 1, 13) to produce a UNIQUE ID which is similar to the output of PHP uniqid()
DB::statement('INSERT INTO '.table('subscribers').'(uid, mail_list_id, email, status, subscription_type, created_at, updated_at)
SELECT SUBSTRING(MD5(UUID()), 1, 13), ' .$this->id.', uniq.email, '.db_quote(Subscriber::STATUS_SUBSCRIBED).', '.db_quote(Subscriber::SUBSCRIPTION_TYPE_IMPORTED).", NOW(), NOW()
FROM (SELECT tmp.email FROM {$tmpTable} tmp LEFT JOIN ".table('subscribers')." main ON (tmp.email = main.email AND main.mail_list_id = {$this->id}) WHERE main.email IS NULL) uniq");
// update status, finish one batch
$system_job->updateStatus(['processed' => $processed_count]);
// Cleanup
DB::statement("DROP TABLE IF EXISTS {$tmpTable};");
// Actually write to the database
DB::commit();
});
// Update status, finish all batches
$system_job->updateStatus(['status' => self::IMPORT_STATUS_DONE, 'total' => $processed_count]);
// Trigger updating related campaigns cache
$this->updateCachedInfo();
// blacklist new emails (if any)
Blacklist::doBlacklist($customer);
// Action Log
$this->log('import_success', $customer, ['count' => $processed_count, 'error' => '']);
$logger->info(trans('messages.Finish_importing_for_list_uid', ['uid' => $this->uid]));
} catch (\Exception $e) {
// finish the transaction
DB::rollBack();
$this->updateCachedInfo();
// update job status
$system_job->updateStatus([
'status' => self::IMPORT_STATUS_FAILED,
'error_message' => $e->getMessage(),
]);
// Action Log
$this->log('import_max_error', $customer, ['count' => $processed_count]);
// write to job's logger
$logger->error($e->getMessage());
}
}
from Newest questions tagged laravel-5 - Stack Overflow https://ift.tt/2StPpjo
via IFTTT
Aucun commentaire:
Enregistrer un commentaire