Fixed bug #9994: ereg* is deprecated in PHP 5.3 alpha3
[Packages/TYPO3.CMS.git] / typo3 / sysext / adodb / adodb / pear / Auth / Container / ADOdb.php
1 <?php
2 //
3 // +----------------------------------------------------------------------+
4 // | PHP Version 4 |
5 // +----------------------------------------------------------------------+
6 // | |
7 // +----------------------------------------------------------------------+
8 // | This source file is subject to version 2.02 of the PHP license, |
9 // | that is bundled with this package in the file LICENSE, and is |
10 // | available at through the world-wide-web at |
11 // | http://www.php.net/license/2_02.txt. |
12 // | If you did not receive a copy of the PHP license and are unable to |
13 // | obtain it through the world-wide-web, please send a note to |
14 // | license@php.net so we can mail you a copy immediately. |
15 // +----------------------------------------------------------------------+
16 // | Authors: Martin Jansen <mj@php.net>
17 // | Richard Tango-Lowy <richtl@arscognita.com> |
18 // +----------------------------------------------------------------------+
19 //
20 // $Id$
21 //
22
23 require_once 'Auth/Container.php';
24 require_once 'adodb.inc.php';
25 require_once 'adodb-pear.inc.php';
26 require_once 'adodb-errorpear.inc.php';
27
28 /**
29 * Storage driver for fetching login data from a database using ADOdb-PHP.
30 *
31 * This storage driver can use all databases which are supported
32 * by the ADBdb DB abstraction layer to fetch login data.
33 * See http://php.weblogs.com/adodb for information on ADOdb.
34 * NOTE: The ADOdb directory MUST be in your PHP include_path!
35 *
36 * @author Richard Tango-Lowy <richtl@arscognita.com>
37 * @package Auth
38 * @version $Revision$
39 */
40 class Auth_Container_ADOdb extends Auth_Container
41 {
42
43 /**
44 * Additional options for the storage container
45 * @var array
46 */
47 var $options = array();
48
49 /**
50 * DB object
51 * @var object
52 */
53 var $db = null;
54 var $dsn = '';
55
56 /**
57 * User that is currently selected from the DB.
58 * @var string
59 */
60 var $activeUser = '';
61
62 // {{{ Constructor
63
64 /**
65 * Constructor of the container class
66 *
67 * Initate connection to the database via PEAR::ADOdb
68 *
69 * @param string Connection data or DB object
70 * @return object Returns an error object if something went wrong
71 */
72 function Auth_Container_ADOdb($dsn)
73 {
74 $this->_setDefaults();
75
76 if (is_array($dsn)) {
77 $this->_parseOptions($dsn);
78
79 if (empty($this->options['dsn'])) {
80 PEAR::raiseError('No connection parameters specified!');
81 }
82 } else {
83 // Extract db_type from dsn string.
84 $this->options['dsn'] = $dsn;
85 }
86 }
87
88 // }}}
89 // {{{ _connect()
90
91 /**
92 * Connect to database by using the given DSN string
93 *
94 * @access private
95 * @param string DSN string
96 * @return mixed Object on error, otherwise bool
97 */
98 function _connect($dsn)
99 {
100 if (is_string($dsn) || is_array($dsn)) {
101 if(!$this->db) {
102 $this->db = &ADONewConnection($dsn);
103 if( $err = ADODB_Pear_error() ) {
104 return PEAR::raiseError($err);
105 }
106 }
107
108 } else {
109 return PEAR::raiseError('The given dsn was not valid in file ' . __FILE__ . ' at line ' . __LINE__,
110 41,
111 PEAR_ERROR_RETURN,
112 null,
113 null
114 );
115 }
116
117 if(!$this->db) {
118 return PEAR::raiseError(ADODB_Pear_error());
119 } else {
120 return true;
121 }
122 }
123
124 // }}}
125 // {{{ _prepare()
126
127 /**
128 * Prepare database connection
129 *
130 * This function checks if we have already opened a connection to
131 * the database. If that's not the case, a new connection is opened.
132 *
133 * @access private
134 * @return mixed True or a DB error object.
135 */
136 function _prepare()
137 {
138 if(!$this->db) {
139 $res = $this->_connect($this->options['dsn']);
140 }
141 return true;
142 }
143
144 // }}}
145 // {{{ query()
146
147 /**
148 * Prepare query to the database
149 *
150 * This function checks if we have already opened a connection to
151 * the database. If that's not the case, a new connection is opened.
152 * After that the query is passed to the database.
153 *
154 * @access public
155 * @param string Query string
156 * @return mixed a DB_result object or DB_OK on success, a DB
157 * or PEAR error on failure
158 */
159 function query($query)
160 {
161 $err = $this->_prepare();
162 if ($err !== true) {
163 return $err;
164 }
165 return $this->db->query($query);
166 }
167
168 // }}}
169 // {{{ _setDefaults()
170
171 /**
172 * Set some default options
173 *
174 * @access private
175 * @return void
176 */
177 function _setDefaults()
178 {
179 $this->options['db_type'] = 'mysql';
180 $this->options['table'] = 'auth';
181 $this->options['usernamecol'] = 'username';
182 $this->options['passwordcol'] = 'password';
183 $this->options['dsn'] = '';
184 $this->options['db_fields'] = '';
185 $this->options['cryptType'] = 'md5';
186 }
187
188 // }}}
189 // {{{ _parseOptions()
190
191 /**
192 * Parse options passed to the container class
193 *
194 * @access private
195 * @param array
196 */
197 function _parseOptions($array)
198 {
199 foreach ($array as $key => $value) {
200 if (isset($this->options[$key])) {
201 $this->options[$key] = $value;
202 }
203 }
204
205 /* Include additional fields if they exist */
206 if(!empty($this->options['db_fields'])){
207 if(is_array($this->options['db_fields'])){
208 $this->options['db_fields'] = join($this->options['db_fields'], ', ');
209 }
210 $this->options['db_fields'] = ', '.$this->options['db_fields'];
211 }
212 }
213
214 // }}}
215 // {{{ fetchData()
216
217 /**
218 * Get user information from database
219 *
220 * This function uses the given username to fetch
221 * the corresponding login data from the database
222 * table. If an account that matches the passed username
223 * and password is found, the function returns true.
224 * Otherwise it returns false.
225 *
226 * @param string Username
227 * @param string Password
228 * @return mixed Error object or boolean
229 */
230 function fetchData($username, $password)
231 {
232 // Prepare for a database query
233 $err = $this->_prepare();
234 if ($err !== true) {
235 return PEAR::raiseError($err->getMessage(), $err->getCode());
236 }
237
238 // Find if db_fields contains a *, i so assume all col are selected
239 if(strstr($this->options['db_fields'], '*')){
240 $sql_from = "*";
241 }
242 else{
243 $sql_from = $this->options['usernamecol'] . ", ".$this->options['passwordcol'].$this->options['db_fields'];
244 }
245
246 $query = "SELECT ".$sql_from.
247 " FROM ".$this->options['table'].
248 " WHERE ".$this->options['usernamecol']." = " . $this->db->Quote($username);
249
250 $ADODB_FETCH_MODE = ADODB_FETCH_ASSOC;
251 $rset = $this->db->Execute( $query );
252 $res = $rset->fetchRow();
253
254 if (DB::isError($res)) {
255 return PEAR::raiseError($res->getMessage(), $res->getCode());
256 }
257 if (!is_array($res)) {
258 $this->activeUser = '';
259 return false;
260 }
261 if ($this->verifyPassword(trim($password, "\r\n"),
262 trim($res[$this->options['passwordcol']], "\r\n"),
263 $this->options['cryptType'])) {
264 // Store additional field values in the session
265 foreach ($res as $key => $value) {
266 if ($key == $this->options['passwordcol'] ||
267 $key == $this->options['usernamecol']) {
268 continue;
269 }
270 // Use reference to the auth object if exists
271 // This is because the auth session variable can change so a static call to setAuthData does not make sence
272 if(is_object($this->_auth_obj)){
273 $this->_auth_obj->setAuthData($key, $value);
274 } else {
275 Auth::setAuthData($key, $value);
276 }
277 }
278
279 return true;
280 }
281
282 $this->activeUser = $res[$this->options['usernamecol']];
283 return false;
284 }
285
286 // }}}
287 // {{{ listUsers()
288
289 function listUsers()
290 {
291 $err = $this->_prepare();
292 if ($err !== true) {
293 return PEAR::raiseError($err->getMessage(), $err->getCode());
294 }
295
296 $retVal = array();
297
298 // Find if db_fileds contains a *, i so assume all col are selected
299 if(strstr($this->options['db_fields'], '*')){
300 $sql_from = "*";
301 }
302 else{
303 $sql_from = $this->options['usernamecol'] . ", ".$this->options['passwordcol'].$this->options['db_fields'];
304 }
305
306 $query = sprintf("SELECT %s FROM %s",
307 $sql_from,
308 $this->options['table']
309 );
310 $res = $this->db->getAll($query, null, DB_FETCHMODE_ASSOC);
311
312 if (DB::isError($res)) {
313 return PEAR::raiseError($res->getMessage(), $res->getCode());
314 } else {
315 foreach ($res as $user) {
316 $user['username'] = $user[$this->options['usernamecol']];
317 $retVal[] = $user;
318 }
319 }
320 return $retVal;
321 }
322
323 // }}}
324 // {{{ addUser()
325
326 /**
327 * Add user to the storage container
328 *
329 * @access public
330 * @param string Username
331 * @param string Password
332 * @param mixed Additional information that are stored in the DB
333 *
334 * @return mixed True on success, otherwise error object
335 */
336 function addUser($username, $password, $additional = "")
337 {
338 if (function_exists($this->options['cryptType'])) {
339 $cryptFunction = $this->options['cryptType'];
340 } else {
341 $cryptFunction = 'md5';
342 }
343
344 $additional_key = '';
345 $additional_value = '';
346
347 if (is_array($additional)) {
348 foreach ($additional as $key => $value) {
349 $additional_key .= ', ' . $key;
350 $additional_value .= ", '" . $value . "'";
351 }
352 }
353
354 $query = sprintf("INSERT INTO %s (%s, %s%s) VALUES ('%s', '%s'%s)",
355 $this->options['table'],
356 $this->options['usernamecol'],
357 $this->options['passwordcol'],
358 $additional_key,
359 $username,
360 $cryptFunction($password),
361 $additional_value
362 );
363
364 $res = $this->query($query);
365
366 if (DB::isError($res)) {
367 return PEAR::raiseError($res->getMessage(), $res->getCode());
368 } else {
369 return true;
370 }
371 }
372
373 // }}}
374 // {{{ removeUser()
375
376 /**
377 * Remove user from the storage container
378 *
379 * @access public
380 * @param string Username
381 *
382 * @return mixed True on success, otherwise error object
383 */
384 function removeUser($username)
385 {
386 $query = sprintf("DELETE FROM %s WHERE %s = '%s'",
387 $this->options['table'],
388 $this->options['usernamecol'],
389 $username
390 );
391
392 $res = $this->query($query);
393
394 if (DB::isError($res)) {
395 return PEAR::raiseError($res->getMessage(), $res->getCode());
396 } else {
397 return true;
398 }
399 }
400
401 // }}}
402 }
403
404 function showDbg( $string ) {
405 print "
406 -- $string</P>";
407 }
408 function dump( $var, $str, $vardump = false ) {
409 print "<H4>$str</H4><pre>";
410 ( !$vardump ) ? ( print_r( $var )) : ( var_dump( $var ));
411 print "</pre>";
412 }
413 ?>