Project

General

Profile

1
<?php
2
/**
3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
4
 *
5
 * 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
 *
10
 * 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
 */
18
/**
19
 * WbDatabase.php
20
 *
21
 * @category     Core
22
 * @package      Core_database
23
 * @author       Manuela v.d.Decken <manuela@isteam.de>
24
 * @author       Dietmar W. <dietmar.woellbrink@websitebaker.org>
25
 * @copyright    Manuela v.d.Decken <manuela@isteam.de>
26
 * @license      http://www.gnu.org/licenses/gpl.html   GPL License
27
 * @version      0.0.9
28
 * @revision     $Revision: 2120 $
29
 * @lastmodified $Date: 2015-03-10 18:16:46 +0100 (Tue, 10 Mar 2015) $
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
/* -------------------------------------------------------- */
35
@define('DATABASE_CLASS_LOADED', true);
36
	/* 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

    
50
class WbDatabase extends WbDatabaseHelper {
51

    
52
	private static $_oInstances = array();
53

    
54
	protected $oDbHandle    = null; // readonly from outside
55
	protected $sDbName      = '';
56
	protected $sInstanceIdentifier = '';
57
	protected $sTablePrefix = '';
58
	protected $sCharset     = '';
59
	protected $connected    = false;
60
	protected $error        = '';
61
	protected $error_type   = '';
62
	protected $iQueryCount  = 0;
63

    
64
/**
65
 * __constructor
66
 *  prevent from public instancing
67
 */
68
	final private function  __construct() {}
69
/**
70
 * prevent from cloning
71
 */
72
	final private function __clone() {}
73
/**
74
 * get a valid instance of this class
75
 * @param string $sIdentifier selector for several different instances
76
 * @return WbDatabase object
77
 */
78
	final public static function getInstance($sIdentifier = 'core')
79
	{
80
		if( !isset(self::$_oInstances[$sIdentifier])) {
81
            $c = __CLASS__;
82
			$oInstance = new $c;
83
			$oInstance->sInstanceIdentifier = $sIdentifier;
84
            self::$_oInstances[$sIdentifier] = $oInstance;
85
		}
86
		return self::$_oInstances[$sIdentifier];
87
	}
88
/**
89
 * disconnect and kills an existing instance
90
 * @param string $sIdentifier selector for instance to kill
91
 */
92
	final public static function killInstance($sIdentifier)
93
	{
94
		if($sIdentifier != 'core') {
95
			if( isset(self::$_oInstances[$sIdentifier])) {
96
				self::$_oInstances[$sIdentifier]->disconnect();
97
				unset(self::$_oInstances[$sIdentifier]);
98
			}
99
		}
100
	}
101
/**
102
 * Establish connection
103
 * @param string $url
104
 * @return bool
105
 * @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
 */
109
	public function doConnect($url = '')
110
	{
111
		if ($this->connected) { return $this->connected; } // prevent from reconnecting
112
		$this->connected = false;
113
		if ($url != '') {
114
		// parse URL and extract connection data
115
			$aIni = parse_url($url);
116
			$scheme   = isset($aIni['scheme']) ? $aIni['scheme'] : 'mysqli';
117
			$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
			$hostport = $hostport == '3306' ? null : $hostport;
122
			$db_name  = ltrim(isset($aIni['path']) ? $aIni['path'] : '', '/\\');
123
			$sTmp = isset($aIni['query']) ? $aIni['query'] : '';
124
			$aQuery = explode('&', $sTmp);
125
			foreach ($aQuery as $sArgument) {
126
				$aArg = explode('=', $sArgument);
127
				switch (strtolower($aArg[0])) {
128
					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
			$this->sDbName = $db_name;
139
		} else {
140
			throw new WbDatabaseException('Missing parameter: unable to connect database');
141
		}
142
		$this->oDbHandle = @mysqli_connect($hostname, $username, $password, $db_name, $hostport);
143
		if (!$this->oDbHandle) {
144
			throw new WbDatabaseException('unable to connect \''.$scheme.'://'.$hostname.':'.$hostport.'\'');
145
		} else {
146
            if ($this->sCharset) {
147
                @mysqli_query($this->oDbHandle, 'SET NAMES '.$this->sCharset);
148
                mysqli_set_charset($this->oDbHandle, $this->sCharset);
149
            }
150
            $this->connected = true;
151
		}
152
		return $this->connected;
153
	}
154
/**
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
			mysqli_close($this->oDbHandle);
164
			$this->connected = false;
165
			return true;
166
		}
167
		return false;
168
	}
169
/**
170
 * Alias for doQuery()
171
 * @deprecated from WB-2.8.5 and higher
172
 */
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
		$this->iQueryCount++;
184
		$mysql = new mysql($this->oDbHandle);
185
		$mysql->query($statement);
186
		$this->set_error($mysql->error($this->oDbHandle));
187
		if ($mysql->error()) {
188
			return null;
189
		} else {
190
			return $mysql;
191
		}
192
	}
193
/**
194
 * Alias for getOne()
195
 * @deprecated from WB-2.8.5 and higher
196
 */
197
	public function get_one( $statement )
198
	{
199
		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
		$this->iQueryCount++;
210
		$fetch_row = mysqli_fetch_array(mysqli_query($this->oDbHandle, $statement));
211
		$result = $fetch_row[0];
212
		$this->set_error(null);
213
		if (mysqli_error($this->oDbHandle)) {
214
    		$this->set_error(mysqli_error($this->oDbHandle));
215
			return null;
216
		} else {
217
			return $result;
218
		}
219
	}
220
/**
221
 * Alias for setError()
222
 * @deprecated from WB-2.8.5 and higher
223
 */
224
	public function set_error($message = null)
225
	{
226
		$this->setError($message = null);
227
	}
228
	// Set the DB error
229
/**
230
 * setError
231
 * @param string $message
232
 */
233
	public function setError($message = null)
234
	{
235
		$this->error = $message;
236
	}
237
/**
238
 * Alias for isError
239
 * @deprecated from WB-2.8.5 and higher
240
 */
241
	public function is_error()
242
	{
243
		return $this->isError();
244
	}
245
/**
246
 * isError
247
 * @return bool
248
 */
249
	public function isError()
250
	{
251
		return (!empty($this->error)) ? true : false;
252
	}
253
/**
254
 * Alias for getError
255
 * @deprecated from WB-2.8.5 and higher
256
 */
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
		return $this->error;
268
	}
269
/**
270
 * Protect class from property injections
271
 * @param string name of property
272
 * @param mixed value
273
 * @throws WbDatabaseException
274
 */	
275
	public function __set($name, $value)
276
	{
277
		throw new WbDatabaseException('tried to set a readonly or nonexisting property ['.$name.']!! ');
278
	}
279
/**
280
 * default Getter for some properties
281
 * @param string name of the Property
282
 * @return NULL on error | valid property
283
 */
284
	public function __get($sPropertyName)
285
	{
286
		switch ($sPropertyName) {
287
			case 'DbHandle':
288
			case 'getDbHandle': // << set deprecated
289
			case 'db_handle': // << set deprecated
290
				$retval = $this->oDbHandle;
291
				break;
292
			case 'LastInsertId':
293
			case 'getLastInsertId': // << set deprecated
294
				$retval = $this->getLastInsertId();
295
				break;
296
			case 'DbName':
297
			case 'getDbName': // << set deprecated
298
			case 'db_name': // << set deprecated
299
				$retval = $this->sDbName;
300
				break;
301
			case 'TablePrefix':
302
			case 'getTablePrefix': // << set deprecated
303
				$retval = $this->sTablePrefix;			
304
				break;
305
			case 'QueryCount':
306
			case 'getQueryCount': // << set deprecated
307
				$retval = $this->iQueryCount;
308
				break;
309
			default:
310
				$retval = null;
311
				break;
312
		}
313
		return $retval;
314
	} // __get()
315
/**
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
		return mysqli_real_escape_string($this->oDbHandle, $unescaped_string);
323
	}
324
/**
325
 * Last inserted Id
326
 * @return bool|int false on error, 0 if no record inserted
327
 */	
328
	public function getLastInsertId()
329
	{
330
		return mysqli_insert_id($this->oDbHandle);
331
	}
