Completed
Push — dev-0.1.x ( 89d2d8...828717 )
by Josué
11:01
created

PdoOci8::getConnectionStringItems()   B

Complexity

Conditions 6
Paths 8

Size

Total Lines 34
Code Lines 24

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 6.0184

Importance

Changes 1
Bugs 0 Features 1
Metric Value
c 1
b 0
f 1
dl 0
loc 34
ccs 23
cts 25
cp 0.92
rs 8.439
cc 6
eloc 24
nc 8
nop 1
crap 6.0184
1
<?php
2
3
namespace Jpina\PdoOci8;
4
5
use Jpina\Oci8\Oci8Connection;
6
use Jpina\Oci8\Oci8ConnectionInterface;
7
use Jpina\Oci8\Oci8Exception;
8
use Jpina\Oci8\Oci8PersistentConnection;
9
use Jpina\Oci8\Oci8StatementInterface;
10
11
/**
12
 * Custom PDO_OCI implementation via OCI8 driver
13
 *
14
 * @see http://php.net/manual/en/class.pdo.php
15
 */
16
class PdoOci8 extends \PDO
17
{
18
    const OCI_ATTR_SESSION_MODE = 8000;
19
20
    const OCI_ATTR_RETURN_LOBS = 8001;
21
22
    /**
23
     * @var Oci8ConnectionInterface
24
     */
25
    protected $connection;
26
27
    /**
28
     * @var bool
29
     */
30
    private $autoCommitMode = false;
31
32
    /** @var bool */
33
    private $isTransactionStarted = false;
34
35
    /**
36
     * @var array
37
     */
38
    protected $options = array();
39
40
    // TODO Receive Oci8ConnectionInterface?
41 14
    public function __construct($dsn, $username = '', $password = '', $options = array())
42
    {
43 14
        $this->options = array(
44 14
            \PDO::ATTR_AUTOCOMMIT         => true,
45 14
            \PDO::ATTR_CASE               => \PDO::CASE_NATURAL,
46 14
            \PDO::ATTR_CLIENT_VERSION     => '',
47 14
            \PDO::ATTR_CONNECTION_STATUS  => '',
48 14
            \PDO::ATTR_DRIVER_NAME        => 'oci',
49 14
            \PDO::ATTR_ERRMODE            => \PDO::ERRMODE_SILENT,
50 14
            \PDO::ATTR_ORACLE_NULLS       => \PDO::NULL_NATURAL,
51 14
            \PDO::ATTR_PERSISTENT         => false,
52 14
            \PDO::ATTR_PREFETCH           => 100,
53 14
            \PDO::ATTR_SERVER_INFO        => '',
54 14
            \PDO::ATTR_SERVER_VERSION     => '',
55 14
            \PDO::ATTR_TIMEOUT            => 600,
56 14
            \PDO::ATTR_STRINGIFY_FETCHES  => false,
57 14
            \PDO::ATTR_STATEMENT_CLASS    => null,
58 14
            \PDO::ATTR_EMULATE_PREPARES   => false,
59 14
            \PDO::ATTR_DEFAULT_FETCH_MODE => \PDO::FETCH_BOTH,
60 14
            static::OCI_ATTR_SESSION_MODE => OCI_DEFAULT,
61 14
            static::OCI_ATTR_RETURN_LOBS  => false,
62
        );
63
64 14 View Code Duplication
        foreach ($options as $option => $value) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
65 4
            if (array_key_exists($option, $this->options)) {
66 4
                $this->options[$option] = $value;
67 4
            }
68 14
        }
69
70 14
        foreach ($options as $attribute => $value) {
71 4
            $this->setAttribute($attribute, $value);
72 14
        }
73
74 14
        $connection = $this->getOracleConnection($dsn, $username, $password);
75 12
        $this->setAttribute(\PDO::ATTR_CLIENT_VERSION, $connection->getClientVersion());
76 12
        $this->setAttribute(\PDO::ATTR_SERVER_VERSION, $connection->getServerVersion());
77
78 12
        $autocommitMode = $this->getAttribute(\PDO::ATTR_AUTOCOMMIT);
79 12
        $this->setAutocommitMode($autocommitMode);
80 12
        if ($this->getAttribute(\PDO::ATTR_AUTOCOMMIT) === false) {
81 1
            $this->beginTransaction();
82 1
        }
83
84 12
        $this->connection = $connection;
85 12
    }
86
87
    /**
88
     * @return bool
89
     */
90 3
    protected function getAutocommitMode()
91
    {
92 3
        return $this->autoCommitMode;
93
    }
94
95
    /**
96
     * @param string $dsn
97
     * @return string
98
     */
99 13
    protected function getCharset($dsn)
100
    {
101 13
        $connectionStringItems = $this->getConnectionStringItems($dsn);
102
103 13
        return $connectionStringItems['charset'];
104
    }
105
106
    /**
107
     * @return Oci8ConnectionInterface
108
     */
109 49
    protected function getConnection()
110
    {
111 49
        return $this->connection;
112
    }
113
114
    /**
115
     * @param string $dsn
116
     * @param string $username
117
     * @param string $password
118
     * @return Oci8ConnectionInterface
119
     */
120 14
    protected function getOracleConnection($dsn, $username = null, $password = null)
121
    {
122 14
        $connectionString = $this->getConnectionString($dsn);
123 13
        $charset = $this->getCharset($dsn);
124 13
        $sessionMode = $this->getAttribute(static::OCI_ATTR_SESSION_MODE);
125
126 13
        $connection = null;
127
        try {
128 13
            if ($this->getAttribute(\PDO::ATTR_PERSISTENT)) {
129 1
                $connection = new Oci8PersistentConnection(
130 1
                    $username,
131 1
                    $password,
132 1
                    $connectionString,
133 1
                    $charset,
134
                    $sessionMode
135 1
                );
136 1
            } else {
137 12
                $connection = new Oci8Connection(
138 12
                    $username,
139 12
                    $password,
140 12
                    $connectionString,
141 12
                    $charset,
142
                    $sessionMode
143 12
                );
144
            }
145 13
        } catch (Oci8Exception $ex) {
146 1
            throw new PdoOci8Exception($ex->getMessage(), $ex->getCode(), $ex);
147
        }
148
149 12
        return $connection;
150
    }
151
152
    /**
153
     * @param string $dsn
154
     * @return string
155
     */
156 14
    protected function getConnectionString($dsn)
157
    {
158 14
        $connectionStringItems = $this->getConnectionStringItems($dsn);
159 13
        $hostname = $connectionStringItems['hostname'];
160 13
        $port = $connectionStringItems['port'];
161 13
        $database = $connectionStringItems['database'];
162 13
        $connectionString = "//{$hostname}:{$port}/{$database}";
163
164 13
        return $connectionString;
165
    }
166
167
    /**
168
     * @param string $dsn
169
     * @return array
170
     */
171 14
    protected function getConnectionStringItems($dsn)
172
    {
173 14
        $dsnRegex = $this->getDsnRegex();
174 14
        $matches = array();
175 14
        if (preg_match("/^{$dsnRegex}$/i", $dsn, $matches) !== 1) {
176 1
            throw new PdoOci8Exception('Invalid DSN');
177
        }
178
179
        // TODO Remove the variables below
180 13
        $hostname = 'localhost';
181 13
        $port     = 1521;
182 13
        $database = null;
0 ignored issues
show
Unused Code introduced by
$database is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
183 13
        $charset  = 'AL32UTF8';
184
185 13
        switch (count($matches)) {
186 13
            case 16:
187 11
                $charset  = empty($matches[15]) ? $charset : $matches[15];
188
                // fall through next case to get the rest of the variables
189 13
            case 14:
190 13
                $port     = empty($matches[12]) ? $port : (int)$matches[12];
191 13
                $hostname = $matches[4];
192 13
                $database = $matches[13];
193 13
                break;
194
            default:
195
                $database = $matches[1];
196 13
        }
197
198
        return array(
199 13
            'hostname' => $hostname,
200 13
            'port'     => $port,
201 13
            'database' => $database,
202 13
            'charset'  => $charset,
203 13
        );
204
    }
205
206
    /**
207
     * @return string
208
     */
209 14
    protected function getDsnRegex()
