Skip to content

Instantly share code, notes, and snippets.

@Erliz
Created May 23, 2013 21:21
Show Gist options
  • Select an option

  • Save Erliz/5639513 to your computer and use it in GitHub Desktop.

Select an option

Save Erliz/5639513 to your computer and use it in GitHub Desktop.
<?php
/**
*
*/
class M_File
{
private $id;
private $handle;
private $delimiter = ';';
private $encode = 'cp1251';
public $tmp = false;
public $path;
public $name;
public $lines;
public $create_time;
public $size;
public $hash;
/**
* @param mixed $data - int(id файла), array($_FILES), string(file_path)
* @param null $encode - кодировка по умолчанию cp1251
* @param null $delimiter - разделитель столбцов по умолчанию ";"
*/
function __construct($data, $encode = null, $delimiter = null)
{
if (isset($delimiter)) {
$this->delimiter = $delimiter;
}
if (isset($encode)) {
$this->encode = $encode;
}
if (is_int($data)) {
if ($this->get_info($data)) {
return true;
} else {
return false;
}
}
if (is_array($data)) {
$this->path = $data['tmp_name'];
$this->name = $data['name'];
} elseif (is_file($data)) {
$this->path = $data;
$this->name = basename($this->path);
} else {
$this->path = $data;
return false;
}
$this->lines = count(file($this->path));
$this->create_time = filemtime($this->path);
$this->size = filesize($this->path);
}
public function setDelimiter($string)
{
$this->delimiter = $string;
}
/**
* @param $name
*
* @return M_File
*/
static public function createTmp($name)
{
$file['tmp_name'] = tempnam('', 'direct_');
$file['name'] = $name . '.csv';
$instance = new M_File($file);
$instance->tmp = true;
return $instance;
}
private function get_info($id)
{
$data = Registry::$db->query("SELECT * FROM `files` WHERE `id`=$id LIMIT 1;")->fetch();
if ($data) {
$this->id = $data['id'];
$this->name = $data['title'];
$this->lines = $data['lines'];
$this->hash = $data['hash'];
$this->create_time = $data['time_upload'];
$this->path = ConfigPath::$real . ConfigPath::$fdb . $data['hash'];
return true;
}
return false;
}
public function create()
{
if (file_exists($this->path)) {
unlink($this->path);
}
$this->handle = fopen($this->path, 'a');
$this->name = basename($this->path);
return (file_exists($this->path)) ? true : false;
}
public function put($array)
{
if ($this->encode !== 'utf-8') {
$tmp_array = Array();
foreach ($array as $val) {
if (is_float($val)) {
$tmp_array[] = str_replace('.', ',', $val);
} else {
$tmp_array[] = iconv(
'utf-8',
'cp1251',
$val
);
}
}
$this->lines++;
$array = $tmp_array;
}
if (!isset($this->handle)) {
$this->handle = fopen($this->path, 'a');
if (!$this->handle) {
throw new E_Fatal('Couldn`t fopen file');
}
}
if (!fputcsv($this->handle, $array, $this->delimiter)) {
throw new E_Fatal('Couldn`t write csv row to file');
}
return true;
}
public function close()
{
if (isset($this->handle)) {
fclose($this->handle);
unset($this->handle);
$this->size = filesize($this->path);
} else {
return false;
}
}
private function hash_gen()
{
$hash = md5_file($this->path);
$hash = md5($hash . $this->name);
$this->hash = $hash;
return true;
}
public function upload()
{
$this->hash_gen();
$new_path = ConfigPath::$real . ConfigPath::$fdb . $this->hash;
if(!copy($this->path, $new_path)){
throw new E_Fatal("Project, could not upload new db from $this->path to $new_path");
}
unlink($this->path);
$this->path = $new_path;
return true;
}
public function download()
{
$this->close();
header('Pragma: public');
header('Content-Description: File Transfer');
header('Content-Type: application/force-download');
header('Content-Disposition: attachment; filename=' . $this->name); //iconv("CP1251","UTF-8",$this->name)
header('Content-Transfer-Encoding: binary');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Cache-Control: must-revalidate, post-check=0, pre-check=0');
if ($this->size) {
header('Content-Length: ' . $this->size);
}
ob_clean();
flush();
readfile($this->path);
exit;
}
public function replace($search, $replace)
{
if ($cont = file_get_contents($this->path)) {
$cont = str_replace($search, $replace, $cont);
$cont = str_replace("\n", "\r\n", $cont);
file_put_contents($this->path, $cont);
return true;
} else {
return false;
}
}
/**
* @return string[]|bool
*/
public function getCSV()
{
$cont = fopen($this->path, "r");
$rows = 0;
while ($row = fgetcsv($cont, 1000, ";")) {
if ($this->encode == 'cp1251') {
foreach ($row as $k => $field) {
$row[$k] = $this->code($field);
}
}
$list[$rows] = $row;
$rows++;
}
fclose($cont);
array_pop($list);
if (count($list) > 0) {
return $list;
} else {
return false;
}
}
public function getAscArray()
{
$array = $this->getCSV();
if ($array == false) {
return false;
}
$result = Array();
foreach ($array as $value) {
if (is_bool($value[0]) || $value[0] == "") {
continue;
}
$row = Array();
foreach ($value as $key => $val) {
if ($key == 0) {
continue;
}
$row[] = $val;
}
$result[$value[0]] = $row;
}
return $result;
}
/**
* Функция для парса csv файла
* Превращения его в ассоциативный массив где ключ это Колонка с $key товара а значения массива это колонка $val
* Удобно парсить текстовые файлы, где нужна только одна колонка.
*
* @param string $file путь к файлу
* @param int $key какой столбец использовать в виде ключей массива
* @param int $val какой столбец использовать в виде значений массива
*
* @throws Exception
* @return bool|array Ошибка или массив с данными из файла
*/
protected function parse_csv($file, $key, $val)
{
if (!is_file($file)) {
return false;
}
$array = Array();
$handle = fopen($file, 'r');
while ($row = fgetcsv($handle, 1000, ";")) {
if (isset($array[$row[$key]])) {
continue;
} elseif (isset($row[$key]) && isset($row[$val])) {
$array[$row[$key]] = $row[$val];
} else {
throw new Exception("no value at column $key or $val in file: $file <br/>", 1);
}
}
fclose($handle);
return $array;
}
public static function decode($value)
{
$value = @iconv("UTF-8", "CP1251", $value);
return $value;
}
public static function code($value)
{
$value = @iconv("CP1251", "UTF-8", $value);
return $value;
}
public static function csv_write($rows, $file_path)
{
if (isset($rows)) {
if (file_exists($file_path)) {
unlink($file_path);
}
$fp = fopen($file_path, "a");
foreach ($rows as $value) {
foreach ($value as $key => $val) {
$value[$key] = self::decode($val);
}
fputcsv($fp, $value, ";");
}
fclose($fp);
}
}
public function delete()
{
unlink($this->path);
}
function __destruct()
{
if ($this->tmp && is_file($this->path)) {
unlink($this->path);
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment