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

Revision 281, 5.4 KB checked in by schst, 8 years ago (diff)

Pass event-handler errors to the user, check, whether DB connection could be established and queries were successful (fixes bug #140), adjust CSV-Storage coding standards

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