TDbParameterModule::getAutoLoadValueFalse()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 2
b 0
f 0
nc 1
nop 0
dl 0
loc 3
rs 10
1
<?php
2
3
/**
4
 * TDbParameterModule class
5
 *
6
 * @author Brad Anderson <[email protected]>
7
 * @link https://github.com/pradosoft/prado
8
 * @license https://github.com/pradosoft/prado/blob/master/LICENSE
9
 */
10
11
namespace Prado\Util;
12
13
use Exception;
14
use PDO;
15
use Prado\Data\TDataSourceConfig;
16
use Prado\Data\TDbConnection;
17
use Prado\Exceptions\TConfigurationException;
18
use Prado\Exceptions\TInvalidDataTypeException;
19
use Prado\Exceptions\TInvalidOperationException;
20
use Prado\TModule;
21
use Prado\TPropertyValue;
22
use Prado\Security\Permissions\IPermissions;
23
use Prado\Security\Permissions\TPermissionEvent;
24
use Prado\Util\Behaviors\TMapLazyLoadBehavior;
25
use Prado\Util\Behaviors\TMapRouteBehavior;
26
27
/**
28
 * TDbParameterModule class
29
 *
30
 * This loads application parameters from a database.  It adds the
31
 * {@see \Prado\Util\Behaviors\TMapLazyLoadBehavior} to Application Parameters when the
32
 * {@see setAutoLoadField} is set.  The key and name fields, table,
33
 * autoload field, and autoload values (both true and false values)
34
 * are parameterized.  Set them to your application specific values.
35
 *
36
 * The following will load the options from a WordPress Database:
37
 * ```xml
38
 *		<module id="dbparams" class="Prado\Util\TDbParameterModule"
39
 * ConnectionID="DB" KeyField="option_name" ValueField="option_value" TableName="wp_options" Serializer="php"
40
 * autoLoadField="autoload" autoLoadValue="'yes'" autoLoadValueFalse="'no'"/>
41
 * ```
42
 *
43
 * This allows for setting and removal of application parameters
44
 * into and from the database through {@see set} and
45
 * {@see remove}, respectively. Arrays and Objects are
46
 * serialized.  The specific serializer can be chose to be 'php',
47
 * 'json', or provide your own function or callable.  Default to 'php'.
48
 *
49
 * setting {@see setSerializer} to your own function that has the
50
 * following format:
51
 * ```php
52
 *		function mySerializerFunction($data, $encode) {...}
53
 * ```
54
 * If $encode is true, then encode, otherwise decode, to text.
55
 *
56
 * When {@see getCaptureParameterChanges} is true, the default,
57
 * then this will route any changes to the Application Parameters
58
 * after TPageService::onPreRunPage back to the TDbParameterModule
59
 * and be saved to the database.  This captures any changes when
60
 * done by the page or user.  These changes are restored when
61
 * this module is loaded again.
62
 *
63
 * When TPermissionsManager is a module in your app, there is one permission
64
 * to control user access to its function:
65
 *  - TDbParameterModule::PERM_PARAM_SHELL 'param_shell' enables the shell command to index, get and set database parameters.
66
 *
67
 * The role and rule management functions only work when the TDbParameter Module is specified.
68
 * The following gives user "admin" and all users with "Administrators" role the
69
 * permission to access permissions shell and its full functionality:
70
 * ```xml
71
 *   <permissionrule name="param_shell" action="allow" users="admin" />
72
 *   <permissionrule name="param_shell" action="allow" roles="Administrators" />
73
 * ```
74
 *
75
 * @author Brad Anderson <[email protected]>
76
 * @since 4.2.0
77
 * @method bool dyRegisterShellAction($returnValue)
78
 */
