Skip to content

Instantly share code, notes, and snippets.

@pavelkucera
Created July 19, 2012 09:59
Show Gist options
  • Save pavelkucera/3142811 to your computer and use it in GitHub Desktop.
Save pavelkucera/3142811 to your computer and use it in GitHub Desktop.
<?php
namespace RS\Doctrine\Config;
use RS\Doctrine\DBAL\Types\Type;
use Nette\Diagnostics\Debugger;
/**
* @author Pavel Kučera
*/
class ConnectionFactory extends \Nette\Object
{
/** @var array */
protected $mappingTypes = array();
/**
* @param array
*/
public function __construct(array $mappingTypes)
{
$this->mappingTypes = $mappingTypes;
foreach ($mappingTypes as $name => $class) {
if (Type::hasType($name)) {
Type::overrideType($name, $class);
} else {
Type::addType($name, $class);
}
}
}
/**
* @param array
* @param \Doctrine\Common\EventManager
* @return \Doctrine\DBAL\Connection
*/
public function createConnection(array $config, \Doctrine\Common\EventManager $evm = NULL)
{
if (!$evm) {
$evm = new \Doctrine\Common\EventManager;
}
if (isset($config['driver']) && $config['driver'] == 'pdo_mysql' && isset($config['charset'])) {
$evm->addEventSubscriber(
new \Doctrine\DBAL\Event\Listeners\MysqlSessionInit($config['charset'], $config['collation'])
);
}
$cfg = new \Doctrine\DBAL\Configuration;
if (isset($config['debugger']) && $config['debugger'] === TRUE) {
$panel = new \Nella\NetteAddons\Doctrine\Diagnostics\ConnectionPanel;
if (Debugger::$bar) {
Debugger::$bar->addPanel($panel);
}
Debugger::$blueScreen->addPanel(array($panel, 'renderException'));
$cfg->setSQLLogger($panel);
} elseif (isset($config['debugger'])) {
Debugger::$blueScreen->addPanel('Nette\Database\Diagnostics\ConnectionPanel::renderException');
$cfg->setSQLLogger($config['debugger']);
}
/** @var \Doctrine\DBAL\Connection $connection */
$connection = \Doctrine\DBAL\DriverManager::getConnection($config, $cfg, $evm);
$platform = $connection->getDatabasePlatform();
foreach ($config['mappingTypes'] as $dbType => $doctrineType) {
$comment = \Nette\Utils\Strings::startsWith($doctrineType, '#');
$doctrineType = $comment ? substr($doctrineType, 1) : $doctrineType;
$platform->registerDoctrineTypeMapping($dbType, $doctrineType);
if ($comment) {
$platform->markDoctrineTypeCommented(Type::getType($doctrineType));
}
}
return $connection;
}
}
<?php
namespace RS\Config\Extensions;
/**
* @author Pavel Kučera
* @author Patrik Votoček
*/
class DoctrineExtension extends \Nella\Config\Extensions\DoctrineExtension
{
/** @var array */
public $connectionDefaults = array(
'debugger' => TRUE,
'collation' => FALSE,
'eventManager' => NULL,
'autowired' => FALSE,
'mappingTypes' => array(
'password' => '#password',
'callback' => '#callback',
),
);
/** @var string[] */
public $defaultTypes = array(
\RS\Doctrine\DBAL\Types\Type::CALLBACK => 'RS\Doctrine\DBAL\Types\Callback',
\RS\Doctrine\DBAL\Types\Type::PASSWORD => 'RS\Doctrine\DBAL\Types\Password',
);
/**
* @return void
*/
protected function processFactories()
{
parent::processFactories();
$container = $this->getContainerBuilder();
$config = $this->getConfig();
// Connection factory class
$mappingTypes = (isset($config['mappingTypes']) ? $config['mappingTypes'] : array()) + $this->defaultTypes;
$container->addDefinition($this->prefix('connectionFactory'))
->setClass('RS\Doctrine\Config\ConnectionFactory', array($mappingTypes))
->setInternal(TRUE);
// A bit of a hack but original extension is so terribly programmed that it can't be easily extended :(
$factory = $this->connectionFactory->factory;
$factory->entity = $this->prefix('@connectionFactory') . '::createConnection';
}
}
<?php
namespace RS\Doctrine\DBAL\Types;
/**
* @author Pavel Kučera
*/
abstract class Type extends \Doctrine\DBAL\Types\Type
{
/** @var string */
const CALLBACK = 'callback',
PASSWORD = 'password';
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment