a class to read and write CSV
Array
(
[0] => Array
(
[name] => Lorem
[number] => 11
)
[1] => Array
(
[name] => ipsum
[number] => 22
)
)
"name", "number"
"Lorem", 11
"ipsum", 22
<?php
/**
* This class is used in Orbisius Price Changer for WooCommerce
* This premium WooCommerce extension allows you to change product prices (up/down) for all products or for a selected category and its subcategories.
* You can review them before actually making the changes.
*
* @see http://club.orbisius.com/products/wordpress-plugins/woocommerce-extensions/orbisius-woocommerce-ext-price-changer/
* @author jaywilliams | myd3.com | https://gist.github.com/jaywilliams
* @author Svetoslav Marinov (SLAVI) | http://orbisius.com
*/
Class orbisius_woocommerce_ext_price_changer_csv {
protected $buff_size = 1024;
protected $delimiter = ',';
public function delimiter($delimiter = '') {
if (!empty($delimiter)) {
$this->delimiter = $delimiter;
}
return $this->delimiter;
}
/**
* Reads a CSV file and returns array of arrays.
* The header rows are not returned. We can extract them by getting the keys of the first array element.
* @link http://gist.github.com/385876
* @return array / false on error
*/
public function read($filename = '') {
if (!file_exists($filename) || !is_readable($filename)) {
trigger_error(sprintf("File [%s] doesn't exist or not readable.", esc_attr($filename)), E_USER_WARNING);
return false;
}
$data = array();
$header = array();
if (($handle = fopen($filename, 'rb')) !== false) {
// we just need a read lock
flock($handle, LOCK_SH);
while (($row = fgetcsv($handle, $this->buff_size, $this->delimiter)) !== false) {
// No header row OR if the data contains header row somewhere instead of data
if (empty($header) || count(array_diff($header, $row)) == 0) {
$header = $row;
} else {
$data[] = array_combine($header, $row);
}
}
flock($handle, LOCK_UN);
fclose($handle);
}
return $data;
/*
* Return value
array (
0 =>
array (
'product_title' => 'Bottle',
'parent_product_id' => '0',
'product_id' => '308',
'old_regular_price' => '1.00',
'new_regular_price' => '5',
'old_sale_price' => '1.00',
'new_sale_price' => '2.00',
'currency' => 'GBP',
'cur_user_id' => '20',
'cur_user_email' => 'user@email.com',
'cur_date' => '2014-06-09 10:59:37',
),
1 =>
array (
'product_title' => 'Bottles (Case)',
'parent_product_id' => '0',
'product_id' => '309',
'old_regular_price' => '100.00',
'new_regular_price' => '50.00',
'old_sale_price' => '10.00',
'new_sale_price' => '10.00',
'currency' => 'GBP',
'cur_user_id' => '20',
'cur_user_email' => 'user@email.com',
'cur_date' => '2014-06-09 10:59:37',
),
)
*/
}
/**
* This outputs data in a file or in the browser (if file param is passed).
* If the browser option is used it will output the data and will exit.
*
* @param array $data array of arrays
* @param array $title_row (optional) title/header row of the CSV file
* @param str $file target file to save the output to
* @return bool true/false depending on success
*/
public function write($data, $title_row = array(), $file = '', $append = 1) {
$output_in_browser = empty($file);
if ($output_in_browser) { // browser
$handle = fopen('php://output', 'w');
} else {
$handle = fopen($file, $append ? 'ab' : 'wb');
}
if (empty($handle)) {
return false;
}
// for some reason filesize would not update if the script accesses this file quickly
// this resulted in header column being written multiple times.
// that's why we clear the cache every time we write.
clearstatcache();
flock($handle, LOCK_EX);
// add the title row only if we're not appending or if the file size is minimal (fewer than 10 bytes).
// no need to add header rows all the time.
if ( !empty($title_row) && (!$append || filesize($file) < 10) ) {
fputcsv($handle, $title_row);
}
foreach ($data as $csv_data) {
fputcsv($handle, $csv_data);
}
flock($handle, LOCK_UN);
fclose($handle);
if ($output_in_browser) {
die;
}
return true;
}
}