Subversion Repositories php_users

Rev

Rev 7 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
4 rodolico 1
<?php
2
 
3
/*
4
 * Users class needs a way of accessing a data source. This is for a
5
 * mysqli instance. Create an instance of this, then pass that instance
6
 * to the Users class
7
 */
8
 
9
class usersDataSource {
10
 
11
   private $dbDefinition = array(
12
      'tables' => array(
13
         'users'  => array(
14
            'table'     => '_users',   // table name for user records
15
            'id'        => '_user_id', // ID column name
16
            'display'   => array(      // fields which are displayed to select
17
               'login'
18
               ),
19
            'password'  => array(      // These fields are stored encrypted
20
               'pass'
21
               ),
22
            'fields' => array(
23
               'login'  => array(
24
                     'dbColumn'  =>  'login',       // login name column name
25
                     'type'      => 'varchar',
26
                     'size'      => 64,
27
                     'required'  => true,
28
                     'editable'  => true
29
                     ),
30
               'pass'   => array( 
31
                     'dbColumn'  => 'password',    // password column name
32
                     'type'   => 'varchar',
33
                     'size'      => 128,
34
                     'required'  => true,
35
                     'editable'  => true
36
                     ),
37
               'admin'  => array(
38
                     'dbColumn'  => 'isAdmin',
39
                     'type'      => 'boolean',
40
                     'required'  => true,
41
                     'default'   => '0'
42
                     ),
43
               'enabled'   => array(
44
                     'dbColumn'  => 'enabled',
45
                     'type'      => 'boolean',
46
                     'required'  => true,
47
                     'default'   => '1'
48
                     )
49
               )
50
            )
51
         )
52
      );
53
 
54
      private $dbConnection = false;
55
 
56
      public function __construct( $dbConnection = null, $dbDef = array(), $dbLoginInfo = array() ) {
57
         $this->dbConnection = $dbConnection;
58
         if ( $dbDef ) {
59
            $this->dbDefinition = array_merge_recursive( $this->dbDefinition, $dbDef );
60
         }
61
         if ( $dbLoginInfo ) {
62
            $this->setDBConnection( $dbLoginInfo );
63
         }
64
      }
65
 
66
      private function escapeString ( $string ) {
67
         $string = $this->dbConnection->real_escape_string( $string );
68
         if ( ! is_numeric( $string ) )
69
            $string = "'$string'";
70
         return $string;
71
      }
72
 
73
      /**
74
       * Create a query to retrieve info from databawse
75
       * 
76
       * Builds a query to retrieve records from the database. With all
77
       * parameters set to null, will retrieve all columns and records
78
       * Setting $field and $toFind create a where clause, and setting
79
       * $fieldList as a has (ie, 'fieldname' => 1) will limit the 
80
       * fields returned
81
       * 
82
       * @param string $field A valid field definition, which may not be a column in the table
83
       * @param string $toFind The string to find, ie where $field = $username
84
       * @param string[] $fieldList a hash where the keys make a list of columns to return. If empty, returns all columns
85
       * 
86
       * @return string A cleaned and formatted SQL Query
87
       * 
88
      */
89
      private function buildQuery( $whereFields, $fieldList = null ) {
90
         // always get the ID field
91
         $fields = array( $this->dbDefinition['tables']['users']['id'] . ' id');
92
         // Get the rest of the available fields
93
         foreach ( $this->dbDefinition['tables']['users']['fields'] as $key => $value ) {
94
            // do not use this one if $fieldList doesn't have it
95
            if ( ! isset( $fieldList ) || isset( $fieldList[$key] ) )
96
               $fields[] = $value['dbColumn'] . ' ' . $key;
97
         }
98
         // Change it into something SQL can handle
99
         $query = implode( ',', $fields );
100
         // now, build the rest of the query
101
         $query = "select $query from " . $this->dbDefinition['tables']['users']['table'];
102
         if ( isset( $whereFields ) ) {
103
            $temp = array();
104
            foreach ( $whereFields as $key => $value ) {
105
               $temp[] = ( 
106
                  $key == 'id' ? 
107
                  $this->dbDefinition['tables']['users']['id'] : 
108
                  $this->dbDefinition['tables']['users']['fields'][$key]['dbColumn']
109
                  ) . '= ' . $this->escapeString( $value );
110
            }
111
            $query .= ' where ' . implode( ' and ', $temp );
112
         }
113
         //print "<p>$query</p>";
114
         return $query;
115
      }
116
 
117
      /**
118
       * Get a record from the database
119
       * 
120
       * Gets a single record from the database which matches $field containing
121
       * $username. If more than one record is returned, will return the first
122
       * one
123
       * 
124
       * @param string[] $whereFields column=>value pairs for where clause
125
       * @param string[] $fieldList a list of columns to return. If empty, returns all columns
126
       * 
127
       * @return string[] a hash containing fieldname=>value pairs
128
       * 
129
      */
130
      public function getARecord( $whereFields, $fieldList = null ) {
131
         // run the query, placing value in $result
132
         mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
133
         $result = $this->dbConnection->query( $this->buildQuery( $whereFields, $fieldList ) );
134
         if ( $result ) { // got one, so return it
135
            return $result->fetch_assoc();
136
         }
137
         // WTFO? nothing, so return empty array
138
         return array();
139
      }
140
 
141
      public function getPassword( $username ) {
142
         return $this->getARecord( array('login' => $username,'enabled' => 1), array('pass' => 1 ) );
143
      }
144
 
145
      public function getRecord ( $username ) {
146
         return $this->getARecord( array( 'login' => $username ) );
147
      }
148
 
149
 
150
      private function setDBConnection ( $parameters ) {
151
         if ( !isset($parameters['username'], $parameters['password'],$parameters['database']  )) {
152
            return false;
153
         }
154
         if ( !isset( $parameters['host'] ) ) {
155
            $parameters['host'] = 'localhost';
156
         }
157
         mysqli_report( MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT );
158
         $this->dbConnection = new mysqli( $parameters['host'], $parameters['username'], $parameters['password'],$parameters['database'] );
159
      }
160
 
161
 
162
 
163
      /**
164
       * Convenience function to create the table
165
       * 
166
       * Using $dbDefinition, build the table (replacing the current one)
167
       * then add $username with $password, setting as admin
168
       * 
169
       * @param string $username The username to create
170
       * @param string $password The password for this record
171
       * @param bool $admin Whether the user is an admin or not
172
       * 
173
       * @return bool true if table was created
174
       * 
175
      */
176
      public function buildTable( $username, $password, $admin = true ) {
177
         if ( $this->dbConnection ) {
178
            $password = password_hash( $password, PASSWORD_DEFAULT );
179
            $fields = array( $this->dbDefinition['tables']['users']['id'] . ' int unsigned not null auto_increment' );
180
            foreach ( $this->dbDefinition['tables']['users']['fields'] as $key => $record ) {
181
               $fieldDef = $record['dbColumn'];
182
               $fieldDef .= ' ' . $record['type'];
183
               if ( isset( $record['size'] ) ) {
184
                  $fieldDef .= '(' . $record['size'] . ')';
185
               }
186
               if ( isset( $record['required'] ) ) {
187
                  $fieldDef .= $record['required'] ? ' not null ' : '';
188
               }
189
               if ( isset( $record['default'] ) ) {
190
                  $fieldDef .= sprintf( " default '%s'", $record['default'] );
191
               }
192
               if ( isset( $record['comment'] ) ) {
193
                  $fieldDef .= "comment '" . $record['comment'] . "'";
194
               }
195
               $fields[] = $fieldDef;
196
            }
197
            $fields[] = 'primary key (' . $this->dbDefinition['tables']['users']['id'] . ')';
198
            $query = implode( ',', $fields );
199
            $query = 'create or replace table ' . $this->dbDefinition['tables']['users']['table'] .
200
                  "($query)";
201
            $this->dbConnection->query( $query );
202
            $query = "insert into _users( login, password, isAdmin ) values ( '$username', '$password', '$admin' )";
203
            $this->dbConnection->query( $query );
204
         }
205
         return false;
206
      } // buildTable
207
 
208
      /**
209
       * Tests that the database connection works and the table is built
210
       * 
211
       */
212
      public function test() {
213
         $result = $this->dbConnection->query( sprintf( "show tables like '%s'", $this->dbDefinition['tables']['users']['table'] ) );
214
         return $result !== false && $result->num_rows;
215
      } // test
216
 
217
      public function update ( $newData ) {
218
         $query = '';
219
         foreach ( $newData as $key => $value ) {
220
            $newData[$key] = $this->escapeString( $value );
221
         }
222
         if ( $newData ) { // make sure they sent us something
223
            if ( $newData['id'] > 0 ) { // we are doing an update
224
               $fields = array();
225
               foreach ( $this->dbDefinition['tables']['users']['fields'] as $key => $record ) {
226
                  if ( isset( $newData[$key] ) ) {
227
                     $fields[] = $record['dbColumn'] . " = $newData[$key]";
228
                  } // if
229
               }
230
               $query = 'update ' . $this->dbDefinition['tables']['users']['table'] . ' set ' .
231
                  implode( ',', $fields ) .
232
                  ' where ' . $this->dbDefinition['tables']['users']['id'] . ' = ' . 
233
                  $this->dbConnection->real_escape_string( $newData['id'] );
234
            } else { // we are doing an insert
235
               $columns = array();
236
               $values = array();
237
               foreach ( $this->dbDefinition['tables']['users']['fields'] as $key => $record ) {
238
                  if ( isset( $newData[$key] ) ) {
239
                     $columns[] = $record['dbColumn'];
240
                     $values[] = $newData[$key];
241
                  } // if
242
               }
243
               $query = 'insert into ' . $this->dbDefinition['tables']['users']['table'] . 
244
                  '(' . implode( ',', $columns ) . ') values (' .
245
                  implode( ',', $values ) . ')';
246
            }
247
            //print "<p>$query</p>";
248
            return $this->dbConnection->query( $query );
249
         }
250
      } // update
251
 
252
 
253
      public function getAllUsers() {
254
         $query = $this->buildQuery( null, null, array('login' => 1) );
255
         //print "<p>$query</p>\n";
256
         mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT);
257
         $result = $this->dbConnection->query( $query );
258
         if ( $result ) {
259
            return $result->fetch_all(MYSQLI_ASSOC);
260
         }
261
         return array();
262
      }
263
 
264
}
265
 
266
?>