79
class TDbParameterModule extends TModule implements IDbModule, IPermissions
80
{
81
	public const SERIALIZE_PHP = 'php';
82
83
	public const SERIALIZE_JSON = 'json';
84
85
	/** The permission for the cron shell */
86
	public const PERM_PARAM_SHELL = 'param_shell';
87
88
	/**
89
	 * The name of the Application Parameter Lazy Load Behavior
90
	 */
91
	public const APP_PARAMETER_LAZY_BEHAVIOR = 'lazyTDbParameter';
92
93
	/**
94
	 * The name of the Application Parameter Lazy Load Behavior
95
	 */
96
	public const APP_PARAMETER_SET_BEHAVIOR = 'setTDbParameter';
97
98
	/**
99
	 * @var string the ID of TDataSourceConfig module
100
	 */
101
	private $_connID = '';
102
103
	/**
104
	 * @var TDbConnection the DB connection instance
105
	 */
106
	private $_conn;
107
108
	/**
109
	 * @var bool whether or not the database parameters have been loaded.
110
	 * when true none of the variables can be changed
111
	 */
112
	private $_initialized = false;
113
114
	/**
115
	 * @var string The key field for the parameter from the database
116
	 */
117
	private $_keyField = 'param_key';
118
119
	/**
120
	 * @var string The value field for the parameter from the database
121
	 */
122
	private $_valueField = 'param_value';
123
124
	/**
125
	 * @var string The table name for the parameters from the database
126
	 */
127
	private $_tableName = 'parameters';
128
129
	/**
130
	 * @var string autoload Field. default "", meaning no autoload field
131
	 */
132
	private $_autoLoadField = 'autoload';
133
134
	/**
135
	 * @var string autoload True value. default sql "1"
136
	 */
137
	private $_autoLoadValue = '1';
138
139
	/**
140
	 * @var string autoload False value. default sql "0"
141
	 */
142
	private $_autoLoadValueFalse = '0';
143
144
	/**
145
	 * @var bool whether the parameter DB table should be created automatically
146
	 */
147
	private $_autoCreate = true;
148
149
	/**
150
	 * @var bool whether ensureTable was called
151
	 */
152
	private $_tableEnsured;
153
154
	/**
155
	 * @var callable|string which serialize function to use,
156
	 */
157
	private $_serializer = self::SERIALIZE_PHP;
158
159
	/**
160
	 * @var bool automatically capture changes to Parameters after Application Initialize
161
	 */
162
	private $_autoCapture = true;
163
164
	/**
165
	 * @var TMapRouteBehavior captures all the changes to the parameters to the db
166
	 */
167
	private $_setBehavior;
168
169
	/**
170
	 * Initializes the module by loading parameters.
171
	 * @param mixed $config content enclosed within the module tag
172
	 */
173
	public function init($config)
174
	{
175
		$this->loadDbParameters();
176
		$this->_initialized = true;
177
178
		if ($this->_autoLoadField) {
179
			$this->getApplication()->getParameters()->attachBehavior(self::APP_PARAMETER_LAZY_BEHAVIOR, new TMapLazyLoadBehavior([$this, 'getFromBehavior']));
180
		}
181
		if ($this->_autoCapture) {
182
			$this->getApplication()->attachEventHandler('onBeginRequest', [$this, 'attachTPageServiceHandler']);
183
		}
184
		$app = $this->getApplication();
185
		$app->attachEventHandler('onAuthenticationComplete', [$this, 'registerShellAction']);
186
		parent::init($config);
187
	}
188
189
	/**
190
	 * @param \Prado\Security\Permissions\TPermissionsManager $manager
191
	 * @return \Prado\Security\Permissions\TPermissionEvent[]
192
	 */
193
	public function getPermissions($manager)
194
	{
195
		return [
196
			new TPermissionEvent(static::PERM_PARAM_SHELL, 'Activates parameter shell commands.', 'dyRegisterShellAction'),
197
		];
198
	}
199
200
	/**
201
	 * Loads parameters from the database into the application.
202
	 * @throws \Prado\Exceptions\TDbException if the Fields and table is not correct
203
	 */
204
	protected function loadDbParameters()
205
	{
206
		$db = $this->getDbConnection();
207
208
		$this->ensureTable();
209
210
		$where = ($this->_autoLoadField ? " WHERE {$this->_autoLoadField}={$this->_autoLoadValue}" : '');
211
		$cmd = $db->createCommand(
212
			"SELECT {$this->_keyField} as keyField, {$this->_valueField}  as valueField FROM {$this->_tableName}{$where}"
213
		);
214
		$results = $cmd->query();
215
216
		$appParameters = $this->getApplication()->getParameters();
217
		$serializer = $this->getSerializer();
218
		foreach ($results->readAll() as $row) {
219
			$value = $row['valueField'];
220
			if ($serializer == self::SERIALIZE_PHP) {
221
				if (($avalue = @unserialize($value)) !== false) {
222
					$value = $avalue;
223
				}
224
			} elseif ($serializer == self::SERIALIZE_JSON) {
225
				if (($avalue = json_decode($value, true)) !== null) {
226
					$value = $avalue;
227
				}
228
			} elseif ($serializer) {
229
				if (($avalue = call_user_func($serializer, $value, false)) !== null) {
230
					$value = $avalue;
231
				}
232
			}
233
			$appParameters[$row['keyField']] = $value;
234
		}
235
	}
236
237
	/**
238
	 * TApplication::onBeginRequest Handler that adds {@see attachTPageBehaviors} to
239
	 * TPageService::onPreRunPage. In turn, this attaches {@see attachTPageBehaviors}
240
	 * to TPageService to then adds the page behaviors.
241
	 * @param object $sender the object that raised the event
242
	 * @param mixed $param parameter of the event
243
	 */
244
	public function attachTPageServiceHandler($sender, $param)
0 ignored issues
show
Unused Code introduced by
The parameter $sender is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

244
	public function attachTPageServiceHandler(/** @scrutinizer ignore-unused */ $sender, $param)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $param is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

244
	public function attachTPageServiceHandler($sender, /** @scrutinizer ignore-unused */ $param)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
245
	{
246
		$service = $this->getService();
247
		if ($service->hasEvent('onPreRunPage')) {
248
			$service->attachEventHandler('onPreRunPage', [$this, 'attachParameterStorage'], 0);
0 ignored issues
show
Bug introduced by
0 of type integer is incompatible with the type Prado\numeric|null expected by parameter $priority of Prado\TComponent::attachEventHandler(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

248
			$service->attachEventHandler('onPreRunPage', [$this, 'attachParameterStorage'], /** @scrutinizer ignore-type */ 0);
Loading history...
249
		}
250
	}
251
252
	/**
253
	 * @param object $sender sender of this event handler
254
	 * @param null|mixed $param parameter for the event
255
	 */
256
	public function registerShellAction($sender, $param)
0 ignored issues
show
Unused Code introduced by
The parameter $param is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

256
	public function registerShellAction($sender, /** @scrutinizer ignore-unused */ $param)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $sender is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

256
	public function registerShellAction(/** @scrutinizer ignore-unused */ $sender, $param)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
257
	{
258
		if ($this->dyRegisterShellAction(false) !== true && ($app = $this->getApplication()) instanceof \Prado\Shell\TShellApplication) {
259
			$app->addShellActionClass(['class' => \Prado\Shell\Actions\TDbParameterAction::class, 'DbParameterModule' => $this]);
0 ignored issues
show
Bug introduced by
array('class' => Prado\S...ameterModule' => $this) of type array<string,Prado\Util\...ParameterModule|string> is incompatible with the type string expected by parameter $class of Prado\Shell\TShellApplic...::addShellActionClass(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

259
			$app->addShellActionClass(/** @scrutinizer ignore-type */ ['class' => \Prado\Shell\Actions\TDbParameterAction::class, 'DbParameterModule' => $this]);
Loading history...
260
		}
261
	}
262
263
	/**
264
	 * This attaches the TMapRouteBehavior on the Parameters.
265
	 * @param object $sender
266
	 * @param null|mixed $param
267
	 * @throws \Prado\Exceptions\TDbException if the Fields and table is not correct
268
	 */
269
	public function attachParameterStorage($sender, $param)
0 ignored issues
show
Unused Code introduced by
The parameter $param is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

269
	public function attachParameterStorage($sender, /** @scrutinizer ignore-unused */ $param)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
Unused Code introduced by
The parameter $sender is not used and could be removed. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-unused  annotation

269
	public function attachParameterStorage(/** @scrutinizer ignore-unused */ $sender, $param)

This check looks for parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
270
	{
271
		$this->_setBehavior = new TMapRouteBehavior(null, [$this, 'setFromBehavior']);
272
		$this->getApplication()->getParameters()->attachBehavior(self::APP_PARAMETER_SET_BEHAVIOR, $this->_setBehavior);
273
	}
274
275
	/**
276
	 * Creates the DB table for storing log messages.
277
	 * @todo create sequence for PostgreSQL, and other db
278
	 */
279
	protected function createDbTable()
280
	{
281
		$db = $this->getDbConnection();
282
		$driver = $db->getDriverName();
283
		$autoidAttributes = '';
284
		$autotype = 'INTEGER';
285
		$postIndices = '; CREATE UNIQUE INDEX tkey ON ' . $this->_tableName . '(' . $this->_keyField . ');' .
286
		($this->_autoLoadField ? ' CREATE INDEX tauto ON ' . $this->_tableName . '(' . $this->_autoLoadField . ');' : '');
287
288
		switch ($driver) {
289
			case 'sqlite':
290
				$autoidAttributes = ' AUTOINCREMENT';
291
				break;
292
			case 'postgresql':
293
				$autotype = 'SERIAL';
294
				break;
295
			default:	// mysql
296
				$autoidAttributes = ' AUTO_INCREMENT';
297
				break;
298
		}
299
300
		$sql = 'CREATE TABLE ' . $this->_tableName . ' (
301
			param_id ' . $autotype . ' PRIMARY KEY ' . $autoidAttributes . ', ' .
302
			$this->_keyField . ' VARCHAR(128) NOT NULL,' .
303
			$this->_valueField . ' MEDIUMTEXT' .
304
			($this->_autoLoadField ? ', ' . $this->_autoLoadField . ' BOOLEAN NOT NULL DEFAULT 1' : '') .
305
			')' . $postIndices;
306
		$db->createCommand($sql)->execute();
307
	}
308
309
	/**
310
	 * checks for the table, and if not there and autoCreate, then creates the table else throw error.
311
	 * @throws \Prado\Exceptions\TConfigurationException if the table does not exist and cannot autoCreate
312
	 */
313
	protected function ensureTable()
314
	{
315
		if ($this->_tableEnsured) {
316
			return;
317
		}
318
		$this->_tableEnsured = true;
319
		$db = $this->getDbConnection();
320
		$sql = 'SELECT * FROM ' . $this->_tableName . ' WHERE 0=1';
321
		try {
322
			$db->createCommand($sql)->query()->close();
323
		} catch (Exception $e) {
324
			// DB table not exists
325
			if ($this->_autoCreate) {
326
				$this->createDbTable();
327
			} else {
328
				throw new TConfigurationException('dbparametermodule_table_nonexistent', $this->_tableName);
329
			}
330
		}
331
	}
332
333
334
	/**
335
	 * Gets a specific parameter parameters into application.
336
	 * @param string $key key to get the value
337
	 * @param bool $checkParameter checks the Application Parameters first
338
	 * @param bool $setParameter should the method set the application parameters
339
	 * @throws \Prado\Exceptions\TInvalidOperationException if the $key is blank
340
	 * @throws \Prado\Exceptions\TDbException if the Fields and table is not correct
341
	 * @return mixed the value of the key
342
	 */
343
	public function get($key, $checkParameter = true, $setParameter = true)
344
	{
345
		if ($key == '') {
346
			throw new TInvalidOperationException('dbparametermodule_get_no_blank_key');
347
		}
348
349
		if ($checkParameter) {
350
			$appParams = $this->getApplication()->getParameters();
351
			if (isset($appParams[$key])) {
352
				return $appParams[$key];
353
			}
354
		}
355
		$this->ensureTable();
356
357
		$db = $this->getDbConnection();
358
		$cmd = $db->createCommand(
359
			"SELECT {$this->_valueField} as valueField FROM {$this->_tableName} WHERE {$this->_keyField}=:key LIMIT 1"
360
		);
361
		$cmd->bindParameter(":key", $key, PDO::PARAM_STR);
362
		$results = $cmd->queryRow();
363
		$serializer = $this->getSerializer();
364
		if (is_array($results) && ($value = $results['valueField']) !== null) {
365
			if ($serializer == self::SERIALIZE_PHP) {
366
				if (($avalue = @unserialize($value)) !== false) {
367
					$value = $avalue;
368
				}
369
			} elseif ($serializer == self::SERIALIZE_JSON) {
370
				if (($avalue = json_decode($value, true)) !== null) {
371
					$value = $avalue;
372
				}
373
			} elseif ($serializer && ($avalue = call_user_func($serializer, $value, false)) !== null) {
374
				$value = $avalue;
375
			}
376
			if ($setParameter) {
377
				$appParams = $this->getApplication()->getParameters();
378
				$appParams[$key] = $value;
379
			}
380
			return $value;
381
		}
382
		return null;
383
	}
384
385
	/**
386
	 * Loads parameters into application.
387
	 * @param string $key key to get the value
388
	 * @throws \Prado\Exceptions\TInvalidOperationException if the $key is blank
389
	 * @throws \Prado\Exceptions\TDbException if the Fields and table is not correct
390
	 * @return mixed the value
391
	 */
392
	public function getFromBehavior($key)
393
	{
394
		return $this->get($key, false, $this->_setBehavior === null);
395
	}
396
397
	/**
398
	 * Sets a parameter in the database and the Application Parameter.
399
	 * @param string $key the key of the parameter
400
	 * @param mixed $value the key of the parameter
401
	 * @param bool $autoLoad should the key be autoloaded at init
402
	 * @param mixed $setParameter
403
	 * @throws \Prado\Exceptions\TInvalidOperationException if the $key is blank
404
	 * @throws \Prado\Exceptions\TDbException if the Fields and table is not correct
405
	 */
406
	public function set($key, $value, $autoLoad = true, $setParameter = true)
407
	{
408
		if (empty($key)) {
409
			throw new TInvalidOperationException('dbparametermodule_set_no_blank_key');
410
		}
411
412
		$_value = $value;
413
		if (($serializer = $this->getSerializer()) && (is_array($value) || is_object($value))) {
414
			if ($serializer == self::SERIALIZE_PHP) {
415
				$_value = @serialize($value);
416
			} elseif ($serializer == self::SERIALIZE_JSON) {
417
				$_value = json_encode($value, JSON_UNESCAPED_UNICODE);
418
			} else {
419
				$_value = call_user_func($serializer, $value, true);
420
			}
421
		}
422
		$this->ensureTable();
423
		$db = $this->getDbConnection();
424
		$driver = $db->getDriverName();
425
		$appendix = '';
426
		if ($driver === 'mysql') {
427
			$dupl = ($this->_autoLoadField ? ", {$this->_autoLoadField}=values({$this->_autoLoadField})" : '');
428
			$appendix = " ON DUPLICATE KEY UPDATE {$this->_valueField}=values({$this->_valueField}){$dupl}";
429
		} else {
430
			$this->remove($key);
431
		}
432
		$field = ($this->_autoLoadField ? ", {$this->_autoLoadField}" : '');
433
		$values = ($this->_autoLoadField ? ", :auto" : '');
434
		$cmd = $db->createCommand("INSERT INTO {$this->_tableName} ({$this->_keyField}, {$this->_valueField}{$field}) " .
435
					"VALUES (:key, :value{$values})" . $appendix);
436
		$cmd->bindParameter(":key", $key, PDO::PARAM_STR);
437
		$cmd->bindParameter(":value", $_value, PDO::PARAM_STR);
438
		if ($this->_autoLoadField) {
439
			$alv = $autoLoad ? $this->_autoLoadValue : $this->_autoLoadValueFalse;
440
			$cmd->bindParameter(":auto", $alv, PDO::PARAM_STR);
441
		}
442
		$cmd->execute();
443
444
		if ($setParameter) {
445
			$appParameters = $this->getApplication()->getParameters();
446
			$appParameters[$key] = $value;
447
		}
448
	}
449
450
	/**
451
	 * Sets a parameter in the database and the Application Parameter.
452
	 * from changes to the Parameter through a TMapRouteBehavior.
453
	 * @param string $key the key of the parameter
454
	 * @param mixed $value the key of the parameter
455
	 * @throws \Prado\Exceptions\TInvalidOperationException if the $key is blank
456
	 * @throws \Prado\Exceptions\TDbException if the Fields and table is not correct
457
	 */
458
	public function setFromBehavior($key, $value)
459
	{
460
		if ($value !== null) {
461
			$this->set($key, $value, true, false);
462
		} else {
463
			$this->remove($key);
464
		}
465
	}
466
467
	/**
468
	 * exists checks for a parameter in the database
469
	 * @param string $key parameter to check in the database
470
	 * @throws \Prado\Exceptions\TDbException if the Fields and table is not correct
471
	 * @return bool whether the key exists in the database table
472
	 * @return mixed the value of the parameter, one last time
473
	 */
474
	public function exists($key)
475
	{
476
		$this->ensureTable();
477
478
		$db = $this->getDbConnection();
479
		$cmd = $db->createCommand(
480
			"SELECT COUNT(*) AS count FROM {$this->_tableName} WHERE {$this->_keyField}=:key"
481
		);
482
		$cmd->bindParameter(":key", $key, PDO::PARAM_STR);
483
		$result = $cmd->queryRow();
484
		return $result['count'] > 0;
485
	}
486
487
	/**
488
	 * remove removes a parameter from the database
489
	 * @param string $key parameter to remove from the database
490
	 * @throws \Prado\Exceptions\TDbException if the Fields and table is not correct
491
	 * @return mixed the value of the key removed
492
	 * @return mixed the value of the parameter, one last time
493
	 */
494
	public function remove($key)
495
	{
496
		$value = $this->get($key, false, false);
497
498
		$this->ensureTable();
499
		$db = $this->getDbConnection();
500
		$driver = $db->getDriverName();
501
		$appendix = '';
502
		if ($driver === 'mysql') {
503
			$appendix = ' LIMIT 1';
504
		}
505
		$cmd = $db->createCommand("DELETE FROM {$this->_tableName} WHERE {$this->_keyField}=:key" . $appendix);
506
		$cmd->bindParameter(":key", $key, PDO::PARAM_STR);
507
		$cmd->execute();
508
		return $value;
509
	}
510
511
	/**
512
	 * @return string the ID of a TDataSourceConfig module. Defaults to empty string, meaning not set.
513
	 */
514
	public function getConnectionID()
515
	{
516
		return $this->_connID;
517
	}
518
519
	/**
520
	 * Sets the ID of a TDataSourceConfig module.
521
	 * The datasource module will be used to establish the DB connection
522
	 * that will be used by the user manager.
523
	 * @param string $value module ID.
524
	 * @throws \Prado\Exceptions\TInvalidOperationException if the module is initialized
525
	 */
526
	public function setConnectionID($value)
527
	{
528
		if ($this->_initialized) {
529
			throw new TInvalidOperationException('dbparametermodule_property_unchangeable', 'ConnectionID');
530
		}
531
		$this->_connID = $value;
532
	}
533
534
	/**
535
	 * @return TDbConnection the database connection that may be used to retrieve user data.
536
	 */
537
	public function getDbConnection()
538
	{
539
		if ($this->_conn === null) {
540
			$this->_conn = $this->createDbConnection($this->_connID);
541
			$this->_conn->setActive(true);
542
		}
543
		return $this->_conn;
544
	}
545
546
	/**
547
	 * Creates the DB connection.  If no ConnectionID is set, this creates a
548
	 * sqlite3 database in the RuntimePath "sqlite3.params".  If the
549
	 * {@see getAutoLoadField} is not set, the default, then the autoLoadField
550
	 * is set to "autoload" to enable the feature by default.
551
	 * @param string $connectionID the module ID for TDataSourceConfig
552
	 * @throws \Prado\Exceptions\TConfigurationException if module ID is invalid or empty
553
	 * @return TDbConnection the created DB connection
554
	 */
555
	protected function createDbConnection($connectionID)
556
	{
557
		if ($connectionID !== '') {
558
			$conn = $this->getApplication()->getModule($connectionID);
559
			if ($conn instanceof TDataSourceConfig) {
560
				return $conn->getDbConnection();
561
			} else {
562
				throw new TConfigurationException('dbparametermodule_connectionid_invalid', $connectionID);
563
			}
564
		} else {
565
			$db = new TDbConnection();
566
			// default to SQLite3 database
567
			$dbFile = $this->getApplication()->getRuntimePath() . DIRECTORY_SEPARATOR . 'app.params';
568
			$db->setConnectionString('sqlite:' . $dbFile);
569
			return $db;
570
		}
571
	}
572
573
	/**
574
	 * @return string the database parameter key field
575
	 */
576
	public function getKeyField()
577
	{
578
		return $this->_keyField;
579
	}
580
581
	/**
582
	 * @param string $value database parameter key field
583
	 * @throws \Prado\Exceptions\TInvalidOperationException if the module is initialized
584
	 */
585
	public function setKeyField($value)
586
	{
587
		if ($this->_initialized) {
588
			throw new TInvalidOperationException('dbparametermodule_property_unchangeable', 'KeyField');
589
		}
590
		$this->_keyField = TPropertyValue::ensureString($value);
591
	}
592
593
	/**
594
	 * @return string the database parameter key value
595
	 */
596
	public function getValueField()
597
	{
598
		return $this->_valueField;
599
	}
600
601
	/**
602
	 * @param string $value database parameter key value
603
	 * @throws \Prado\Exceptions\TInvalidOperationException if the module is initialized
604
	 */
605
	public function setValueField($value)
606
	{
607
		if ($this->_initialized) {
608
			throw new TInvalidOperationException('dbparametermodule_property_unchangeable', 'ValueField');
609
		}
610
		$this->_valueField = TPropertyValue::ensureString($value);
611
	}
612
613
	/**
614
	 * @return string the database parameter key value
615
	 */
616
	public function getTableName()
617
	{
618
		return $this->_tableName;
619
	}
620
621
	/**
622
	 * @param string $value database parameter key value
623
	 * @throws \Prado\Exceptions\TInvalidOperationException if the module is initialized
624
	 */
625
	public function setTableName($value)
626
	{
627
		if ($this->_initialized) {
628
			throw new TInvalidOperationException('dbparametermodule_property_unchangeable', 'TableName');
629
		}
630
		$this->_tableName = TPropertyValue::ensureString($value);
631
	}
632
633
	/**
634
	 * @return string the database parameter key value
635
	 */
636
	public function getAutoLoadField()
637
	{
638
		return $this->_autoLoadField;
639
	}
640
641
	/**
642
	 * @param string $value database parameter key value
643
	 * @throws \Prado\Exceptions\TInvalidOperationException if the module is initialized
644
	 */
645
	public function setAutoLoadField($value)
646
	{
647
		if ($this->_initialized) {
648
			throw new TInvalidOperationException('dbparametermodule_property_unchangeable', 'AutoLoadField');
649
		}
650
		$this->_autoLoadField = TPropertyValue::ensureString($value);
651
	}
652
653
	/**
654
	 * @return string the database parameter key value
655
	 */
656
	public function getAutoLoadValue()
657
	{
658
		return $this->_autoLoadValue;
659
	}
660
661
	/**
662
	 * @param string $value database parameter key value
663
	 * @throws \Prado\Exceptions\TInvalidOperationException if the module is initialized
664
	 */
665
	public function setAutoLoadValue($value)
666
	{
667
		if ($this->_initialized) {
668
			throw new TInvalidOperationException('dbparametermodule_property_unchangeable', 'AutoLoadValue');
669
		}
670
		$this->_autoLoadValue = TPropertyValue::ensureString($value);
671
	}
672
673
	/**
674
	 * @return string the database parameter key value
675
	 */
676
	public function getAutoLoadValueFalse()
677
	{
678
		return $this->_autoLoadValueFalse;
679
	}
680
681
	/**
682
	 * @param string $value database parameter key value
683
	 * @throws \Prado\Exceptions\TInvalidOperationException if the module is initialized
684
	 */
685
	public function setAutoLoadValueFalse($value)
686
	{
687
		if ($this->_initialized) {
688
			throw new TInvalidOperationException('dbparametermodule_property_unchangeable', 'AutoLoadValueFalse');
689
		}
690
		$this->_autoLoadValueFalse = TPropertyValue::ensureString($value);
691
	}
692
693
	/**
694
	 * @return bool whether the paramter DB table should be automatically created if not exists. Defaults to true.
695
	 * @see setAutoCreateParamTable
696
	 */
697
	public function getAutoCreateParamTable()
698
	{
699
		return $this->_autoCreate;
700
	}
701
702
	/**
703
	 * @param bool $value whether the parameter DB table should be automatically created if not exists.
704
	 * @see setTableName
705
	 */
706
	public function setAutoCreateParamTable($value)
707
	{
708
		$this->_autoCreate = TPropertyValue::ensureBoolean($value);
709
	}
710
711
	/**
712
	 * @return null|callable|string
713
	 */
714
	public function getSerializer()
715
	{
716
		return $this->_serializer;
717
	}
718
719
	/**
720
	 * Serializer sets the type of serialization of objects and arrays in parameters
721
	 * to and from the database.  'php' uses serialze and unserialize. 'json' uses
722
	 * json_encode and json_decade. or you can provide your own callable to serialized
723
	 * and unserialize objects and arrays.
724
	 * @param callable|string $value the type of un/serialization.
725
	 * @throws \Prado\Exceptions\TInvalidOperationException if the module is initialized
726
	 * @throws \Prado\Exceptions\TInvalidDataTypeException if the $value is not 'php', 'json', or a callable
727
	 */
728
	public function setSerializer($value)
729
	{
730
		if ($this->_initialized) {
731
			throw new TInvalidOperationException('dbparametermodule_property_unchangeable', 'Serializer');
732
		}
733
		if ($value !== self::SERIALIZE_PHP && $value !== self::SERIALIZE_JSON && !is_callable($value)) {
734
			throw new TInvalidDataTypeException('dbparametermodule_serializer_not_callable');
735
		}
736
		$this->_serializer = $value;
737
	}
738
739
	/**
740
	 * @return bool whether the parameter DB table should be automatically created if not exists. Defaults to true.
741
	 */
742
	public function getCaptureParameterChanges()
743
	{
744
		return $this->_autoCapture;
745
	}
746
747
	/**
748
	 * @param bool $value whether the parameter DB table should be automatically created if not exists.
749
	 */
750
	public function setCaptureParameterChanges($value)
751
	{
752
		$this->_autoCapture = TPropertyValue::ensureBoolean($value);
753
	}
754
}
755