1<?php
2
3namespace Doctrine\DBAL\Event\Listeners;
4
5use Doctrine\Common\EventSubscriber;
6use Doctrine\DBAL\Event\ConnectionEventArgs;
7use Doctrine\DBAL\Events;
8
9use function array_change_key_case;
10use function array_merge;
11use function count;
12use function implode;
13
14use const CASE_UPPER;
15
16/**
17 * Should be used when Oracle Server default environment does not match the Doctrine requirements.
18 *
19 * The following environment variables are required for the Doctrine default date format:
20 *
21 * NLS_TIME_FORMAT="HH24:MI:SS"
22 * NLS_DATE_FORMAT="YYYY-MM-DD HH24:MI:SS"
23 * NLS_TIMESTAMP_FORMAT="YYYY-MM-DD HH24:MI:SS"
24 * NLS_TIMESTAMP_TZ_FORMAT="YYYY-MM-DD HH24:MI:SS TZH:TZM"
25 */
26class OracleSessionInit implements EventSubscriber
27{
28    /** @var string[] */
29    protected $_defaultSessionVars = [
30        'NLS_TIME_FORMAT' => 'HH24:MI:SS',
31        'NLS_DATE_FORMAT' => 'YYYY-MM-DD HH24:MI:SS',
32        'NLS_TIMESTAMP_FORMAT' => 'YYYY-MM-DD HH24:MI:SS',
33        'NLS_TIMESTAMP_TZ_FORMAT' => 'YYYY-MM-DD HH24:MI:SS TZH:TZM',
34        'NLS_NUMERIC_CHARACTERS' => '.,',
35    ];
36
37    /**
38     * @param string[] $oracleSessionVars
39     */
40    public function __construct(array $oracleSessionVars = [])
41    {
42        $this->_defaultSessionVars = array_merge($this->_defaultSessionVars, $oracleSessionVars);
43    }
44
45    /**
46     * @return void
47     */
48    public function postConnect(ConnectionEventArgs $args)
49    {
50        if (! count($this->_defaultSessionVars)) {
51            return;
52        }
53
54        $vars = [];
55        foreach (array_change_key_case($this->_defaultSessionVars, CASE_UPPER) as $option => $value) {
56            if ($option === 'CURRENT_SCHEMA') {
57                $vars[] = $option . ' = ' . $value;
58            } else {
59                $vars[] = $option . " = '" . $value . "'";
60            }
61        }
62
63        $sql = 'ALTER SESSION SET ' . implode(' ', $vars);
64        $args->getConnection()->executeStatement($sql);
65    }
66
67    /**
68     * {@inheritdoc}
69     */
70    public function getSubscribedEvents()
71    {
72        return [Events::postConnect];
73    }
74}
75