Project

General

Profile

1 4 ryan
<?php
2 1362 Luisehahne
/**
3 1866 Luisehahne
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4 1362 Luisehahne
 *
5 1866 Luisehahne
 * This program is free software: you can redistribute it and/or modify
6
 * it under the terms of the GNU General Public License as published by
7
 * the Free Software Foundation, either version 3 of the License, or
8
 * (at your option) any later version.
9 1362 Luisehahne
 *
10 1866 Luisehahne
 * This program is distributed in the hope that it will be useful,
11
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
 * GNU General Public License for more details.
14
 *
15
 * You should have received a copy of the GNU General Public License
16
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17 1362 Luisehahne
 */
18 1866 Luisehahne
/**
19
 * WbDatabase.php
20
 *
21
 * @category     Core
22
 * @package      Core_database
23 1998 darkviper
 * @author       Manuela v.d.Decken <manuela@isteam.de>
24 1866 Luisehahne
 * @author       Dietmar W. <dietmar.woellbrink@websitebaker.org>
25 1998 darkviper
 * @copyright    Manuela v.d.Decken <manuela@isteam.de>
26 1866 Luisehahne
 * @license      http://www.gnu.org/licenses/gpl.html   GPL License
27
 * @version      0.0.9
28
 * @revision     $Revision$
29
 * @lastmodified $Date$
30
 * @deprecated   from WB version number 2.9
31
 * @description  Mysql database wrapper for use with websitebaker up to version 2.8.4
32
 */
33
34 1496 DarkViper
/* -------------------------------------------------------- */
35 1885 Luisehahne
@define('DATABASE_CLASS_LOADED', true);
36 2104 darkviper
	/* define the old mysql consts for Backward compatibility */
37
	if (!defined('MYSQL_ASSOC'))
38
	{
39
		define('MYSQL_SEEK_LAST',            -1);
40
		define('MYSQL_SEEK_FIRST',            0);
41
		define('MYSQL_ASSOC',                 1);
42
		define('MYSQL_NUM',                   2);
43
		define('MYSQL_BOTH',                  3);
44
		define('MYSQL_CLIENT_COMPRESS',      32);
45
		define('MYSQL_CLIENT_IGNORE_SPACE', 256);
46
		define('MYSQL_CLIENT_INTERACTIVE', 1024);
47
		define('MYSQL_CLIENT_SSL',         2048);
48
	}