332

    
333
} /// end of class database
334
// //////////////////////////////////////////////////////////////////////////////////// //
335
/**
336
 * WbDatabaseException
337
 *
338
 * @category     Core
339
 * @package      Core_database
340
 * @author       Manuela v.d.Decken <manuela@isteam.de>
341
 * @copyright    Manuela v.d.Decken <manuela@isteam.de>
342
 * @license      http://www.gnu.org/licenses/gpl.html   GPL License
343
 * @version      2.9.0
344
 * @revision     $Revision: 2120 $
345
 * @lastmodified $Date: 2015-03-10 18:16:46 +0100 (Tue, 10 Mar 2015) $
346
 * @description  Exceptionhandler for the WbDatabase and depending classes
347
 */
348
class WbDatabaseException extends AppException {}
349

    
350
/* 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

    
354
/**
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: 2120 $
364
 * @lastmodified $Date: 2015-03-10 18:16:46 +0100 (Tue, 10 Mar 2015) $
365
 * @description  MYSQL result object for requests
366
 *
367
 */
368
class mysql {
369

    
370
	private $result    = null;
371
	private $oDbHandle = null;
372
    private $error     = '';
373

    
374
    public function __construct($oHandle)
375
    {
376
        $this->oDbHandle = $oHandle;
377
    }
378
/**
379
 * query sql statement
380
 * @param  string $statement
381
 * @return object
382
 * @throws WbDatabaseException
383
 */
384
	public function query($sStatement)
385
	{
386
		$this->result = @mysqli_query($this->oDbHandle, $sStatement);
387
		if ($this->result === false) {
388
			if (DEBUG) {
389
				throw new WbDatabaseException(mysqli_error($this->oDbHandle));
390
			} else {
391
				throw new WbDatabaseException('Error in SQL-Statement');
392
			}
393
		}
394
		$this->error = mysqli_error($this->oDbHandle);
395
		return $this->result;
396
	}
397
/**
398
 * numRows
399
 * @return integer
400
 * @description number of returned records
401
 */
402
	public function numRows()
403
	{
404
		return mysqli_num_rows($this->result);
405
	}
406
/**
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
	public function fetchRow($typ = MYSQLI_BOTH)
413
	{
414
		return mysqli_fetch_array($this->result, $typ);
415
	}
416
/**
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
	public function fetchObject($sClassName = null, array $aParams = null)
424
	{
425
		if ($sClassName === null || class_exists($sClassName)) {
426
			return mysqli_fetch_object($this->result, $sClassName, $aParams);
427
		} else {
428
			throw new WbDatabaseException('Class <'.$sClassName.'> not available on request of mysql_fetch_object()');
429
		}
430
	}
431
/**
432
 * 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
 * rewind
457
 * @return bool
458
 * @description set the recordpointer to the first record || false on error
459
 */
460
	public function rewind()
461
	{
462
		return $this->seekRow(MYSQL_SEEK_FIRST);
463
	}
464
/**
465
 * seekRow
466
 * @param int $position
467
 * @return bool
468
 * @description set the pointer to the given record || false on error
469
 */
470
	public function seekRow( $position = MYSQL_SEEK_FIRST )
471
	{
472
		$pmax = $this->numRows() - 1;
473
		$p = (($position < 0 || $position > $pmax) ? $pmax : $position);
474
		return mysqli_data_seek($this->result, $p);
475
	}
476
/**
477
 * freeResult
478
 * @return bool
479
 * @description remove retult object from memeory
480
 */
481
	public function freeResult()
482
	{
483
		return mysqli_free_result($this->result);
484
	}
485
/** 
486
 * Get error
487
 * @return string || null if no error
488
 */
489
	public function error()
490
	{
491
		if (isset($this->error)) {
492
			return $this->error;
493
		} else {
494
			return null;
495
		}
496
	}
497

    
498
}
499
// //////////////////////////////////////////////////////////////////////////////////// //
500
/* 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
		$oDb = WbDatabase::getInstance();
512
        $table = preg_replace('/^'.preg_quote($oDb->TablePrefix, '/').'/s', '', $table);
513
		if (!is_array($key)) {
514
			if (trim($key) != '') {
515
				$key = array( trim($key) => trim($value) );
516
			} else {
517
				$key = array();
518
			}
519
		}
520
		$retval = true;
521
        $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
			if (!$oDb->doQuery($sql)) {
530
				$retval = false;
531
			}
532
        }
533
		return $retval;
534
	}
(19-19/38)