210
    {
211 14
        $hostnameRegrex = "(([a-z]|[a-z][a-z0-9\-_]*[a-z0-9])\.)*([a-z]|[a-z][a-z0-9\-_]*[a-z0-9])";
212
        $validIpAddressRegex = "(([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])\.){3}" .
213 14
            "([0-9]|[1-9][0-9]|1[0-9]{2}|2[0-4][0-9]|25[0-5])";
214 14
        $hostnameOrIpAddressRegrex = "\/\/({$hostnameRegrex}|{$validIpAddressRegex})";
215 14
        $databaseRegex = "([a-z_][a-z\-_\d]*)|({$hostnameOrIpAddressRegrex}(:(\d+))?\/([a-z_][a-z\-_\d]*))";
216 14
        $charsetRegex = "(charset=([a-z\d\-_]+))?";
217 14
        $dsnRegex = "oci\:database=({$databaseRegex});?{$charsetRegex}";
218
219 14
        return $dsnRegex;
220
    }
221
222
    /**
223
     * @param array $overrideOptions
224
     * @return array
225
     */
226 44
    protected function getOptions($overrideOptions = array())
227
    {
228 44
        $options = array_merge($this->options, $overrideOptions);
229
230 44
        return $options;
231
    }
232
233
    /**
234
     * @link http://php.net/manual/en/pdo.begintransaction.php
235
     * @return bool
236
     */
237 5
    public function beginTransaction()
238
    {
239 5
        if ($this->inTransaction()) {
240 2
            return false;
241
        }
242
243 5
        $this->setAttribute(\PDO::ATTR_AUTOCOMMIT, false);
244 5
        $this->isTransactionStarted = true;
245
246 5
        return true;
247
    }
248
249
    /**
250
     * @link http://php.net/manual/en/pdo.commit.php
251
     * @return bool
252
     */
253 1
    public function commit()
254
    {
255
        try {
256 1
            $isSuccess = $this->getConnection()->commit();
257 1
        } catch (Oci8Exception $ex) {
258
            $isSuccess = false;
259
        }
260
261 1
        $this->restoreAutocommitMode();
262
263 1
        return $isSuccess;
264
    }
265
266
    /**
267
     * @link http://php.net/manual/en/pdo.errorcode.php
268
     * @return null|string
269
     */
270 1 View Code Duplication
    public function errorCode()
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
271
    {
272 1
        $connection = $this->getConnection();
273 1
        $driverError = $connection->getError();
274 1
        if (!$driverError) {
275 1
            return null;
276
        }
277
278
        $error = $this->errorInfo();
279
        $sqlStateErrorCode = $error[0];
280
281
        return $sqlStateErrorCode;
282
    }
283
284
    /**
285
     * @link http://php.net/manual/en/pdo.errorinfo.php
286
     * @return array
287
     */
288 1
    public function errorInfo()
289
    {
290 1
        $error = $this->getConnection()->getError();
291 1
        if (is_array($error)) {
292
            $errorInfo = array(
293
                OracleSqlStateCode::getSqlStateErrorCode((int)$error['code']),
294
                $error['message'],
295
                $error['code']
296
            );
297
        } else {
298
            $errorInfo = array(
299 1
                '00000',
300 1
                null,
301
                null
302 1
            );
303
        }
304
305 1
        return $errorInfo;
306
    }
307
308
    /**
309
     * @param string $statement
310
     *
311
     * @link http://php.net/manual/en/pdo.exec.php
312
     * @return bool|int
313
     */
314 4
    public function exec($statement)
315
    {
316 4
        $statement = $this->prepare($statement);
317 4
        $type      = $this->getStatementType($statement);
0 ignored issues
show
Security Bug introduced by
It seems like $statement defined by $this->prepare($statement) on line 316 can also be of type false; however, Jpina\PdoOci8\PdoOci8::getStatementType() does only seem to accept object<Jpina\PdoOci8\PdoOci8Statement>, did you maybe forget to handle an error condition?

This check looks for type mismatches where the missing type is false. This is usually indicative of an error condtion.

Consider the follow example

<?php

function getDate($date)
{
    if ($date !== null) {
        return new DateTime($date);
    }

    return false;
}

This function either returns a new DateTime object or false, if there was an error. This is a typical pattern in PHP programming to show that an error has occurred without raising an exception. The calling code should check for this returned false before passing on the value to another function or method that may not be able to handle a false.

Loading history...
318 4
        if ($type === 'SELECT') {
319 1
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type of the parent method PDO::exec of type integer.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
320
        }
321 3
        $statement->execute();
322
323 3
        return $statement->rowCount();
324
    }
325
326
    /**
327
     * @param PdoOci8Statement $statement
328
     * @return string
329
     */
330 4
    protected function getStatementType($statement)
331
    {
332 4
        $class = new \ReflectionClass($statement);
333 4
        $property = $class->getProperty('statement');
334 4
        $property->setAccessible(true);
335
        /** @var Oci8StatementInterface $rawStatement */
336 4
        $oci8Statement = $property->getValue($statement);
337 4
        $type = $oci8Statement->getType();
338
339 4
        return $type;
340
    }
341
342
    /**
343
     * @param int $attribute
344
     *
345
     * @link http://php.net/manual/en/pdo.getattribute.php
346
     * @return mixed
347
     */
348 13
    public function getAttribute($attribute)
349
    {
350 13
        if (array_key_exists($attribute, $this->options)) {
351 13
            return $this->options[$attribute];
352
        }
353
354
        return null;
355
    }
356
357
    /**
358
     * @link http://php.net/manual/en/pdo.getavailabledrivers.php
359
     * @return array
360
     */
361 1
    public static function getAvailableDrivers()
362
    {
363 1
        return array('oci');
364
    }
365
366
    /**
367
     * @link http://php.net/manual/en/pdo.intransaction.php
368
     * @return bool
369
     */
370 6
    public function inTransaction()
371
    {
372 6
        return $this->isTransactionStarted;
373
    }
374
375
    /**
376
     * @param string $name
377
     *
378
     * @link http://php.net/manual/en/pdo.lastinsertid.php
379
     * @return string
380
     */
381
    public function lastInsertId($name = null)
382
    {
383
        $statement = $this->query("select {$name}.currval from dual");
384
        $lastInsertedId = $statement->fetch();
385
386
        return $lastInsertedId;
387
    }
388
389
    /**
390
     * @param string $statement
391
     * @param array $driver_options
392
     *
393
     * @link http://php.net/manual/en/pdo.prepare.php
394
     * @return bool|PdoOci8Statement
395
     */
396 44
    public function prepare($statement, $driver_options = array())
397
    {
398
        // TODO Use $driver_options, eg. configure a cursor
399 44
        $exception = null;
0 ignored issues
show
Unused Code introduced by
$exception is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
400
        try {
401 44
            $options = $this->getOptions($driver_options);
402 44
            $db = $this->getConnection();
403 44
            return new PdoOci8Statement($db, $statement, $options);
404
        } catch (\Exception $ex) {
405
            $exception = new PdoOci8Exception($ex->getMessage(), $ex->getCode(), $ex);
406
        }
407
408
        // TODO Create error handler
409
        $errorMode = $this->getAttribute(\PDO::ATTR_ERRMODE);
410
        switch ($errorMode) {
411
            case \PDO::ERRMODE_EXCEPTION:
412
                throw $exception;
413
            case \PDO::ERRMODE_WARNING:
414
                trigger_error($exception->getMessage(), E_WARNING);
415
                break;
416
            case \PDO::ERRMODE_SILENT:
417
            default:
418
        }
419
420
        return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type of the parent method PDO::prepare of type PDOStatement.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
421
    }
422
423
    /**
424
     * @param string $statement
425
     * @param int $mode
426
     * @param int|string|object $arg3
427
     * @param array $ctorargs
428
     *
429
     * @link http://php.net/manual/en/pdo.query.php
430
     * @return bool|PdoOci8Statement
431
     */
432 1
    public function query($statement, $mode = \PDO::ATTR_DEFAULT_FETCH_MODE, $arg3 = null, $ctorargs = array())
433
    {
434 1
        $result = false;
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression false; of type false adds false to the return on line 454 which is incompatible with the return type of the parent method PDO::query of type PDOStatement. It seems like you forgot to handle an error condition.
Loading history...
435
        try {
436 1
            $statement = $this->prepare($statement);
0 ignored issues
show
Comprehensibility Best Practice introduced by
The expression $this->prepare($statement); of type Jpina\PdoOci8\PdoOci8Statement|false adds false to the return on line 454 which is incompatible with the return type of the parent method PDO::query of type PDOStatement. It seems like you forgot to handle an error condition.
Loading history...
437
            switch ($mode) {
438 1
                case \PDO::FETCH_CLASS:
439
                    $statement->setFetchMode($mode, $arg3, $ctorargs);
440
                    break;
441 1
                case \PDO::FETCH_INTO:
442
                    $statement->setFetchMode($mode, $arg3);
443
                    break;
444 1
                case \PDO::FETCH_COLUMN:
445 1
                default:
446 1
                    $statement->setFetchMode($mode);
447 1
            }
448 1
            $statement->execute();
449 1
            $result = $statement;
450 1
        } catch (\PDOException $ex) {
451
            //TODO Handle Exception
452
        }
453
454 1
        return $result;
455
    }
456
457
    /**
458
     * @param string $string
459
     * @param int $parameter_type
460
     *
461
     * @link http://php.net/manual/en/pdo.quote.php
462
     * @return bool|string
463
     */
464 5
    public function quote($string, $parameter_type = \PDO::PARAM_STR)
465
    {
466 5
        if (!is_scalar($string)) {
467 1
            return false;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return false; (false) is incompatible with the return type of the parent method PDO::quote of type string.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
468
        }
469
470
        try {
471 4
            if ($parameter_type !== \PDO::PARAM_STR) {
472 1
                $quotedString = (string)$string;
473 1
                $quotedString = "'" . $quotedString . "'";
474 1
                return $quotedString;
475
            }
476 4
        } catch (\Exception $ex) {
0 ignored issues
show
Unused Code introduced by
catch (\Exception $ex) { return false; } does not seem to be reachable.

This check looks for unreachable code. It uses sophisticated control flow analysis techniques to find statements which will never be executed.

Unreachable code is most often the result of return, die or exit statements that have been added for debug purposes.

function fx() {
    try {
        doSomething();
        return true;
    }
    catch (\Exception $e) {
        return false;
    }

    return false;
}

In the above example, the last return false will never be executed, because a return statement has already been met in every possible execution path.

Loading history...
477
            return false;
478
        }
479
480 4
        $quotedString = str_replace("\'", "'", $string);
481 4
        $quotedString = str_replace("'", "''", $quotedString);
482 4
        $quotedString = "'" . $quotedString . "'";
483
484 4
        return $quotedString;
485
    }
486
487 3
    protected function restoreAutocommitMode()
488
    {
489 3
        $autocommitMode = $this->getAutocommitMode();
490 3
        $this->setAttribute(\PDO::ATTR_AUTOCOMMIT, $autocommitMode);
491 3
    }
492
493
    /**
494
     * @link http://php.net/manual/en/pdo.rollback.php
495
     * @return bool
496
     */
497 3
    public function rollback()
498
    {
499 3
        if (!$this->inTransaction()) {
500 1
            throw new PdoOci8Exception('There is no active transaction');
501
        }
502
503
        try {
504 2
            $isSuccess = $this->getConnection()->rollback();
505 2
        } catch (Oci8Exception $ex) {
506
            $isSuccess = false;
507
        }
508
509 2
        $this->restoreAutocommitMode();
510
511 2
        return $isSuccess;
512
    }
513
514
    /**
515
     * @param bool $onOff
516
     */
517 12
    protected function setAutocommitMode($onOff)
518
    {
519 12
        $this->autoCommitMode = $onOff;
520 12
    }
521
522
    /**
523
     * @param int $attribute
524
     * @param mixed $value
525
     *
526
     * @link http://php.net/manual/en/pdo.setattribute.php
527
     * @return bool
528
     */
529 12
    public function setAttribute($attribute, $value)
530
    {
531
        $readOnlyAttributes = array(
532 12
            \PDO::ATTR_CLIENT_VERSION,
533 12
            \PDO::ATTR_CONNECTION_STATUS,
534 12
            \PDO::ATTR_DRIVER_NAME,
535 12
            \PDO::ATTR_PERSISTENT,
536 12
            \PDO::ATTR_SERVER_INFO,
537 12
            \PDO::ATTR_SERVER_VERSION,
538 12
        );
539
540 12 View Code Duplication
        if (array_search($attribute, $readOnlyAttributes) !== false ||
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
541 12
            !array_key_exists($attribute, $this->options)) {
542 12
            return false;
543
        }
544
545 6
        $this->options[$attribute] = $value;
546
547 6
        return true;
548
    }
549
}
550