1: <?php
2:
3: 4: 5: 6:
7:
8: namespace Nette\Bridges\DatabaseDI;
9:
10: use Nette;
11:
12:
13: 14: 15:
16: class DatabaseExtension extends Nette\DI\CompilerExtension
17: {
18: public $databaseDefaults = array(
19: 'dsn' => NULL,
20: 'user' => NULL,
21: 'password' => NULL,
22: 'options' => NULL,
23: 'debugger' => TRUE,
24: 'explain' => TRUE,
25: 'reflection' => NULL,
26: 'conventions' => 'discovered',
27: 'autowired' => NULL,
28: );
29:
30:
31: private $debugMode;
32:
33:
34: public function __construct($debugMode = FALSE)
35: {
36: $this->debugMode = $debugMode;
37: }
38:
39:
40: public function loadConfiguration()
41: {
42: $configs = $this->getConfig();
43: if (isset($configs['dsn'])) {
44: $configs = array('default' => $configs);
45: }
46:
47: $defaults = $this->databaseDefaults;
48: $defaults['autowired'] = TRUE;
49: foreach ((array) $configs as $name => $config) {
50: if (!is_array($config)) {
51: continue;
52: }
53: $config = $this->validateConfig($defaults, $config, $this->prefix($name));
54: $defaults['autowired'] = FALSE;
55: $this->setupDatabase($config, $name);
56: }
57: }
58:
59:
60: private function setupDatabase($config, $name)
61: {
62: $container = $this->getContainerBuilder();
63:
64: foreach ((array) $config['options'] as $key => $value) {
65: if (preg_match('#^PDO::\w+\z#', $key)) {
66: unset($config['options'][$key]);
67: $config['options'][constant($key)] = $value;
68: }
69: }
70:
71: $connection = $container->addDefinition($this->prefix("$name.connection"))
72: ->setClass('Nette\Database\Connection', array($config['dsn'], $config['user'], $config['password'], $config['options']))
73: ->setAutowired($config['autowired']);
74:
75: $structure = $container->addDefinition($this->prefix("$name.structure"))
76: ->setClass('Nette\Database\Structure')
77: ->setArguments(array($connection))
78: ->setAutowired($config['autowired']);
79:
80: if (!empty($config['reflection'])) {
81: $conventionsServiceName = 'reflection';
82: $config['conventions'] = $config['reflection'];
83: if (strtolower($config['conventions']) === 'conventional') {
84: $config['conventions'] = 'Static';
85: }
86: } else {
87: $conventionsServiceName = 'conventions';
88: }
89:
90: if (!$config['conventions']) {
91: $conventions = NULL;
92:
93: } elseif (is_string($config['conventions'])) {
94: $conventions = $container->addDefinition($this->prefix("$name.$conventionsServiceName"))
95: ->setClass(preg_match('#^[a-z]+\z#i', $config['conventions'])
96: ? 'Nette\Database\Conventions\\' . ucfirst($config['conventions']) . 'Conventions'
97: : $config['conventions'])
98: ->setArguments(strtolower($config['conventions']) === 'discovered' ? array($structure) : array())
99: ->setAutowired($config['autowired']);
100:
101: } else {
102: $tmp = Nette\DI\Compiler::filterArguments(array($config['conventions']));
103: $conventions = reset($tmp);
104: }
105:
106: $container->addDefinition($this->prefix("$name.context"))
107: ->setClass('Nette\Database\Context', array($connection, $structure, $conventions))
108: ->setAutowired($config['autowired']);
109:
110: if ($config['debugger']) {
111: $connection->addSetup('@Tracy\BlueScreen::addPanel', array(
112: 'Nette\Bridges\DatabaseTracy\ConnectionPanel::renderException'
113: ));
114: if ($this->debugMode) {
115: $connection->addSetup('Nette\Database\Helpers::createDebugPanel', array($connection, !empty($config['explain']), $name));
116: }
117: }
118:
119: if ($this->name === 'database') {
120: $container->addAlias($this->prefix($name), $this->prefix("$name.connection"));
121: $container->addAlias("nette.database.$name", $this->prefix($name));
122: $container->addAlias("nette.database.$name.context", $this->prefix("$name.context"));
123: }
124: }
125:
126: }
127: