Completed
Pull Request — develop (#209)
by Felipe
26:08 queued 36s
created

Postgres83::alterSequenceOwner()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 16
Code Lines 7

Duplication

Lines 16
Ratio 100 %

Importance

Changes 0
Metric Value
dl 16
loc 16
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 2
nop 2
1
<?php
2
3
/**
4
 * PHPPgAdmin v6.0.0-beta.48
5
 */
6
7
namespace PHPPgAdmin\Database;
8
9
/**
10
 * @file
11
 * PostgreSQL 8.3 support
12
 *
13
 * Id: Postgres82.php,v 1.10 2007/12/28 16:21:25 ioguix Exp $
14
 *
15
 * @package PHPPgAdmin
16
 */
17
class Postgres83 extends Postgres84
1 ignored issue
show
Coding Style introduced by
The property $major_version is not named in camelCase.

This check marks property names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
18
{
19
    public $major_version = 8.3;
20
21
    // List of all legal privileges that can be applied to different types
22
    // of objects.
23
    public $privlist = [
24
        'table'      => ['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'REFERENCES', 'TRIGGER', 'ALL PRIVILEGES'],
25
        'view'       => ['SELECT', 'INSERT', 'UPDATE', 'DELETE', 'REFERENCES', 'TRIGGER', 'ALL PRIVILEGES'],
26
        'sequence'   => ['SELECT', 'UPDATE', 'ALL PRIVILEGES'],
27
        'database'   => ['CREATE', 'TEMPORARY', 'CONNECT', 'ALL PRIVILEGES'],
28
        'function'   => ['EXECUTE', 'ALL PRIVILEGES'],
29
        'language'   => ['USAGE', 'ALL PRIVILEGES'],
30
        'schema'     => ['CREATE', 'USAGE', 'ALL PRIVILEGES'],
31
        'tablespace' => ['CREATE', 'ALL PRIVILEGES'],
32
    ];
33
    // List of characters in acl lists and the privileges they
34
    // refer to.
35
    public $privmap = [
36
        'r' => 'SELECT',
37
        'w' => 'UPDATE',
38
        'a' => 'INSERT',
39
        'd' => 'DELETE',
40
        'R' => 'RULE',
41
        'x' => 'REFERENCES',
42
        't' => 'TRIGGER',
43
        'X' => 'EXECUTE',
44
        'U' => 'USAGE',
45
        'C' => 'CREATE',
46
        'T' => 'TEMPORARY',
47
        'c' => 'CONNECT',
48
    ];
49
50
    // Databse functions
51
52
    /**
53
     * Return all database available on the server.
54
     *
55
     * @param string $currentdatabase database name that should be on top of the resultset
0 ignored issues
show
Documentation introduced by
Should the type for parameter $currentdatabase not be string|null?

This check looks for @param annotations where the type inferred by our type inference engine differs from the declared type.

It makes a suggestion as to what type it considers more descriptive.

Most often this is a case of a parameter that can be null in addition to its declared types.

Loading history...
56
     *
57
     * @return int|\PHPPgAdmin\ADORecordSet A recordset or an error number A list of databases, sorted alphabetically
58
     */
59 View Code Duplication
    public function getDatabases($currentdatabase = null)
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...
60
    {
61
        $conf        = $this->conf;
62
        $server_info = $this->server_info;
63
64
        if (isset($conf['owned_only']) && $conf['owned_only'] && !$this->isSuperUser()) {
65
            $username = $server_info['username'];
66
            $this->clean($username);
67
            $clause = " AND pr.rolname='{$username}'";
68
        } else {
69
            $clause = '';
70
        }
71
72
        if ($currentdatabase != null) {
0 ignored issues
show
Bug introduced by
It seems like you are loosely comparing $currentdatabase of type string|null against null; this is ambiguous if the string can be empty. Consider using a strict comparison !== instead.
Loading history...
73
            $this->clean($currentdatabase);
74
            $orderby = "ORDER BY pdb.datname = '{$currentdatabase}' DESC, pdb.datname";
75
        } else {
76
            $orderby = 'ORDER BY pdb.datname';
77
        }
78
79
        if (!$conf['show_system']) {
80
            $where = ' AND NOT pdb.datistemplate';
81
        } else {
82
            $where = ' AND pdb.datallowconn';
83
        }
84
85
        $sql = "
86
			SELECT pdb.datname AS datname, pr.rolname AS datowner, pg_encoding_to_char(encoding) AS datencoding,
87
				(SELECT description FROM pg_catalog.pg_shdescription pd WHERE pdb.oid=pd.objoid AND pd.classoid='pg_database'::regclass) AS datcomment,
88
				(SELECT spcname FROM pg_catalog.pg_tablespace pt WHERE pt.oid=pdb.dattablespace) AS tablespace,
89
				pg_catalog.pg_database_size(pdb.oid) as dbsize
90
			FROM pg_catalog.pg_database pdb LEFT JOIN pg_catalog.pg_roles pr ON (pdb.datdba = pr.oid)
91
			WHERE true
92
				{$where}
93
				{$clause}
94
			{$orderby}";
95
96
        return $this->selectSet($sql);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->selectSet($sql); of type integer|PHPPgAdmin\ADORecordSet adds the type integer to the return on line 96 which is incompatible with the return type of the parent method PHPPgAdmin\Database\Postgres::getDatabases of type PHPPgAdmin\ADORecordSet.
Loading history...
97
    }
98
99
    // Administration functions
100
101
    /**
102
     * Returns all available autovacuum per table information.
103
     *
104
     * @param string $table
105
     *
106
     * @return \PHPPgAdmin\ADORecordSet A recordset
107
     */
108
    public function getTableAutovacuum($table = '')
109
    {
110
        $sql = '';
0 ignored issues
show
Unused Code introduced by
$sql 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...
111
112
        if ($table !== '') {
113
            $this->clean($table);
114
            $c_schema = $this->_schema;
115
            $this->clean($c_schema);
116
117
            $sql = "
118
				SELECT vacrelid, nspname, relname,
119
					CASE enabled
120
						WHEN 't' THEN 'on'
121
						ELSE 'off'
122
					END AS autovacuum_enabled, vac_base_thresh AS autovacuum_vacuum_threshold,
123
					vac_scale_factor AS autovacuum_vacuum_scale_factor, anl_base_thresh AS autovacuum_analyze_threshold,
124
					anl_scale_factor AS autovacuum_analyze_scale_factor, vac_cost_delay AS autovacuum_vacuum_cost_delay,
125
					vac_cost_limit AS autovacuum_vacuum_cost_limit
126
				FROM pg_autovacuum AS a
127
					join pg_class AS c on (c.oid=a.vacrelid)
128
					join pg_namespace AS n on (n.oid=c.relnamespace)
129
				WHERE c.relname = '{$table}' AND n.nspname = '{$c_schema}'
130
				ORDER BY nspname, relname
131
			";
132
        } else {
133
            $sql = "
134
				SELECT vacrelid, nspname, relname,
135
					CASE enabled
136
						WHEN 't' THEN 'on'
137
						ELSE 'off'
138
					END AS autovacuum_enabled, vac_base_thresh AS autovacuum_vacuum_threshold,
139
					vac_scale_factor AS autovacuum_vacuum_scale_factor, anl_base_thresh AS autovacuum_analyze_threshold,
140
					anl_scale_factor AS autovacuum_analyze_scale_factor, vac_cost_delay AS autovacuum_vacuum_cost_delay,
141
					vac_cost_limit AS autovacuum_vacuum_cost_limit
142
				FROM pg_autovacuum AS a
143
					join pg_class AS c on (c.oid=a.vacrelid)
144
					join pg_namespace AS n on (n.oid=c.relnamespace)
145
				ORDER BY nspname, relname
146
			";
147
        }
148
149
        return $this->selectSet($sql);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->selectSet($sql); of type integer|PHPPgAdmin\ADORecordSet adds the type integer to the return on line 149 which is incompatible with the return type documented by PHPPgAdmin\Database\Postgres83::getTableAutovacuum of type PHPPgAdmin\ADORecordSet.
Loading history...
150
    }
151
152
    public function saveAutovacuum(
153
        $table,
154
        $vacenabled,
155
        $vacthreshold,
156
        $vacscalefactor,
157
        $anathresold,
158
        $anascalefactor,
159
        $vaccostdelay,
160
        $vaccostlimit
161
    ) {
162
        $defaults = $this->getAutovacuum();
163
        $c_schema = $this->_schema;
164
        $this->clean($c_schema);
165
        $this->clean($table);
166
167
        $rs = $this->selectSet("
168
			SELECT c.oid
169
			FROM pg_catalog.pg_class AS c
170
				LEFT JOIN pg_catalog.pg_namespace AS n ON (n.oid=c.relnamespace)
171
			WHERE
172
				c.relname = '{$table}' AND n.nspname = '{$c_schema}'
173
		");
174
175
        if ($rs->EOF) {
176
            return -1;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return -1; (integer) is incompatible with the return type of the parent method PHPPgAdmin\Database\Postgres::saveAutovacuum of type boolean.

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...
177
        }
178
179
        $toid = $rs->fields('oid');
0 ignored issues
show
Documentation introduced by
'oid' is of type string, but the function expects a object<is>.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
180
        unset($rs);
181
182
        if (empty($_POST['autovacuum_vacuum_threshold'])) {
183
            $_POST['autovacuum_vacuum_threshold'] = $defaults['autovacuum_vacuum_threshold'];
184
        }
185
186
        if (empty($_POST['autovacuum_vacuum_scale_factor'])) {
187
            $_POST['autovacuum_vacuum_scale_factor'] = $defaults['autovacuum_vacuum_scale_factor'];
188
        }
189
190
        if (empty($_POST['autovacuum_analyze_threshold'])) {
191
            $_POST['autovacuum_analyze_threshold'] = $defaults['autovacuum_analyze_threshold'];
192
        }
193
194
        if (empty($_POST['autovacuum_analyze_scale_factor'])) {
195
            $_POST['autovacuum_analyze_scale_factor'] = $defaults['autovacuum_analyze_scale_factor'];
196
        }
197
198
        if (empty($_POST['autovacuum_vacuum_cost_delay'])) {
199
            $_POST['autovacuum_vacuum_cost_delay'] = $defaults['autovacuum_vacuum_cost_delay'];
200
        }
201
202
        if (empty($_POST['autovacuum_vacuum_cost_limit'])) {
203
            $_POST['autovacuum_vacuum_cost_limit'] = $defaults['autovacuum_vacuum_cost_limit'];
204
        }
205
206
        if (empty($_POST['vacuum_freeze_min_age'])) {
207
            $_POST['vacuum_freeze_min_age'] = $defaults['vacuum_freeze_min_age'];
208
        }
209
210
        if (empty($_POST['autovacuum_freeze_max_age'])) {
211
            $_POST['autovacuum_freeze_max_age'] = $defaults['autovacuum_freeze_max_age'];
212
        }
213
214
        $rs = $this->selectSet("SELECT vacrelid
215
			FROM \"pg_catalog\".\"pg_autovacuum\"
216
			WHERE vacrelid = {$toid};");
217
218
        $status = -1; // ini
0 ignored issues
show
Unused Code introduced by
$status 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...
219
        if ($rs->RecordCount() and ($rs->fields['vacrelid'] == $toid)) {
220
            // table exists in pg_autovacuum, UPDATE
221
            $sql = sprintf(
222
                "UPDATE \"pg_catalog\".\"pg_autovacuum\" SET
223
						enabled = '%s',
224
						vac_base_thresh = %s,
225
						vac_scale_factor = %s,
226
						anl_base_thresh = %s,
227
						anl_scale_factor = %s,
228
						vac_cost_delay = %s,
229
						vac_cost_limit = %s,
230
						freeze_min_age = %s,
231
						freeze_max_age = %s
232
					WHERE vacrelid = {$toid};
233
				",
234
                ($_POST['autovacuum_enabled'] == 'on') ? 't' : 'f',
235
                $_POST['autovacuum_vacuum_threshold'],
236
                $_POST['autovacuum_vacuum_scale_factor'],
237
                $_POST['autovacuum_analyze_threshold'],
238
                $_POST['autovacuum_analyze_scale_factor'],
239
                $_POST['autovacuum_vacuum_cost_delay'],
240
                $_POST['autovacuum_vacuum_cost_limit'],
241
                $_POST['vacuum_freeze_min_age'],
242
                $_POST['autovacuum_freeze_max_age']
243
            );
244
            $status = $this->execute($sql);
245
        } else {
246
            // table doesn't exists in pg_autovacuum, INSERT
247
            $sql = sprintf(
248
                "INSERT INTO \"pg_catalog\".\"pg_autovacuum\"
249
				VALUES (%s, '%s', %s, %s, %s, %s, %s, %s, %s, %s )",
250
                $toid,
251
                ($_POST['autovacuum_enabled'] == 'on') ? 't' : 'f',
252
                $_POST['autovacuum_vacuum_threshold'],
253
                $_POST['autovacuum_vacuum_scale_factor'],
254
                $_POST['autovacuum_analyze_threshold'],
255
                $_POST['autovacuum_analyze_scale_factor'],
256
                $_POST['autovacuum_vacuum_cost_delay'],
257
                $_POST['autovacuum_vacuum_cost_limit'],
258
                $_POST['vacuum_freeze_min_age'],
259
                $_POST['autovacuum_freeze_max_age']
260
            );
261
            $status = $this->execute($sql);
262
        }
263
264
        return $status;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $status; (PHPPgAdmin\ADORecordSet) is incompatible with the return type of the parent method PHPPgAdmin\Database\Postgres::saveAutovacuum of type boolean.

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...
265
    }
266
267
    public function dropAutovacuum($table)
268
    {
269
        $c_schema = $this->_schema;
270
        $this->clean($c_schema);
271
        $this->clean($table);
272
273
        $rs = $this->selectSet("
274
			SELECT c.oid
275
			FROM pg_catalog.pg_class AS c
276
				LEFT JOIN pg_catalog.pg_namespace AS n ON (n.oid=c.relnamespace)
277
			WHERE
278
				c.relname = '{$table}' AND n.nspname = '{$c_schema}'
279
		");
280
281
        return $this->deleteRow('pg_autovacuum', ['vacrelid' => $rs->fields['oid']], 'pg_catalog');
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->deleteRow('pg_aut...'oid']), 'pg_catalog'); of type boolean|integer adds the type integer to the return on line 281 which is incompatible with the return type of the parent method PHPPgAdmin\Database\Postgres::dropAutovacuum of type boolean.
Loading history...
282
    }
283
284
    // Sequence functions
285
286
    /**
287
     * Alter a sequence's properties.
288
     *
289
     * @param \PHPPgAdmin\ADORecordSet $seqrs        The sequence RecordSet returned by getSequence()
290
     * @param int                      $increment    The sequence incremental value
291
     * @param int                      $minvalue     The sequence minimum value
292
     * @param int                      $maxvalue     The sequence maximum value
293
     * @param int                      $restartvalue The sequence current value
294
     * @param int                      $cachevalue   The sequence cache value
295
     * @param bool                     $cycledvalue  Sequence can cycle ?
296
     * @param int                      $startvalue   The sequence start value when issueing a restart (ignored)
297
     *
298
     * @return int 0 if operation was successful
0 ignored issues
show
Documentation introduced by
Should the return type not be \PHPPgAdmin\ADORecordSet|integer?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
299
     */
300
    public function alterSequenceProps(
301
        $seqrs,
302
        $increment,
303
        $minvalue,
304
        $maxvalue,
305
        $restartvalue,
306
        $cachevalue,
307
        $cycledvalue,
308
        $startvalue
309
    ) {
310
        $sql = '';
311
        /* vars are cleaned in _alterSequence */
312
        if (!empty($increment) && ($increment != $seqrs->fields['increment_by'])) {
313
            $sql .= " INCREMENT {$increment}";
314
        }
315
316
        if (!empty($minvalue) && ($minvalue != $seqrs->fields['min_value'])) {
317
            $sql .= " MINVALUE {$minvalue}";
318
        }
319
320
        if (!empty($maxvalue) && ($maxvalue != $seqrs->fields['max_value'])) {
321
            $sql .= " MAXVALUE {$maxvalue}";
322
        }
323
324
        if (!empty($restartvalue) && ($restartvalue != $seqrs->fields['last_value'])) {
325
            $sql .= " RESTART {$restartvalue}";
326
        }
327
328
        if (!empty($cachevalue) && ($cachevalue != $seqrs->fields['cache_value'])) {
329
            $sql .= " CACHE {$cachevalue}";
330
        }
331
332
        // toggle cycle yes/no
333
        if (!is_null($cycledvalue)) {
334
            $sql .= (!$cycledvalue ? ' NO ' : '').' CYCLE';
335
        }
336
337
        if ($sql != '') {
338
            $f_schema = $this->_schema;
339
            $this->fieldClean($f_schema);
340
            $sql = "ALTER SEQUENCE \"{$f_schema}\".\"{$seqrs->fields['seqname']}\" {$sql}";
341
342
            return $this->execute($sql);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->execute($sql); (PHPPgAdmin\ADORecordSet) is incompatible with the return type of the parent method PHPPgAdmin\Database\Postgres::alterSequenceProps 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...
343
        }
344
345
        return 0;
346
    }
347
348
    /**
349
     * Alter a sequence's owner.
350
     *
351
     * @param \PHPPgAdmin\ADORecordSet $seqrs The sequence RecordSet returned by getSequence()
352
     * @param string                   $owner sequence owner
353
     *
354
     * @return int 0 if operation was successful
0 ignored issues
show
Documentation introduced by
Should the return type not be \PHPPgAdmin\ADORecordSet|integer?

This check compares the return type specified in the @return annotation of a function or method doc comment with the types returned by the function and raises an issue if they mismatch.

Loading history...
355
     *
356
     * @internal param string The $name new owner for the sequence
357
     */
358 View Code Duplication
    public function alterSequenceOwner($seqrs, $owner)
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...
359
    {
360
        // If owner has been changed, then do the alteration.  We are
361
        // careful to avoid this generally as changing owner is a
362
        // superuser only function.
363
        /* vars are cleaned in _alterSequence */
364
        if (!empty($owner) && ($seqrs->fields['seqowner'] != $owner)) {
365
            $f_schema = $this->_schema;
366
            $this->fieldClean($f_schema);
367
            $sql = "ALTER TABLE \"{$f_schema}\".\"{$seqrs->fields['seqname']}\" OWNER TO \"{$owner}\"";
368
369
            return $this->execute($sql);
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->execute($sql); (PHPPgAdmin\ADORecordSet) is incompatible with the return type of the parent method PHPPgAdmin\Database\Postgres::alterSequenceOwner 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...
370
        }
371
372
        return 0;
373
    }
374
375
    // Function functions
376
377
    /**
378
     * Returns all details for a particular function.
379
     *
380
     * @param $function_oid
381
     *
382
     * @return \PHPPgAdmin\ADORecordSet Function info
383
     *
384
     * @internal param string $func name of the function to retrieve
385
     */
386
    public function getFunction($function_oid)
0 ignored issues
show
Coding Style Naming introduced by
The parameter $function_oid is not named in camelCase.

This check marks parameter names that have not been written in camelCase.

In camelCase names are written without any punctuation, the start of each new word being marked by a capital letter. Thus the name database connection string becomes databaseConnectionString.

Loading history...
387
    {
388
        $this->clean($function_oid);
389
390
        $sql = "
391
			SELECT
392
				pc.oid AS prooid, proname, pg_catalog.pg_get_userbyid(proowner) AS proowner,
393
				nspname as proschema, lanname as prolanguage, procost, prorows,
394
				pg_catalog.format_type(prorettype, NULL) as proresult, prosrc,
395
				probin, proretset, proisstrict, provolatile, prosecdef,
396
				pg_catalog.oidvectortypes(pc.proargtypes) AS proarguments,
397
				proargnames AS proargnames,
398
				pg_catalog.obj_description(pc.oid, 'pg_proc') AS procomment,
399
				proconfig
400
			FROM
401
				pg_catalog.pg_proc pc, pg_catalog.pg_language pl,
402
				pg_catalog.pg_namespace pn
403
			WHERE
404
				pc.oid = '{$function_oid}'::oid AND pc.prolang = pl.oid
405
				AND pc.pronamespace = pn.oid
406
			";
407
408
        return $this->selectSet($sql);
0 ignored issues
show
Bug Compatibility introduced by
The expression $this->selectSet($sql); of type integer|PHPPgAdmin\ADORecordSet adds the type integer to the return on line 408 which is incompatible with the return type documented by PHPPgAdmin\Database\Postgres83::getFunction of type PHPPgAdmin\ADORecordSet.
Loading history...
409
    }
410
411
    // Capabilities
412
    public function hasQueryKill()
413
    {
414
        return false;
415
    }
416
417
    public function hasDatabaseCollation()
418
    {
419
        return false;
420
    }
421
422
    public function hasAlterSequenceStart()
423
    {
424
        return false;
425
    }
426
}
427