How to write Some Data in CSV file in Magento? - magento

I am trying print some shipment details as a CSV file and I am almost done in implementing this but it does not gives the the option for downloading.It automatically create the file and save it in the directory mentioned.
I think I am missing _prepareDownloadResponse() function but how do I implement this.
I am using this code ->
$file_path = 'sample_shipment.csv';
$mage_csv = new Varien_File_Csv();
$mage_csv->saveData($file_path, $content);
Edit:
All this code is in my indexcontroller.php
full code in indexcontroller.php ->
class Company_Manifestupload_IndexController extends Mage_Adminhtml_Controller_Action
{
public function indexAction() {
echo 'Manifestupload Index!';
}
public function bluedartmanifestuploadAction() {
$request = $this->getRequest();
$shipmentIds = $request->getPost('shipment_ids', array());
$file_path = 'manifest_upload_'.Mage::getSingleton('core/date')->date('d-m-Y_H-i-s').'_csv.csv';
$mage_csv = new Varien_File_Csv();
$shipment_csv=array();
/* Putting data in $shipment_csv[] */
$mage_csv->saveData($file_path, $shipment_csv);
}

In order to make the csv file downloadable, just put the following code inside the related controller action:
$fileName = 'filename.csv';
$content = $csvData; //prepare the csv data and return as string
$this->_prepareDownloadResponse($fileName, $content); //this will make the csv file downloadable with the $content as contents in it.
Hope this helps.
Edit:
Please find the updated controller action code.
public function bluedartmanifestuploadAction() {
$request = $this->getRequest();
$shipmentIds = $request->getPost('shipment_ids', array());
$fileName = 'manifest_upload_'.Mage::getSingleton('core/date')->date('d-m-Y_H-i-s').'_csv.csv';
//prepare csv contents
#prepare header
$csv = '';
$_columns = array(
"field1",
"field2",
//...
);
$data = array();
foreach ($_columns as $column) {
$data[] = '"'.$column.'"';
}
$csv .= implode(',', $data)."\n";
#prepare data
foreach($dataFromShipmentIds as $_data){ //just dummy loop
$data = array();
$data[] = $_data['field1'];
$data[] = $_data['field2'];
//...
$csv .= implode(',', $data)."\n";
}
//now $csv varaible has csv data as string
$this->_prepareDownloadResponse($fileName, $csv);
}
Edit 2: The above code will only work properly in ideal case.It will not generate proper Csv when there "\n"s and ","s in the fields .To make it work properly one can use code from varien file CSV .I'll add it here-
First make array of values in $data[] as above then instead of using $csv.=implode(',',$data)."\n" use the below code.
foreach ($data as $value) {
if (strpos($value, $delimiter) != false ||
strpos($value, $enclosure) != false ||
strpos($value, "\n") != false ||
strpos($value, "\r") != false ||
strpos($value, "\t") != false ||
strpos($value, ' ') != false) {
$str2 = $enclosure;
$escaped = 0;
$len = strlen($value);
for ($i=0;$i<$len;$i++) {
if ($value[$i] == $escape_char) {
$escaped = 1;
} else if (!$escaped && $value[$i] == $enclosure) {
$str2 .= $enclosure;
} else {
$escaped = 0;
}
$str2 .= $value[$i];
}
$str2 .= $enclosure;
$str .= $str2.$delimiter;
} else {
$str .= $enclosure.$value.$enclosure.$delimiter;
}
}
$str = substr($str,0,-1);
$str .= "\n";

If you want to create downloadable csv of you ordered item's you can use following script.
$orders = Mage::getModel("sales/order")->getCollection();
// prepare CSV header
$csv = '';
$_columns = array(
"Order Id",
"Product Name",
"Sku",
"Price"
);
$data = array();
// prepare CSV header...
foreach ($_columns as $column) {
$data[] = '"'.$column.'"';
}
$csv .= implode(',', $data)."\n";
foreach ($orders as $order) {
$items = $order->getAllItems();
foreach ($items as $item) {
$loadProduct = Mage::getModel('catalog/product')->load($item->getProductId());
//prepare csv contents
$data = array();
$data[] = $order->getId();
$data[] = $loadProduct['name'];
$data[] = $loadProduct['sku'];
$data[] = $loadProduct['price'];
$csv .= implode(',', $data)."\n";
//now $csv varaible has csv data as string
}
}
$this->_redirect('*/*/');
$this->_prepareDownloadResponse('file.csv', $csv, 'text/csv');
For more info visit here

Related

How to skip blank rows in a csv file during import in Laravel

During the import of a CSV file, my import function creates a database record for every row of the import file. This means that if a user has left a blank row in the file then the import process creates a blank record in the database. How does one develop it so that the importer identifies blank/null rows in the CSV file, skips those blank/null rows, and only creates a record and imports a row if the row contains data?
Here is the Controller for the Import function:
public function process(Request $request)
{
$filename = $request->input('filename', false);
$path = storage_path('app/csv_import/'.$filename);
$hasHeader = $request->input('hasHeader', false);
$isAddingNewReligiousBackground = $request->input('is_adding_new_religious_background', false);
$fields = $request->input('fields', false);
$fields = array_flip(array_filter($fields));
$modelName = $request->input('modelName', false);
$model = 'App\\'.$modelName;
$reader = new SpreadsheetReader($path);
$insert = [];
$update = [];
$tags = [];
$team_id = $request->input('church_id');
$custom_fields = CustomField::where('created_by_team_id', $team_id)->get();
foreach ($reader as $key => $row) {
if ($hasHeader && $key == 0) {
continue;
}
$tmp = [];
$meta = [];
foreach ($fields as $header => $k) {
$tmp[$header] = $row[$k];
}
$tmp['created_by_id'] = auth()->user()->id;
$tmp['created_by_team_id'] = $team_id;
$tmp['created_at'] = now();
if ($modelName == 'Interest') {
$this->translateReligiousBackgroud($tmp, $isAddingNewReligiousBackground);
$meta = $this->processInterestMeta($tmp, $custom_fields);
$existing = Interest::matchingInterest((object) $tmp, $request->input('church_id'));
if ($existing) {
$update[] = $existing;
$tagsArr = array_filter((array) $request->input('interest_tags'));
foreach (\DB::table('interest_tag')->where('interest_id', $existing->id)->get() as $tag) {
$tagsArr[] = $tag->tag_id;
}
$existing->interest_tags()->sync(array_filter($tagsArr));
if (! empty($meta)) {
$existing->syncMeta($meta);
}
} else {
$tmp['meta'] = $meta;
$insert[] = $tmp;
}
} else {
$insert[] = $tmp;
}
}
$for_insert = array_chunk($insert, 10000); // this was 100, but the chunking was causing the system to only import the first 100 records, even though the success message said it imported all of them - LW 1/25/2019
foreach ($for_insert as $insert_item) {
if ($modelName == 'Interest') {
foreach ($insert_item as $item) {
$interest = new $model;
foreach ($item as $field => $value) {
if ($field != 'meta') {
$interest->$field = $value;
}
}
$interest->created_by_id = auth()->user()->id;
$interest->created_by_team_id = $request->input('church_id');
$interest->save();
// For some reason, created_by_team_id was null on initial save, do it again
$interest->created_by_team_id = $request->input('church_id');
$interest->save();
// deal with tags
$interest->interest_tags()->sync(array_filter((array) $request->input('interest_tags')));
// deal with custom fields
if (! empty($item['meta'])) {
$interest->syncMeta($item['meta']);
}
}
} else {
$model::insert($insert_item);
}
}
$rows = count($insert);
$updates = count($update);
$table = Str::plural($modelName);
File::delete($path);
$redirect = $request->input('redirect', false);
return redirect()->to($redirect)->with('message', trans(($updates > 0 ? 'global.app_imported_rows_to_table_with_updates' : 'global.app_imported_rows_to_table'),
['rows' => $rows, 'updates' => $updates, 'table' => $table]
));
}
I do not believe this is the proper way and I hope someone comes along and gives the proper answer but this here is my dirty hack. In my dataset, I have a column for lastname and all the records to have any functional purpose must have a last name so I put an -if- statement if (!empty($interest['lastname'])) checking that the 'lastname' not be empty before save.
$for_insert = array_chunk($insert, 10000); // this was 100, but the chunking was causing the system to only import the first 100 records, even though the success message said it imported all of them - LW 1/25/2019
foreach ($for_insert as $insert_item) {
if ($modelName == 'Interest') {
foreach ($insert_item as $item) {
$interest = new $model;
foreach ($item as $field => $value) {
if ($field != 'meta') {
$interest->$field = $value;
}
}
$interest->created_by_id = auth()->user()->id;
$interest->created_by_team_id = $request->input('church_id');
if (!empty($interest['lastname']))
{
$interest->save();
}
// For some reason, created_by_team_id was null on initial save, do it again
$interest->created_by_team_id = $request->input('church_id');
if (!empty($interest['lastname']))
{
$interest->save();
}
So in this manner, the system goes through the process of importing all the rows in the csv whether they have data or not but it only saves those records that have a lastname value. This accomplishes what I need but I know there must be a cleaner way to do it.
I believe there should be a method of doing this in which a record should be skipped only if all the values in a row/record is empty. So if one value is in place it will insert and create an entry but if all the values in a row are empty it will skip entry. Hopefully, someone will come along sometime and provide that more eloquent solution.

Find the error that array_combine(): Both parameters should have an equal number of elements

I am importing CSV file to Laravel controller and insert data into two tables, but I got error-
array_combine() Both parameters should have an equal number of elements
function csvToArray ($filename = '', $delimiter = ',')
{
If (! file_exists ($filename) ||!is_readable($filename))
return false;
$header = null;
$data = array ();
if (($handle = fopen ($filename,'r')) !== false)
{
while (($row = fgetcsv($handle, 300000, $delimiter)) !== false)
{
if (!$header)
$header = $row;
else
$data[] = array_combine($header, $row);
}
fclose($handle);
}
return $data;
}
public function importCsv()
{
$file = public_path('file/city_master.csv');
$customerArr_data = $this->csvToArray($file);
for ($i = 0; $i < count($customerArr_data); $i++)
{
dd($customerArr_data);
}
return 'not in array';
}
Please try using array_merge() instead. Hope this helps

Getting Error when converting array to a variable in laravel

I have problem when converting multiple checkbox($request->courses) to a variable(checkbox1).Because I need to insert an array to Database.
public function store(Request $request) {
$customer = new prospect;
$customer->ProspectName = $request->ProspectName;
$customer->NicNumber = $request->NicNumber;
$customer->ContactNumber = $request->ContactNumber;
$customer->ContactAddress = $request->ContactAddress;
$customer->Comments = $request->Comments;
$customer->ReferredThrough = $request->ReferredThrough;
$checkbox1 = $request->courses; //courses is an array from form
$chk = "";
foreach ($checkbox1 as $chk1) {
$chk .= $chk1 . ",";
}
$customer->IntrestedCourses = $chk;
if ($customer->save()) {
echo 'saved successfully';
} else {
echo 'error';
}
}
But I'm getting error!

DataBase Schema File (.sql file ) Download with laravel

Schenario :
1) suppose that i have a database called myDataBase
2) Assume that myDataBase have some tables like A,B,C,D
3) i have to download the schema of the table A,B from the database with name myDataBase
Hope you have done the migration of all the table of your project . If you are using a xampp server then goto http://localhost/phpmyadmin and select your database and then goto export tab on the top tab bar and simply export with go button
<?php
//ENTER THE RELEVANT INFO BELOW
$mysqlUserName = "root";
$mysqlPassword = "";
$mysqlHostName = "localhost";
$DbName = "ukkoteknik";
$backup_name = "mybackup.sql";
$tables = array("admin", "sample");
Export_Database($mysqlHostName,$mysqlUserName,$mysqlPassword,$DbName, $tables, $backup_name=false );
function Export_Database($host,$user,$pass,$name, $tables=false, $backup_name=false )
{
$mysqli = new mysqli($host,$user,$pass,$name);
$mysqli->select_db($name);
$mysqli->query("SET NAMES 'utf8'");
$queryTables = $mysqli->query('SHOW TABLES');
while($row = $queryTables->fetch_row())
{
$target_tables[] = $row[0];
}
if($tables !== false)
{
$target_tables = array_intersect( $target_tables, $tables);
}
foreach($target_tables as $table)
{
$result = $mysqli->query('SELECT * FROM '.$table);
$fields_amount = $result->field_count;
$rows_num=$mysqli->affected_rows;
$res = $mysqli->query('SHOW CREATE TABLE '.$table);
$TableMLine = $res->fetch_row();
$content = (!isset($content) ? '' : $content) . "\n\n".$TableMLine[1].";\n\n";
for ($i = 0, $st_counter = 0; $i < $fields_amount; $i++, $st_counter=0)
{
while($row = $result->fetch_row())
{ //when started (and every after 100 command cycle):
if ($st_counter%100 == 0 || $st_counter == 0 )
{
$content .= "\nINSERT INTO ".$table." VALUES";
}
$content .= "\n(";
for($j=0; $j<$fields_amount; $j++)
{
$row[$j] = str_replace("\n","\\n", addslashes($row[$j]) );
if (isset($row[$j]))
{
$content .= '"'.$row[$j].'"' ;
}
else
{
$content .= '""';
}
if ($j<($fields_amount-1))
{
$content.= ',';
}
}
$content .=")";
//every after 100 command cycle [or at last line] ....p.s. but should be inserted 1 cycle eariler
if ( (($st_counter+1)%100==0 && $st_counter!=0) || $st_counter+1==$rows_num)
{
$content .= ";";
}
else
{
$content .= ",";
}
$st_counter=$st_counter+1;
}
} $content .="\n\n\n";
}
//$backup_name = $backup_name ? $backup_name : $name."___(".date('H-i-s')."_".date('d-m-Y').")__rand".rand(1,11111111).".sql";
$date = date("Y-m-d");
$backup_name = $backup_name ? $backup_name : $name.".$date.sql";
header('Content-Type: application/octet-stream');
header("Content-Transfer-Encoding: Binary");
header("Content-disposition: attachment; filename=\"".$backup_name."\"");
//echo $content; exit;
}
?>

Magento export categories -> import with magmi

we need to change the categories of some products and it is easier for us to do this with a csv file.
Is there a way to export the categories in magmi format?
sku,categories
"abc","cat1/cat2;;cat5/cat6/cat1"
"bgb","cat1/cat2"
or is there maybe a small tool to manage the products in categories?
Edit:
this is the current code which is displaying the category names.
But I am trying to display the category path like this:
FirstCat/Tools/Screwdriver
But it is displaying like this:
FirstCat/Screwdriver/Tools
so the categoryid is not sorted.
<?php
error_reporting(E_ALL | E_STRICT);
define('MAGENTO_ROOT', getcwd());
$mageFilename = MAGENTO_ROOT . '/app/Mage.php';
require_once $mageFilename;
Mage::setIsDeveloperMode(true);
ini_set('display_errors', 1);
Mage::app();
$products = Mage::getModel("catalog/product")->getCollection();
$products->addAttributeToSelect('category_ids');
$products->addAttributeToSelect('sku');
$products->addAttributeToFilter('status', 1);//optional for only enabled products
$products->addAttributeToFilter('visibility', 4);//optional for products only visible in catalog and search
$fp = fopen('exports.csv', 'w');
$csvHeader = array("sku", "category_ids");
fputcsv( $fp, $csvHeader,",");
foreach ($products as $product){
$sku = $product->getSku();
$i = 2;
$len = count($product->getCategoryIds());
$str = "";
foreach ($product->getCategoryIds() as $id){
$category = Mage::getModel('catalog/category')->load($id);
$name = $category->getName();
$str .= $name;
if($i <= $len) {
$str = $str .= "/";
}
$i++;
}
fputcsv($fp, array($sku, $str), ",");
}
fclose($fp);
I use this code to export out categories. You can try to run it, don't forget to modify your path to your mage/app.php:
<?php
require_once('../yourpath/app/Mage.php');
Mage::app('admin');
Mage::app()->getStore()->setId(Mage_Core_Model_App::ADMIN_STORE_ID);
Mage::register("isSecureArea", true);
function saveData($file, $data) {
$fh = fopen($file, 'w');
foreach ($data as $dataRow) {
fputcsva($fh, $dataRow);
}
fclose($fh);
return $this;
}
function fputcsva(&$handle, $fields = array(), $delimiter = ',', $enclosure = '"') {
$str = '';
$escape_char = '\\';
foreach ($fields as $value) {
if (strpos($value, $delimiter) !== false ||
strpos($value, $enclosure) !== false ||
strpos($value, "\n") !== false ||
strpos($value, "\r") !== false ||
strpos($value, "\t") !== false ||
strpos($value, ' ') !== false) {
$str2 = $enclosure;
$escaped = 0;
$len = strlen($value);
for ($i = 0; $i < $len; $i++) {
if ($value[$i] == $escape_char) {
$escaped = 1;
} else if (!$escaped && $value[$i] == $enclosure) {
$str2 .= $enclosure;
} else {
$escaped = 0;
}
$str2 .= $value[$i];
}
$str2 .= $enclosure;
$str .= $str2 . $delimiter;
} else {
if (strlen($value)):
$str .= $enclosure . $value . $enclosure . $delimiter;
else:
$str .= $value . $delimiter;
endif;
}
}
$str = substr($str, 0, -1);
$str .= "\n";
return fwrite($handle, $str);
}
function geturl($connect, $value){
$id= $value;
if ($id) {
$sql = "SELECT value FROM magento.catalog_category_entity_url_key where entity_id=$id;";
$result = $connect->query($sql)->fetchObject();
} else {
return "";
}
return $result->value;
}
$modifiedarray = array();
$configpricearray=array();
$coreResource = Mage::getSingleton('core/resource');
$connect = $coreResource->getConnection('core_write');
$sql = "SELECT entity_id FROM catalog_category_entity;";
$category_row = $connect->query($sql);
$i=1;
$problematiccats=array(394,395,397,398);
$problematiccolumn=array('path','parent_id','level', 'position');
while ($row = $category_row->fetch()) {
$catid=$row['entity_id'];
echo "Category id: ".$catid.PHP_EOL;
if (in_array($catid,$problematiccats)): continue; endif;
$catsql="SELECT
ce.entity_id,
ce.parent_id,
ce.path,
ce.level,
ce.position,
ce.children_count,
ea.attribute_id,
ea.attribute_code,
CASE ea.backend_type
WHEN 'varchar' THEN ce_varchar.value
WHEN 'int' THEN IFNULL (eav_option.value,ce_int.value)
WHEN 'text' THEN ce_text.value
WHEN 'decimal' THEN ce_decimal.value
WHEN 'datetime' THEN ce_datetime.value
ELSE ea.backend_type
END AS value,
ea.is_required AS required
FROM catalog_category_entity AS ce
LEFT JOIN eav_attribute AS ea
ON ce.entity_type_id = ea.entity_type_id
LEFT JOIN catalog_category_entity_varchar AS ce_varchar
ON ce.entity_id = ce_varchar.entity_id
AND ea.attribute_id = ce_varchar.attribute_id
AND ea.backend_type = 'varchar'
AND ce_varchar.store_id = 0
LEFT JOIN catalog_category_entity_int AS ce_int
ON ce.entity_id = ce_int.entity_id
AND ea.attribute_id = ce_int.attribute_id
AND ea.backend_type = 'int'
AND ce_int.store_id = 0
LEFT JOIN catalog_category_entity_text AS ce_text
ON ce.entity_id = ce_text.entity_id
AND ea.attribute_id = ce_text.attribute_id
AND ea.backend_type = 'text'
AND ce_text.store_id = 0
LEFT JOIN catalog_category_entity_decimal AS ce_decimal
ON ce.entity_id = ce_decimal.entity_id
AND ea.attribute_id = ce_decimal.attribute_id
AND ea.backend_type = 'decimal'
AND ce_decimal.store_id = 0
LEFT JOIN catalog_category_entity_datetime AS ce_datetime
ON ce.entity_id = ce_datetime.entity_id
AND ea.attribute_id = ce_datetime.attribute_id
AND ea.backend_type = 'datetime'
LEFT JOIN eav_attribute_option_value as eav_option
ON eav_option.option_id=ce_int.value
AND eav_option.store_id=0
WHERE ce.entity_id = '$catid';";
$category_info = $connect->query($catsql);
$csvrow=array();
if ($i==1): $csvrow['entity']='entity_id';$csvrow['parent']='parent_id'; $csvrow['path']='path';
$csvrow['level']='level';
$csvrow['position']='position';
$csvrow['children_count']='children_count';endif;
while ($catrow = $category_info->fetch()) {
if (in_array($catrow['attribute_code'],$problematiccolumn)): continue; endif;
if ($i==1):
$csvrow[]=$catrow['attribute_code'];
else:
$csvrow['entity']=$catrow['entity_id'];
$csvrow['parent']=$catrow['parent_id'];
$csvrow['path']=$catrow['path'];
$csvrow['level']=$catrow['level'];
$csvrow['position']=$catrow['position'];
$csvrow['children_count']=$catrow['children_count'];
$csvrow[$catrow['attribute_code']]=($catrow['value']?$catrow['value']:"");
if ($catrow['attribute_code']=="url_key"):
if (strlen($catrow['url_key'])<3):
$csvrow['url_key']=geturl($connect,$catid);
endif;
endif;
endif;
}
$csv[]=$csvrow;
$i++;
}
$file_path = 'categoryexport.csv';
try {
saveData($file_path, $csv);
} catch (Exception $e) {
echo "[ERROR] Creating sale report file: " . $e->getMessage() . PHP_EOL;
}
In this solution the db was'n in very well state, so the url needs to grabbed separately, you can remove that part if not necessary for you.
I used this on EE 1.13.0.2
You can run it from the shell.
Now here is my solution. Its displaying the csv in the browser. After that you can reimport with magmi
<?php
error_reporting(E_ALL | E_STRICT);
define('MAGENTO_ROOT', getcwd());
$mageFilename = MAGENTO_ROOT . '/app/Mage.php';
require_once $mageFilename;
Mage::setIsDeveloperMode(true);
ini_set('display_errors', 1);
Mage::app();
$products = Mage::getModel("catalog/product")->getCollection();
$products->addAttributeToSelect('category_ids');
$products->addAttributeToSelect('sku');
$products->addAttributeToFilter('status', 1);//optional for only enabled products
$products->addAttributeToFilter('visibility', 4);//optional for products only visible in catalog and search
foreach ($products as $product){
$sku = $product->getSku();
echo $sku.",";
$i = 2;
$anzahl = count($product->getCategoryIds());
foreach ($product->getCategoryIds() as $id){
$category = Mage::getModel('catalog/category')->load($id);
$path = $category->getPath();
$ids = explode("/", $path);
$name = "";
$i2 = 2;
$anzahl2 = count($ids);
foreach($ids as $id_2) {
$category = Mage::getModel('catalog/category')->load($id_2);
$name .= $category->getName();
echo $category->getName();
if($i2 <= $anzahl2) {
$name .= "/";
echo "/";
}
$i2++;
}
if($i <= $anzahl) {
$name .= ";;";
echo ";;";
}
$i++;
}
echo "<br />";
}

Resources