diff --git a/examples/basic.php b/examples/basic.php new file mode 100644 index 0000000..2cd16a7 --- /dev/null +++ b/examples/basic.php @@ -0,0 +1,13 @@ +
+auto('books.csv');
+
+print_r($csv);
+
+?>
+
\ No newline at end of file
diff --git a/examples/books.csv b/examples/books.csv
new file mode 100644
index 0000000..ed0906c
--- /dev/null
+++ b/examples/books.csv
@@ -0,0 +1,15 @@
+rating,title,by,type,asin,tags,review
+0,The Killing Kind,John Connolly,Book,0340771224,,
+0,The Third Secret,Steve Berry,Book,0340899263,,
+0,The Last Templar,Raymond Khoury,Book,0752880705,,
+5,The Traveller,John Twelve Hawks,Book,059305430X,,
+4,Crisis Four,Andy Mcnab,Book,0345428080,,
+5,Prey,Michael Crichton,Book,0007154534,,
+3,The Broker (Paperback),John Grisham,Book,0440241588,book johngrisham,"good book, but is slow in the middle"
+3,Without Blood (Paperback),Alessandro Baricco,Book,1841955744,,
+5,State of Fear (Paperback),Michael Crichton,Book,0061015733,,
+4,The Rule of Four (Paperback),Ian Caldwell,Book,0099451956,book bestseller,
+4,Deception Point (Paperback),Dan Brown,Book,0671027387,book danbrown bestseller,
+5,Digital Fortress : A Thriller (Mass Market Paperback),Dan Brown,Book,0312995423,book danbrown bestseller,
+5,Angels & Demons (Mass Market Paperback),Dan Brown,Book,0671027360,book danbrown bestseller,
+5,The Da Vinci Code (Hardcover),Dan Brown,Book,0385504209,book movie danbrown bestseller davinci,
diff --git a/examples/conditions.php b/examples/conditions.php
new file mode 100644
index 0000000..d302c49
--- /dev/null
+++ b/examples/conditions.php
@@ -0,0 +1,15 @@
+
+conditions = array( 'title' => array('*paperback*', '*hardcover*') );
+
+$csv->auto('books.csv');
+
+print_r($csv->data);
+
+?>
+
\ No newline at end of file
diff --git a/examples/limit.php b/examples/limit.php
new file mode 100644
index 0000000..a11f816
--- /dev/null
+++ b/examples/limit.php
@@ -0,0 +1,21 @@
+
+sort_by = 'title';
+
+$csv->limit = 3;
+$csv->offset = 2;
+
+$csv->auto('books.csv');
+
+print_r($csv->data);
+
+?>
+
\ No newline at end of file
diff --git a/parsecsv.lib.php b/parsecsv.lib.php
index 3c62f03..8a2990b 100644
--- a/parsecsv.lib.php
+++ b/parsecsv.lib.php
@@ -76,6 +76,7 @@ class parseCSV {
/**
* Configuration
+ * - set these options with $object->var_name = 'value';
*/
# use first line/entry as field names
@@ -92,6 +93,15 @@ class parseCSV {
var $delimiter = ',';
var $enclosure = '"';
+ # basic conditional matching against values. rows that don't match are ignored
+ var $conditions = array();
+
+ # number of rows to ignore from beginning of data
+ var $offset = null;
+
+ # limits the number of returned rows to specified amount
+ var $limit = null;
+
# number of rows to analyze when attempting to auto-detect delimiter
var $auto_depth = 15;
@@ -137,7 +147,10 @@ class parseCSV {
* @param input CSV file or string
* @return nothing
*/
- function parseCSV ($input = null) {
+ function parseCSV ($input = null, $offset = null, $limit = null, $conditions = array()) {
+ if ( $offset !== null ) $this->offset = $offset;
+ if ( $limit !== null ) $this->limit = $limit;
+ if ( count($conditions) > 0 ) $this->conditions = $conditions;
if ( !empty($input) ) $this->parse($input);
}
@@ -151,8 +164,11 @@ class parseCSV {
* @param input CSV file or string
* @return nothing
*/
- function parse ($input = null) {
+ function parse ($input = null, $offset = null, $limit = null, $conditions = array()) {
if ( !empty($input) ) {
+ if ( $offset !== null ) $this->offset = $offset;
+ if ( $limit !== null ) $this->limit = $limit;
+ if ( count($conditions) > 0 ) $this->conditions = $conditions;
if ( is_readable($input) ) {
$this->data = $this->parse_file($input);
} else {
@@ -367,9 +383,9 @@ class parseCSV {
// walk through each character
for ( $i=0; $i < $strlen; $i++ ) {
- $ch = $data[$i];
- $nch = ( isset($data[$i+1]) ) ? $data[$i+1] : false ;
- $pch = ( isset($data[$i-1]) ) ? $data[$i-1] : false ;
+ $ch = $data{$i};
+ $nch = ( isset($data{$i+1}) ) ? $data{$i+1} : false ;
+ $pch = ( isset($data{$i-1}) ) ? $data{$i-1} : false ;
// open and closing quotes
if ( $ch == $this->enclosure && (!$enclosed || $nch != $this->enclosure) ) {
@@ -390,22 +406,29 @@ class parseCSV {
// end of row
if ( $ch == "\n" || $ch == "\r" ) {
- if ( $this->heading && empty($head) ) {
- $head = $row;
- } elseif ( empty($this->fields) || (!empty($this->fields) && (($this->heading && $row_count > 0) || !$this->heading)) ) {
- if ( !empty($this->sort_by) && !empty($row[$this->sort_by]) ) {
- if ( isset($rows[$row[$this->sort_by]]) ) {
- $rows[$row[$this->sort_by].'_0'] = &$rows[$row[$this->sort_by]];
- unset($rows[$row[$this->sort_by]]);
- for ( $sn=1; isset($rows[$row[$this->sort_by].'_'.$sn]); $sn++ ) {}
- $rows[$row[$this->sort_by].'_'.$sn] = $row;
- } else $rows[$row[$this->sort_by]] = $row;
- } else $rows[] = $row;
+ if ( $this->validate_offset($row_count) ) {
+ if ( $this->validate_row_conditions($row, $this->conditions) ) {
+ if ( $this->heading && empty($head) ) {
+ $head = $row;
+ } elseif ( empty($this->fields) || (!empty($this->fields) && (($this->heading && $row_count > 0) || !$this->heading)) ) {
+ if ( !empty($this->sort_by) && !empty($row[$this->sort_by]) ) {
+ if ( isset($rows[$row[$this->sort_by]]) ) {
+ $rows[$row[$this->sort_by].'_0'] = &$rows[$row[$this->sort_by]];
+ unset($rows[$row[$this->sort_by]]);
+ for ( $sn=1; isset($rows[$row[$this->sort_by].'_'.$sn]); $sn++ ) {}
+ $rows[$row[$this->sort_by].'_'.$sn] = $row;
+ } else $rows[$row[$this->sort_by]] = $row;
+ } else $rows[] = $row;
+ }
+ }
}
$row = array();
$col = 0;
$row_count++;
- }
+ if ( $this->sort_by === null && $this->limit !== null && count($rows) == $this->limit ) {
+ $i = $strlen;
+ }
+ }
// append character to current field
} else {
@@ -415,6 +438,9 @@ class parseCSV {
$this->titles = $head;
if ( !empty($this->sort_by) ) {
( $this->sort_reverse ) ? krsort($rows) : ksort($rows) ;
+ if ( $this->offset !== null || $this->limit !== null ) {
+ $rows = array_slice($rows, ($this->offset === null ? 0 : $this->offset) , $this->limit, true);
+ }
}
return $rows;
}
@@ -463,6 +489,49 @@ class parseCSV {
// ----- [ Internal Functions ] -----------------
// ==============================================
+ /**
+ * Validate a row against specified conditions
+ * @param row array with values from a row
+ * @param conditions specified conditions that the row must match
+ * @return true of false
+ */
+ function validate_row_conditions ($row = array(), $conditions = array()) {
+ if ( !empty($row) ) {
+ if ( !empty($conditions) ) {
+ foreach( $conditions as $key => $value ) {
+ if ( array_key_exists($key, $row) ) {
+ if ( is_array($value) ) {
+ $match = array();
+ foreach( $value as $k => $v ) {
+ $v = preg_quote($v, '/');
+ $match[] = '(?:'.str_replace('\*', '.*?', $v).')';
+ }
+ $match = implode('|', $match);
+ } else {
+ $match = preg_quote($value, '/');
+ $match = str_replace('\*', '.*?', $match);
+ }
+ if ( !preg_match('/^'.$match.'$/i', $row[$key]) ) {
+ return false;
+ }
+ }
+ }
+ }
+ return true;
+ }
+ return false;
+ }
+
+ /**
+ * Validates if the row is within the offset or not if sorting is disabled
+ * @param current_row the current row number being processed
+ * @return true of false
+ */
+ function validate_offset ($current_row) {
+ if ( $this->sort_by === null && $this->offset !== null && $current_row < $this->offset ) return false;
+ return true;
+ }
+
/**
* Enclose values if needed
* - only used by unparse()