Skip to content

Instantly share code, notes, and snippets.

@fprochazka
Created July 7, 2010 18:38
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save fprochazka/467074 to your computer and use it in GitHub Desktop.
Save fprochazka/467074 to your computer and use it in GitHub Desktop.
<?php
class CSVFile extends ArrayList
{
/*
* Is first line list of titles?
*/
var $titles = True;
var $separator = ',';
var $encoding = 'UTF-8';
private $file;
private $titleKeys = array();
private $lines = array();
private $line = 0;
public function __construct($file, $separator = ',', $withoutTitles = False, $encoding = 'UTF-8')
{
if( is_string($file) AND is_file($file) ){
$this->file = @fopen($file, 'r');
if( !$this->file ){
throw new FileNotFoundException("Cannot open file '$file'.");
}
} elseif(is_resource($file) AND get_resource_type($file) == 'file' ){
$this->file = $file;
} else {
throw new InvalidStateException("\$file must be readable file or file resource, ".gettype($file)." given.");
}
if( strlen($separator) > 1 ){
throw new InvalidStateException("Separator must be only one character!");
}
$this->separator = $separator;
$this->titles = $withoutTitles ? False : True;
$this->encoding = $encoding;
// realy need this
mb_internal_encoding("UTF-8");
// let's dance
$this->parseFile();
@fclose($this->file);
}
public function getTitleKeys()
{
return $this->titleKeys;
}
private function getLine()
{
$line = fgets($this->file);
if( $this->encoding != 'UTF-8' ){
return iconv($this->charset, 'UTF-8', $line);
}
return $line;
}
public function export($separator = Null)
{
if( $separator === Null ){
$separator = $this->separator;
}
$csv = Null;
if( $this->titles ){
$csv .= implode($separator, $this->titleKeys). "\n";
}
foreach( $this->lines AS $line ){
$csv .= implode($separator, $line). "\n";
}
return $csv;
}
private function parseFile()
{
while( !feof($this->file) ){
$this->lines[] = rtrim($this->getLine(), "\r\n");
}
if( $this->titles ){
$firstLine = array_shift($this->lines);
$this->titleKeys = $this->parseLine($firstLine);
} else {
$titles = array();
}
foreach( $this->lines AS $i => $line ){
$this->lines[$i] = $this->parseLine($line, $this->titleKeys);
}
}
private function stringToArray($string)
{
$arr = array();
for($i=0; $i <= mb_strlen($string) ;$i++){
$arr[] = mb_substr($string, $i, 1);
}
return $arr;
}
public function parseLine($line, $keys = array())
{
$arr = array();
$item = Null;
$counter = 0;
foreach( $this->stringToArray($line) AS $char ){
if( $char === $this->separator ){
$item = trim($item, "\r\n\t ");
if( isset($keys[$counter]) ){
$arr[$keys[$counter]] = $item;
} else {
$arr[$counter] = $item;
}
$item = Null;
$counter++;
} else {
$item .= $char;
}
}
return $arr;
}
/********************* interface ArrayAccess ****************f*p**/
public function getIterator()
{
return new ArrayIterator($this->lines);
}
public function offsetSet($offset, $value)
{
$this->lines[$offset] = $value;
}
public function offsetExists($offset)
{
return isset($this->lines[$offset]);
}
public function offsetUnset($offset)
{
unset($this->lines[$offset]);
}
public function offsetGet($offset)
{
return isset($this->lines[$offset]) ? $this->lines[$offset] : null;
}
}
?>
<?php
function editCSV(AppForm $form)
{
$values = $form->getValues();
$tmpf = $values['csvfile']->getTemporaryFile();
array_pop($values);
$csv = new CSVFile($tmpf, "\t");
foreach( $csv AS $i => $row ){
foreach( $row AS $key => $value ){
if( preg_match("~destination +url~i", $key) AND strlen($value)>0 ){
$uri = new Uri($value);
$uri->appendQuery($values);
$row[$key] = (string)$uri;
}
}
$csv[$i] = $row;
}
// echo "<table border=1>\n";
// echo "<tr><th>"; echo implode("</th><th>", $csv->getTitleKeys()); echo "</th></tr>\n";
// foreach( $csv AS $i => $row ){
// echo "<tr><td>"; echo implode("</td><td>", $row); echo "</td></tr>\n";
// }
// echo "</table>\n";
return $csv->export();
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment