Completed
Push — master ( cfcf82...657c44 )
by Nick
21:51 queued 16:40
created

Connection::fatal_error()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 11
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 5
nc 1
nop 1
dl 0
loc 11
ccs 0
cts 5
cp 0
crap 2
rs 9.4285
c 0
b 0
f 0
1
<?php
1 ignored issue
show
Coding Style Compatibility introduced by
For compatibility and reusability of your code, PSR1 recommends that a file should introduce either new symbols (like classes, functions, etc.) or have side-effects (like outputting something, or including other files), but not both at the same time. The first symbol is defined on line 45 and the first side effect is on line 7.

The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.

The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.

To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.

Loading history...
2
3
namespace MySociety\TheyWorkForYou\Db;
4
5
// We'll add up the times of each query so we can output the page total at the end.
6
7
global $mysqltotalduration;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
8
$mysqltotalduration = 0.0;
9
$global_connection = null;
10
11
/**
12
 * Database Connection
13
 *
14
 * Somewhere (probably in `includes/easyparliament/init.php`) there should be
15
 * something like:
16
 *
17
 * ```php
18
 * Class ParlDB extends \MySociety\TheyWorkForYou\Db\Connection {
19
 *     function ParlDB() {
20
 *         $this->init (OPTION_TWFY_DB_HOST, OPTION_TWFY_DB_USER, OPTION_TWFY_DB_PASS, OPTION_TWFY_DB_NAME);
21
 *     }
22
 * }
23
 * ```
24
 *
25
 * Then, when you need to do queries, you do:
26
 *
27
 * ```php
28
 * $db = new ParlDB;
29
 * $q = $db->query("SELECT haddock FROM fish");
30
 * ```
31
 *
32
 * `$q` is then an instance of `Db\Query`.
33
 *
34
 * If other databases are needed, we just need to create a class for each, each
35
 * one extending `Db\Connection`.
36
 *
37
 * Call `$db->display_total_duration()` at the end of a page to send total
38
 * query time to `debug()`.
39
 *
40
 * Depends on having the `debug()` and `getmicrotime()` functions available
41
 * elsewhere to output debugging info.
42
 *
43
 */
44
45
class Connection {
46
47
    /**
48
     * Initialise Connection
49
     *
50
     * If an existing MySQL connection exists, use that. Otherwise, create a
51
     * new connection.
52
     *
53
     * @param string $db_host The hostname of the database server
54
     * @param string $db_user The user to connect to the database as
55
     * @param string $db_pass The password for the database user
56
     * @param string $db_name The name of the database
57
     *
58
     * @return boolean If the connection has been created successfully.
59
     */
60
61 82
    public function init($db_host, $db_user, $db_pass, $db_name) {
62 82
        global $global_connection;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
63
        // These vars come from config.php.
64
65 82
        if (!$global_connection) {
66
            $dsn = 'mysql:charset=utf8;dbname=' . $db_name . ';host=' . $db_host;
67
68
            try {
69
                $conn = new \PDO($dsn, $db_user, $db_pass);
70
            } catch (\PDOException $e) {
71
                $this->fatal_error('We were unable to connect to the TheyWorkForYou database for some reason. Please try again in a few minutes.');
72
            }
73
74
            $global_connection = $conn;
75
        }
76
77 82
        $this->conn = $global_connection;
78
79 82
        return true;
80
    }
81
82
    /**
83
     * Quote String
84
     *
85
     * @param string $string The string to quote.
86
     *
87
     * @return string The quoted string.
88
     */
89
90
    public function quote($string) {
91
        return $this->conn->quote($string);
92
    }
93
94
    /**
95
     * Execute Query
96
     *
97
     * Takes a query, executes it and turns it into a query object.
98
     *
99
     * @param string     $sql    The SQL query to execute
100
     * @param array|null $params Parameters to inject into the query
101
     *
102
     * @return Query An object containing the results of the query.
103
     */
104
105 76
    public function query($sql, $params = null) {
106
107 76
        $start = getmicrotime();
108 76
        $q = new \MySociety\TheyWorkForYou\Db\Query($this->conn);
109 76
        $q->query($sql, $params);
110
111 76
        $duration = getmicrotime() - $start;
112 76
        global $mysqltotalduration;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
113 76
        $mysqltotalduration += $duration;
114 76
        twfy_debug("SQL", "Complete after $duration seconds.");
115
        // We could also output $q->mysql_info() here, but that's for
116
        // PHP >= 4.3.0.
117 76
        return $q;
118
    }
119
120
    /**
121
     * Display Total Duration
122
     *
123
     * Displays the total time taken to execute all queries made via this
124
     * connection.
125
     */
126
127
    public function display_total_duration() {
128
        global $mysqltotalduration;
0 ignored issues
show
Compatibility Best Practice introduced by
Use of global functionality is not recommended; it makes your code harder to test, and less reusable.

Instead of relying on global state, we recommend one of these alternatives:

1. Pass all data via parameters

function myFunction($a, $b) {
    // Do something
}

2. Create a class that maintains your state

class MyClass {
    private $a;
    private $b;

    public function __construct($a, $b) {
        $this->a = $a;
        $this->b = $b;
    }

    public function myFunction() {
        // Do something
    }
}
Loading history...
129
        twfy_debug("TIME", "Total time for MySQL queries on this page: " . $mysqltotalduration . " seconds.");
130
    }
131
132
    /**
133
     * Fatal Error
134
     *
135
     * Display a fatal error and exit the script.
136
     *
137
     * @param string $error The error message to display.
138
     */
139
140
    public function fatal_error($error) {
141
        echo '
142
<html><head><title>TheyWorkForYou - Database Error</title></head>
143
<body>
144
<h1><a href="/"><img border="0" src="/images/theyworkforyoucom.gif" width="293" height="28" alt="TheyWorkForYou"></a></h1>
145
<h2>Database error</h2>
146
';
147
        echo "<p>$error</p>";
148
        echo '</body></html>';
149
        exit;
0 ignored issues
show
Coding Style Compatibility introduced by
The method fatal_error() contains an exit expression.

An exit expression should only be used in rare cases. For example, if you write a short command line script.

In most cases however, using an exit expression makes the code untestable and often causes incompatibilities with other libraries. Thus, unless you are absolutely sure it is required here, we recommend to refactor your code to avoid its usage.

Loading history...
150
    }
151
152
}
153