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

Revision 281, 6.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 DB
4 *
5 * $Id$
6 *
7 * @package     patForms
8 * @subpackage  Storage
9 * @author      Stephan Schmidt <schst@php-tools.net>
10 */
11
12/**
13 * needs PEAR::DB
14 */
15require_once 'DB.php';
16 
17/**
18 * patForms storage DB
19 *
20 * Stores form data in a database.
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_DB extends patForms_Storage
31{
32   /**
33    * datasource name
34    *
35    * @access   private
36    * @var      string
37    */
38    var $_dsn;
39
40   /**
41    * table name
42    *
43    * @access   private
44    * @var      string
45    */
46    var $_table;
47
48   /**
49    * instance of PEAR::DB
50    *
51    * @access   private
52    * @var      object
53    */
54    var $_db;
55
56   /**
57    * field map
58    *
59    * @access   private
60    * @var      string
61    */
62    var $_fieldMap  =   array();
63
64   /**
65    * set the dsn and table
66    *
67    * @access   public
68    * @param    string      datasource name
69    * @param    string      table
70    */
71    function setStorageLocation( $dsn, $table )
72    {
73        $this->_dsn     =   $dsn;
74        $this->_table   =   $table;
75    }
76
77   /**
78    * set the field map
79    *
80    * The field map is an associative array, that defines how
81    * the form elements (key) map to fields in the
82    * table (value)
83    *
84    * @access   public
85    * @param    array       field map
86    */
87    function setFieldMap($fieldMap)
88    {
89        $this->_fieldMap = $fieldMap;
90    }
91
92   /**
93    * get an entry
94    *
95    * This tries to find an entry in the storage container
96    * that matches the current data that has been set in the
97    * form and populates the form with the data of this
98    * entry
99    *
100    * @access   public
101    * @param    object patForms     patForms object that should be stored
102    * @return   boolean             true on success
103    */
104    function loadEntry(&$form)
105    {
106        $values  = $form->getValues();
107        $primary = $this->getPrimary($values);
108
109        // no primary key, storage will only add entries
110        if (empty($primary)) {
111            return array();
112        }
113       
114        /**
115         * entry does not exists
116         */
117        if (!$data = $this->_entryExists($primary)) {
118            return array();
119        }
120           
121        $values = $this->_unmapFields($data);
122
123        $form->setValues($values);
124        return true;
125    }
126
127   /**
128    * adds an entry to the storage
129    *
130    * The entry will be appended at the end of the file.
131    *
132    * @abstract
133    * @param    object patForms     patForms object that should be stored
134    * @return   boolean             true on success
135    */
136    function _addEntry(&$form)
137    {
138        $values = $form->getValues();
139       
140        $result = $this->_prepareConnection();
141        if (PEAR::isError($result)) {
142            return patErrorManager::raiseError(PATFORMS_STORAGE_ERROR_STORAGE_INVALID, 'Could not connect to database: ' . $result->getMessage());
143        }
144        $values = $this->_mapFields($values);
145       
146        $values = array_merge($values, $this->_staticValues);
147       
148        $fields = array_keys($values);
149        $values = array_map(array($this->_db, 'quoteSmart'), array_values($values));
150
151        $query  = sprintf('INSERT INTO %s (%s) VALUES (%s);', 
152                          $this->_table,
153                          implode(',', $fields),
154                          implode(',', $values)
155                      );
156       
157        $result = $this->_db->query($query);
158       
159        if (PEAR::isError($result)) {
160            return patErrorManager::raiseError(PATFORMS_STORAGE_ERROR_STORAGE_INVALID, 'Query failed: ' . $result->getMessage());
161        }
162        return true;       
163    }
164
165   /**
166    * updates an entry in the storage
167    *
168    * Implement this in the concrete storage container.
169    *
170    * @abstract
171    * @param    object patForms     patForms object that should be stored
172    * @return   boolean             true on success
173    */
174    function _updateEntry( &$form, $primary )
175    {
176        $values = $form->getValues();
177       
178        $result = $this->_prepareConnection();
179        if (PEAR::isError($result)) {
180            return patErrorManager::raiseError(PATFORMS_STORAGE_ERROR_STORAGE_INVALID, 'Could not connect to database: ' . $result->getMessage());
181        }
182        $values  = $this->_mapFields($values);
183        $primary = $this->_mapFields($primary);
184       
185        $tmp = array();
186        foreach ($values as $key => $value) {
187            array_push( $tmp, $key.'='.$this->_db->quoteSmart( $value ) );
188        }
189
190        $ptmp = array();
191        foreach ($primary as $key => $value) {
192            array_push( $ptmp, $key.'='.$this->_db->quoteSmart( $value ) );
193        }
194
195        $query  = 'UPDATE '.$this->_table.' SET '.implode( ', ', $tmp ).' WHERE '.implode( ' AND ', $ptmp );
196        $result = $this->_db->query($query);
197        if (PEAR::isError($result)) {
198            return patErrorManager::raiseError(PATFORMS_STORAGE_ERROR_STORAGE_INVALID, 'Query failed: ' . $result->getMessage());
199        }
200        return true;       
201    }
202
203   /**
204    * check, whether an entry exists
205    *
206    * @access   private
207    * @param    array
208    */
209    function _entryExists($primary)
210    {
211        $result = $this->_prepareConnection();
212        if (PEAR::isError($result)) {
213            return patErrorManager::raiseError(PATFORMS_STORAGE_ERROR_STORAGE_INVALID, 'Could not connect to database: ' . $result->getMessage());
214        }
215        $primary = $this->_mapFields($primary);
216
217        $tmp = array();
218        foreach ($primary as $key => $value) {
219            array_push($tmp, $key.'='.$this->_db->quoteSmart($value));
220        }
221
222        $query  = 'SELECT * FROM '.$this->_table.' WHERE '.implode( ' AND ', $tmp );
223        $result = $this->_db->getRow( $query, array(), DB_FETCHMODE_ASSOC );
224        if (PEAR::isError($result)) {
225            return patErrorManager::raiseError(PATFORMS_STORAGE_ERROR_STORAGE_INVALID, 'Could not connect to database: ' . $result->getMessage());
226        }
227
228        if (empty($result)) {
229            return false;
230        }
231
232        return $result;
233    }
234
235   /**
236    * map the values to the correct fields
237    *
238    * @access   private
239    * @param    array       values
240    * @return   array       values mapped to the correct fields
241    */
242    function _mapFields( $values )
243    {
244        if (empty($this->_fieldMap)) {
245            return $values;
246        }
247
248        $fields =   array();
249        foreach ($this->_fieldMap as $el => $field) {
250            if (!isset($values[$el])) {
251                continue;
252            }
253
254            $fields[$field] = $values[$el];
255        }
256        return $fields; 
257    }
258
259   /**
260    * map the fields to the correct elements
261    *
262    * @access   private
263    * @param    array       values
264    * @return   array       values mapped to the correct fields
265    */
266    function _unmapFields( $values )
267    {
268        if (empty($this->_fieldMap)) {
269            return $values;
270        }
271
272        $fields = array();
273        foreach ($this->_fieldMap as $el => $field) {
274            if( !isset($values[$field])) {
275                continue;
276            }
277
278            $fields[$el] = $values[$field];
279        }
280        return $fields; 
281    }
282
283   /**
284    * prepare the DB connection
285    *
286    * @access   private
287    */
288    function _prepareConnection()
289    {
290        if ($this->_db != null) {
291            return true;
292        }
293       
294        if (is_object($this->_dsn)) {
295            $this->_db = &$this->_dsn;
296            return true;
297        }
298
299        $this->_db = &DB::connect($this->_dsn);
300        if (PEAR::isError($this->_db)) {
301            $error = $this->_db;
302            $this->_db = null;
303            return $error;
304        }
305        return true;
306    }
307}
308?>
Note: See TracBrowser for help on using the repository browser.