source: trunk/patForms/Storage/CSV.php @ 85

Revision 85, 5.4 KB checked in by schst, 9 years ago (diff)

added boolean return values
removed debug output

  • Property svn:eol-style set to native
  • Property svn:keywords set to Author Date Id Revision
Line 
1<?php
2/**
3 * patForms storage CSV
4 *
5 * $Id$
6 *
7 * @package     patForms
8 * @subpackage  Storage
9 * @author      Stephan Schmidt <schst@php-tools.net>
10 */
11
12/**
13 * could not open storage container
14 */
15define( 'PATFORMS_STORAGE_ERROR_STORAGE_INVALID', 20000 );
16 
17/**
18 * patForms storage CSV
19 *
20 * Stores form data in a CSV file.
21 *
22 * @access      protected
23 * @package     patForms
24 * @subpackage  Storage
25 * @author      Stephan Schmidt <schst@php-tools.net>
26 * @license     LGPL, see license.txt for details
27 * @link        http://www.php-tools.net
28 * @todo        add error management
29 */
30class patForms_Storage_CSV extends patForms_Storage
31{
32   /**
33    * storage file
34    *
35    * @access   private
36    * @var      string
37    */
38    var $_file;
39
40   /**
41    * csv delimeter
42    *
43    * @access   private
44    * @var      string
45    */
46    var $_delimeter =   ';';
47
48   /**
49    * linefeed
50    *
51    * @access   private
52    * @var      string
53    */
54    var $_linefeed  =   "\n";
55
56   /**
57    * field order
58    *
59    * @access   private
60    * @var      string
61    */
62    var $_fieldOrder    =   array();
63
64   /**
65    * set the storage file
66    *
67    * @access   public
68    * @param    string      filename
69    */
70    function setFile( $file )
71    {
72        $this->_file    =   $file;
73    }
74
75   /**
76    * set the delimeter
77    *
78    * @access   public
79    * @param    string      delimeter
80    */
81    function setDelimeter( $delimeter )
82    {
83        $this->_delimeter   =   $delimeter;
84    }
85
86   /**
87    * set the field order
88    *
89    * @access   public
90    * @param    array       field order
91    */
92    function setFieldOrder( $fields )
93    {
94        $this->_fieldOrder  =   $fields;
95    }
96
97   /**
98    * get an entry
99    *
100    * This tries to find an entry in the storage container
101    * that matches the current data that has been set in the
102    * form and populates the form with the data of this
103    * entry
104    *
105    * @access   public
106    * @param    object patForms     patForms object that should be stored
107    * @return   boolean             true on success
108    */
109    function loadEntry( &$form )
110    {
111        $values  = $form->getValues();
112        $primary = $this->getPrimary( $values );
113
114        /**
115         * primary key not given
116         */
117        if( empty( $primary ) )
118            return array();
119
120        /**
121         * entry does not exists
122         */
123        if( !$data = $this->_entryExists( $primary ) )
124            return array();
125
126        $values = array();
127        foreach( $this->_fieldOrder as $pos => $field )
128        {
129            if( isset( $data[$pos] ) )
130                $values[$field] = $data[$pos];
131        }
132        $form->setValues( $values );
133        return true;
134    }
135
136   /**
137    * adds an entry to the storage
138    *
139    * The entry will be appended at the end of the file.
140    *
141    * @abstract
142    * @param    object patForms     patForms object that should be stored
143    * @return   boolean             true on success
144    */
145    function _addEntry( &$form )
146    {
147        $values = $form->getValues();
148       
149        $line   = array();
150        foreach( $this->_fieldOrder as $field )
151        {
152            if( !isset( $values[$field] ) )
153                $value  =   '';
154            else
155                $value  =   $values[$field];
156           
157            array_push( $line, '"'.addslashes( $value ).'"' );
158        }
159        $line   =   implode( $this->_delimeter, $line ) . $this->_linefeed;
160        $fp     =   @fopen( $this->_file, 'a' );
161        if( !$fp )
162        {
163            return patErrorManager::raiseError( PATFORMS_STORAGE_ERROR_STORAGE_INVALID, 'Could not open the supplied csv file.' );
164        }
165       
166        flock( $fp, LOCK_EX );
167        fwrite( $fp, $line );
168        flock( $fp, LOCK_UN );
169        fclose( $fp );
170        return true;
171    }
172
173   /**
174    * updates an entry in the storage
175    *
176    * Implement this in the concrete storage container.
177    *
178    * @abstract
179    * @param    object patForms     patForms object that should be stored
180    * @return   boolean             true on success
181    */
182    function _updateEntry( &$form, $primary )
183    {
184        $keys   =   array();
185        foreach( $primary as $key => $value )
186        {
187            $pos = array_search( $key, $this->_fieldOrder );
188            $keys[$pos] = $value;
189        }
190
191        $new    =   array();
192   
193        $fp     =   @fopen( $this->_file, 'r' );
194        if( !$fp )
195        {
196            return patErrorManager::raiseError( PATFORMS_STORAGE_ERROR_STORAGE_INVALID, 'Could not open the supplied csv file.' );
197        }
198       
199        flock( $fp, LOCK_SH );
200        while( !feof( $fp ) )
201        {
202            $tmp    =   fgetcsv( $fp, 10000, $this->_delimeter );
203
204            foreach( $keys as $key => $value )
205            {
206                if( $tmp[$key] != $value )
207                {
208                    array_push( $new, $tmp );
209                    continue;
210                }
211               
212                $line   = array();
213                $values = $form->getValues();
214                foreach( $this->_fieldOrder as $field )
215                {
216                    if( !isset( $values[$field] ) )
217                        $value  =   '';
218                    else
219                        $value  =   $values[$field];
220                   
221                    array_push( $line, $value );
222                }
223                array_push( $new, $line );
224            }
225        }
226        flock( $fp, LOCK_UN );
227        fclose( $fp );
228
229        /**
230         * rewrite the file
231         */
232        $fp = @fopen( $this->_file, 'w' );
233        if( !$fp )
234        {
235            return patErrorManager::raiseError( PATFORMS_STORAGE_ERROR_STORAGE_INVALID, 'Could not open the supplied csv file.' );
236        }
237       
238        flock( $fp, LOCK_EX );
239
240        foreach( $new as $line )
241        {
242            if( empty( $line ) )
243                continue;
244            for( $i = 0; $i < count( $line ); $i++ )
245            {
246                $line[$i] = '"'.addslashes( $line[$i] ).'"';
247            }
248            $line   =   implode( $this->_delimeter, $line ) . $this->_linefeed;
249            fwrite( $fp, $line );
250        }
251
252        flock( $fp, LOCK_UN );
253        fclose( $fp );
254        return true;
255    }
256
257   /**
258    * check, whether an entry exists
259    *
260    * @access   private
261    * @param    array
262    */
263    function _entryExists( $primary )
264    {
265        $keys   =   array();
266        foreach( $primary as $key => $value )
267        {
268            $pos = array_search( $key, $this->_fieldOrder );
269            $keys[$pos] = $value;
270        }
271   
272        $fp     =   @fopen( $this->_file, 'r' );
273        if( !$fp )
274            return false;
275        flock( $fp, LOCK_SH );
276        while( !feof( $fp ) )
277        {
278            $tmp    =   fgetcsv( $fp, 10000, $this->_delimeter );
279            foreach( $keys as $key => $value )
280            {
281                if( $tmp[$key] != $value )
282                    continue;
283               
284                flock( $fp, LOCK_UN );
285                fclose( $fp );
286                return $tmp;
287            }
288        }
289        flock( $fp, LOCK_UN );
290        fclose( $fp );
291        return false;
292    }
293}
294?>
Note: See TracBrowser for help on using the repository browser.