49 4 ryan
50 2120 darkviper
class WbDatabase extends WbDatabaseHelper {
51 1763 Luisehahne
52 1686 darkviper
	private static $_oInstances = array();
53 1680 darkviper
54 1998 darkviper
	protected $oDbHandle    = null; // readonly from outside
55
	protected $sDbName      = '';
56
	protected $sInstanceIdentifier = '';
57 1885 Luisehahne
	protected $sTablePrefix = '';
58 1889 Luisehahne
	protected $sCharset     = '';
59 1885 Luisehahne
	protected $connected    = false;
60
	protected $error        = '';
61
	protected $error_type   = '';
62
	protected $iQueryCount  = 0;
63 1362 Luisehahne
64 1998 darkviper
/**
65
 * __constructor
66
 *  prevent from public instancing
67
 */
68 2104 darkviper
	final private function  __construct() {}
69 1998 darkviper
/**
70
 * prevent from cloning
71
 */
72 2104 darkviper
	final private function __clone() {}
73 1683 darkviper
/**
74 1686 darkviper
 * get a valid instance of this class
75
 * @param string $sIdentifier selector for several different instances
76 1998 darkviper
 * @return WbDatabase object
77 1686 darkviper
 */
78 2104 darkviper
	final public static function getInstance($sIdentifier = 'core')
79 1998 darkviper
	{
80 1686 darkviper
		if( !isset(self::$_oInstances[$sIdentifier])) {
81
            $c = __CLASS__;
82 1974 darkviper
			$oInstance = new $c;
83 1998 darkviper
			$oInstance->sInstanceIdentifier = $sIdentifier;
84 1974 darkviper
            self::$_oInstances[$sIdentifier] = $oInstance;
85 1686 darkviper
		}
86
		return self::$_oInstances[$sIdentifier];
87
	}
88
/**
89
 * disconnect and kills an existing instance
90 1998 darkviper
 * @param string $sIdentifier selector for instance to kill
91 1686 darkviper
 */
92 2104 darkviper
	final public static function killInstance($sIdentifier)
93 1998 darkviper
	{
94 1686 darkviper
		if($sIdentifier != 'core') {
95
			if( isset(self::$_oInstances[$sIdentifier])) {
96
				self::$_oInstances[$sIdentifier]->disconnect();
97
				unset(self::$_oInstances[$sIdentifier]);
98
			}
99
		}
100
	}
101
/**
102 1998 darkviper
 * Establish connection
103 1683 darkviper
 * @param string $url
104
 * @return bool
105 1998 darkviper
 * @throws WbDatabaseException
106
 * @description opens a connection using connect URL<br />
107
 *              Example for SQL-Url:  'mysql://user:password@example.com[:3306]/database?charset=utf8&tableprefix=xx_'
108 1683 darkviper
 */
109 1998 darkviper
	public function doConnect($url = '')
110
	{
111
		if ($this->connected) { return $this->connected; } // prevent from reconnecting
112 1885 Luisehahne
		$this->connected = false;
113 1998 darkviper
		if ($url != '') {
114
		// parse URL and extract connection data
115 1680 darkviper
			$aIni = parse_url($url);
116 2120 darkviper
			$scheme   = isset($aIni['scheme']) ? $aIni['scheme'] : 'mysqli';
117 1866 Luisehahne
			$hostname = isset($aIni['host']) ? $aIni['host'] : '';
118
			$username = isset($aIni['user']) ? $aIni['user'] : '';
119
			$password = isset($aIni['pass']) ? $aIni['pass'] : '';
120
			$hostport = isset($aIni['port']) ? $aIni['port'] : '3306';
121 2104 darkviper
			$hostport = $hostport == '3306' ? null : $hostport;
122 1866 Luisehahne
			$db_name  = ltrim(isset($aIni['path']) ? $aIni['path'] : '', '/\\');
123 1885 Luisehahne
			$sTmp = isset($aIni['query']) ? $aIni['query'] : '';
124
			$aQuery = explode('&', $sTmp);
125 1998 darkviper
			foreach ($aQuery as $sArgument) {
126 1885 Luisehahne
				$aArg = explode('=', $sArgument);
127 1998 darkviper
				switch (strtolower($aArg[0])) {
128 1885 Luisehahne
					case 'charset':
129
						$this->sCharset = strtolower(preg_replace('/[^a-z0-9]/i', '', $aArg[1]));
130
						break;
131
					case 'tableprefix':
132
						$this->sTablePrefix = $aArg[1];
133
						break;
134
					default:
135
						break;
136
				}
137
			}
138 1998 darkviper
			$this->sDbName = $db_name;
139
		} else {
140 1885 Luisehahne
			throw new WbDatabaseException('Missing parameter: unable to connect database');
141 1680 darkviper
		}
142 2104 darkviper
		$this->oDbHandle = @mysqli_connect($hostname, $username, $password, $db_name, $hostport);
143 1998 darkviper
		if (!$this->oDbHandle) {
144 2104 darkviper
			throw new WbDatabaseException('unable to connect \''.$scheme.'://'.$hostname.':'.$hostport.'\'');
145 4 ryan
		} else {
146 2104 darkviper
            if ($this->sCharset) {
147 2120 darkviper
                @mysqli_query($this->oDbHandle, 'SET NAMES '.$this->sCharset);
148
                mysqli_set_charset($this->oDbHandle, $this->sCharset);
149 2104 darkviper
            }
150
            $this->connected = true;
151 4 ryan
		}
152
		return $this->connected;
153
	}
154 1998 darkviper
/**
155
 * disconnect database
156
 * @return bool
157
 * @description Disconnect current object from the database<br />
158
 *              the 'core' connection can NOT be disconnected!
159
 */
160
	public function disconnect()
161
	{
162
		if ($this->connected == true && $oInstance->sInstanceIdentifier != 'core') {
163 2104 darkviper
			mysqli_close($this->oDbHandle);
164 1974 darkviper
			$this->connected = false;
165 4 ryan
			return true;
166
		}
167 1974 darkviper
		return false;
168 4 ryan
	}
169 1998 darkviper
/**
170
 * Alias for doQuery()
171 2104 darkviper
 * @deprecated from WB-2.8.5 and higher
172 1998 darkviper
 */
173
	public function query($statement)
174
	{
175
		return $this->doQuery($statement);
176
	}
177
/**
178
 * execute query
179
 * @param string $statement the SQL-statement to execute
180
 * @return null|\mysql
181
 */
182
	public function doQuery($statement) {
183 1662 darkviper
		$this->iQueryCount++;
184 2104 darkviper
		$mysql = new mysql($this->oDbHandle);
185
		$mysql->query($statement);
186 1998 darkviper
		$this->set_error($mysql->error($this->oDbHandle));
187 2104 darkviper
		if ($mysql->error()) {
188 4 ryan
			return null;
189
		} else {
190
			return $mysql;
191
		}
192
	}
193 1998 darkviper
/**
194
 * Alias for getOne()
195 2104 darkviper
 * @deprecated from WB-2.8.5 and higher
196 1998 darkviper
 */
197 1686 darkviper
	public function get_one( $statement )
198 1362 Luisehahne
	{
199 1998 darkviper
		return $this->getOne($statement);
200
	}
201
	// Gets the first column of the first row
202
/**
203
 * Gets the first column of the first row
204
 * @param string $statement  SQL-statement
205
 * @return null|mixed
206
 */
207
	public function getOne( $statement )
208
	{
209 1662 darkviper
		$this->iQueryCount++;
210 2104 darkviper
		$fetch_row = mysqli_fetch_array(mysqli_query($this->oDbHandle, $statement));
211 4 ryan
		$result = $fetch_row[0];
212 2104 darkviper
		$this->set_error(null);
213
		if (mysqli_error($this->oDbHandle)) {
214
    		$this->set_error(mysqli_error($this->oDbHandle));
215 4 ryan
			return null;
216
		} else {
217
			return $result;
218
		}
219
	}
220 1998 darkviper
/**
221
 * Alias for setError()
222 2104 darkviper
 * @deprecated from WB-2.8.5 and higher
223 1998 darkviper
 */
224
	public function set_error($message = null)
225
	{
226
		$this->setError($message = null);
227
	}
228 4 ryan
	// Set the DB error
229 1998 darkviper
/**
230
 * setError
231
 * @param string $message
232
 */
233
	public function setError($message = null)
234
	{
235 4 ryan
		$this->error = $message;
236
	}
237 1998 darkviper
/**
238
 * Alias for isError
239 2104 darkviper
 * @deprecated from WB-2.8.5 and higher
240 1998 darkviper
 */
241
	public function is_error()
242
	{
243
		return $this->isError();
244
	}
245
/**
246
 * isError
247
 * @return bool
248
 */
249
	public function isError()
250
	{
251 4 ryan
		return (!empty($this->error)) ? true : false;
252
	}
253 1998 darkviper
/**
254
 * Alias for getError
255 2104 darkviper
 * @deprecated from WB-2.8.5 and higher
256 1998 darkviper
 */
257
	public function get_error()
258
	{
259
		return $this->getError();
260
	}
261
/**
262
 * get last Error
263
 * @return string
264
 */
265
	public function getError()
266
	{
267 4 ryan
		return $this->error;
268
	}
269 1613 darkviper
/**
270 1885 Luisehahne
 * Protect class from property injections
271
 * @param string name of property
272
 * @param mixed value
273
 * @throws WbDatabaseException
274 1866 Luisehahne
 */
275 1998 darkviper
	public function __set($name, $value)
276
	{
277 1885 Luisehahne
		throw new WbDatabaseException('tried to set a readonly or nonexisting property ['.$name.']!! ');
278 1866 Luisehahne
	}
279
/**
280 1613 darkviper
 * default Getter for some properties
281 1866 Luisehahne
 * @param string name of the Property
282 1998 darkviper
 * @return NULL on error | valid property
283 1362 Luisehahne
 */
284 1613 darkviper
	public function __get($sPropertyName)
285 1362 Luisehahne
	{
286 1998 darkviper
		switch ($sPropertyName) {
287 1613 darkviper
			case 'DbHandle':
288 1998 darkviper
			case 'getDbHandle': // << set deprecated
289
			case 'db_handle': // << set deprecated
290
				$retval = $this->oDbHandle;
291 1613 darkviper
				break;
292 1866 Luisehahne
			case 'LastInsertId':
293 1998 darkviper
			case 'getLastInsertId': // << set deprecated
294 2104 darkviper
				$retval = $this->getLastInsertId();
295 1866 Luisehahne
				break;
296 1613 darkviper
			case 'DbName':
297 1998 darkviper
			case 'getDbName': // << set deprecated
298
			case 'db_name': // << set deprecated
299
				$retval = $this->sDbName;
300 1613 darkviper
				break;
301 1885 Luisehahne
			case 'TablePrefix':
302 1998 darkviper
			case 'getTablePrefix': // << set deprecated
303 1885 Luisehahne
				$retval = $this->sTablePrefix;
304
				break;
305 1974 darkviper
			case 'QueryCount':
306 1998 darkviper
			case 'getQueryCount': // << set deprecated
307 1662 darkviper
				$retval = $this->iQueryCount;
308
				break;
309 1613 darkviper
			default:
310
				$retval = null;
311
				break;
312 1998 darkviper
		}
313 1613 darkviper
		return $retval;
314
	} // __get()
315 1885 Luisehahne
/**
316
 * Escapes special characters in a string for use in an SQL statement
317
 * @param string $unescaped_string
318
 * @return string
319
 */
320
	public function escapeString($unescaped_string)
321
	{
322 2104 darkviper
		return mysqli_real_escape_string($this->oDbHandle, $unescaped_string);
323 1885 Luisehahne
	}
324
/**
325
 * Last inserted Id
326
 * @return bool|int false on error, 0 if no record inserted
327
 */
328
	public function getLastInsertId()
329
	{
330 2104 darkviper
		return mysqli_insert_id($this->oDbHandle);
331 1885 Luisehahne
	}
332 1362 Luisehahne
333
} /// end of class database
334 1885 Luisehahne
// //////////////////////////////////////////////////////////////////////////////////// //
335
/**
336
 * WbDatabaseException
337
 *
338
 * @category     Core
339
 * @package      Core_database
340 1998 darkviper
 * @author       Manuela v.d.Decken <manuela@isteam.de>
341
 * @copyright    Manuela v.d.Decken <manuela@isteam.de>
342 1885 Luisehahne
 * @license      http://www.gnu.org/licenses/gpl.html   GPL License
343
 * @version      2.9.0
344
 * @revision     $Revision$
345
 * @lastmodified $Date$
346
 * @description  Exceptionhandler for the WbDatabase and depending classes
347
 */
