From 9c389ed0c126760dcb2f966cdb817d725668804a Mon Sep 17 00:00:00 2001 From: zynode Date: Wed, 8 Aug 2007 18:48:11 +0000 Subject: [PATCH] conditions, limit and offset are functional. conditions needs a rewrite tho. added examples to trunk. git-svn-id: http://parsecsv-for-php.googlecode.com/svn/trunk@13 339761fc-0c37-0410-822d-8b8cac1f6a97 --- examples/basic.php | 13 +++++ examples/books.csv | 15 ++++++ examples/conditions.php | 15 ++++++ examples/limit.php | 21 ++++++++ parsecsv.lib.php | 103 +++++++++++++++++++++++++++++++++------- 5 files changed, 150 insertions(+), 17 deletions(-) create mode 100644 examples/basic.php create mode 100644 examples/books.csv create mode 100644 examples/conditions.php create mode 100644 examples/limit.php 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()