348
class WbDatabaseException extends AppException {}
349 1362 Luisehahne
350 1998 darkviper
/* extend global constants of mysql */
351
if(!defined('MYSQL_SEEK_FIRST')) { define('MYSQL_SEEK_FIRST', 0); }
352
if(!defined('MYSQL_SEEK_LAST')) { define('MYSQL_SEEK_LAST', -1); }
353 1549 Luisehahne
354 1998 darkviper
/**
355
 * mysql
356
 *
357
 * @category     Core
358
 * @package      Core_database
359
 * @author       Manuela v.d.Decken <manuela@isteam.de>
360
 * @copyright    Manuela v.d.Decken <manuela@isteam.de>
361
 * @license      http://www.gnu.org/licenses/gpl.html   GPL License
362
 * @version      2.9.0
363
 * @revision     $Revision$
364
 * @lastmodified $Date$
365
 * @description  MYSQL result object for requests
366
 *
367
 */
368 4 ryan
class mysql {
369
370 2104 darkviper
	private $result    = null;
371 2011 darkviper
	private $oDbHandle = null;
372 2104 darkviper
    private $error     = '';
373 1998 darkviper
374 2104 darkviper
    public function __construct($oHandle)
375
    {
376
        $this->oDbHandle = $oHandle;
377
    }
378 1998 darkviper
/**
379
 * query sql statement
380
 * @param  string $statement
381
 * @return object
382
 * @throws WbDatabaseException
383
 */
384 2120 darkviper
	public function query($sStatement)
385 1998 darkviper
	{
386 2104 darkviper
		$this->result = @mysqli_query($this->oDbHandle, $sStatement);
387 1998 darkviper
		if ($this->result === false) {
388
			if (DEBUG) {
389 2104 darkviper
				throw new WbDatabaseException(mysqli_error($this->oDbHandle));
390 1998 darkviper
			} else {
391 1889 Luisehahne
				throw new WbDatabaseException('Error in SQL-Statement');
392
			}
393
		}
394 2104 darkviper
		$this->error = mysqli_error($this->oDbHandle);
395 4 ryan
		return $this->result;
396
	}
397 1998 darkviper
/**
398
 * numRows
399
 * @return integer
400
 * @description number of returned records
401
 */
402 2120 darkviper
	public function numRows()
403 1998 darkviper
	{
404 2104 darkviper
		return mysqli_num_rows($this->result);
405 4 ryan
	}
406 1998 darkviper
/**
407
 * fetchRow
408
 * @param  int $typ MYSQL_BOTH(default) | MYSQL_ASSOC | MYSQL_NUM
409
 * @return array
410
 * @description get current record and increment pointer
411
 */
412 2120 darkviper
	public function fetchRow($typ = MYSQLI_BOTH)
413 1998 darkviper
	{
414 2104 darkviper
		return mysqli_fetch_array($this->result, $typ);
415 4 ryan
	}
416 1998 darkviper
/**
417
 * fetchObject
418
 * @param  string $sClassname Name of the class to use. Is no given use stdClass
419
 * @param  string $aParams    optional array of arguments for the constructor
420
 * @return object
421
 * @description get current record as an object and increment pointer
422
 */
423 2120 darkviper
	public function fetchObject($sClassName = null, array $aParams = null)
424 1998 darkviper
	{
425 2011 darkviper
		if ($sClassName === null || class_exists($sClassName)) {
426 2104 darkviper
			return mysqli_fetch_object($this->result, $sClassName, $aParams);
427 2011 darkviper
		} else {
428
			throw new WbDatabaseException('Class <'.$sClassName.'> not available on request of mysql_fetch_object()');
429
		}
430 1998 darkviper
	}
431
/**
432 2120 darkviper
 * fetchArray
433
 * @param  int $iType MYSQL_ASSOC(default) | MYSQL_BOTH | MYSQL_NUM
434
 * @return array of current record
435
 * @description get current record and increment pointer
436
 */
437
	public function fetchArray($iType = MYSQLI_ASSOC)
438
	{
439
        if ($iType < MYSQLI_ASSOC || $iType > MYSQLI_BOTH) {
440
            $iType = MYSQLI_ASSOC;
441
        }
442
		return mysqli_fetch_array($this->result, $iType);
443
	}
444
/**
445
 * fetchAll
446
 * @param  int $iType MYSQL_ASSOC(default) | MYSQL_NUM
447
 * @return array of rows
448
 * @description get all records of the result set
449
 */
450
    public function fetchAll($iType = MYSQL_ASSOC)
451
    {
452
        $iType = $iType != MYSQL_NUM ? MYSQL_ASSOC : MYSQL_NUM;
453
        return mysqli_fetch_all($this->result, $iType);
454
    }
455
/**
456 1998 darkviper
 * rewind
457
 * @return bool
458
 * @description set the recordpointer to the first record || false on error
459
 */
460 2120 darkviper
	public function rewind()
461 1549 Luisehahne
	{
462 1998 darkviper
		return $this->seekRow(MYSQL_SEEK_FIRST);
463 1549 Luisehahne
	}
464 1998 darkviper
/**
465
 * seekRow
466
 * @param int $position
467
 * @return bool
468
 * @description set the pointer to the given record || false on error
469
 */
470 2120 darkviper
	public function seekRow( $position = MYSQL_SEEK_FIRST )
471 1549 Luisehahne
	{
472
		$pmax = $this->numRows() - 1;
473
		$p = (($position < 0 || $position > $pmax) ? $pmax : $position);
474 2104 darkviper
		return mysqli_data_seek($this->result, $p);
475 1549 Luisehahne
	}
476 1998 darkviper
/**
477
 * freeResult
478
 * @return bool
479
 * @description remove retult object from memeory
480
 */
481 2120 darkviper
	public function freeResult()
482 1998 darkviper
	{
483 2104 darkviper
		return mysqli_free_result($this->result);
484 1998 darkviper
	}
485
/**
486
 * Get error
487
 * @return string || null if no error
488
 */
489 2120 darkviper
	public function error()
490 1998 darkviper
	{
491
		if (isset($this->error)) {
492 4 ryan
			return $this->error;
493
		} else {
494
			return null;
495
		}
496
	}
497
498
}
499 1885 Luisehahne
// //////////////////////////////////////////////////////////////////////////////////// //
500 1364 Luisehahne
/* this function is placed inside this file temporarely until a better place is found */
501
/*  function to update a var/value-pair(s) in table ****************************
502
 *  nonexisting keys are inserted
503
 *  @param string $table: name of table to use (without prefix)
504
 *  @param mixed $key:    a array of key->value pairs to update
505
 *                        or a string with name of the key to update
506
 *  @param string $value: a sting with needed value, if $key is a string too
507
 *  @return bool:  true if any keys are updated, otherwise false
508
 */
509
	function db_update_key_value($table, $key, $value = '')
510
	{
511 1998 darkviper
		$oDb = WbDatabase::getInstance();
512 2120 darkviper
        $table = preg_replace('/^'.preg_quote($oDb->TablePrefix, '/').'/s', '', $table);
513 1998 darkviper
		if (!is_array($key)) {
514
			if (trim($key) != '') {
515 1364 Luisehahne
				$key = array( trim($key) => trim($value) );
516
			} else {
517
				$key = array();
518
			}
519
		}
520
		$retval = true;
521 2104 darkviper
        $sNameValPairs = '';
522
		foreach ($key as $index => $val) {
523
            $sNameValPairs .= ', (\''.$index.'\', \''.$val.'\')';
524
        }
525
        $sValues = ltrim($sNameValPairs, ', ');
526
        if ($sValues != '') {
527
            $sql = 'REPLACE INTO `'.$oDb->TablePrefix.$table.'` (`name`, `value`) '
528
                 . 'VALUES '.$sValues;
529 1998 darkviper
			if (!$oDb->doQuery($sql)) {
530 1364 Luisehahne
				$retval = false;
531
			}
532 2104 darkviper
        }
533 1364 Luisehahne
		return $retval;
534
	}