GitHub Access Token became invalid

It seems like the GitHub access token used for retrieving details about this repository from GitHub became invalid. This might prevent certain types of inspections from being run (in particular, everything related to pull requests).
Please ask an admin of your repository to re-new the access token on this website.

CodendiUpgrade   B
last analyzed

Complexity

Total Complexity 47

Size/Duplication

Total Lines 244
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 3
Metric Value
wmc 47
lcom 1
cbo 3
dl 0
loc 244
rs 8.439

18 Methods

Rating   Name   Duplication   Size   Complexity  
A getUpgradeErrors() 0 3 1
A addUpgradeError() 0 3 1
A isUpgradeError() 0 3 1
A getEnvironment() 0 3 1
A databaseConnect() 0 3 1
A isAlreadyApplied() 0 9 4
A isAlreadyAppliedWithSuccess() 0 9 4
A tableExists() 0 10 4
A fieldExists() 0 11 4
A CodendiUpgrade() 0 6 1
A setEnvironment() 0 9 2
A _isWebExecution() 0 6 2
A isDatabaseConnected() 0 8 1
B indexNameExists() 0 13 5
A apply() 0 21 4
B storeUpgrade() 0 17 5
A writeFeedback() 0 14 3
A getLineSeparator() 0 12 3

How to fix   Complexity   

Complex Class

Complex classes like CodendiUpgrade often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use CodendiUpgrade, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * Copyright (c) Xerox Corporation, Codendi Team, 2001-2009. All rights reserved
5
 * 
6
 * 
7
 *
8
 * CodendiUpgrade
9
 * Generic class for upgrading Codendi Server.
10
 *
11
 */
12
/*
13
14
Files must be XXX_filename.class.php where XXX = 000 to 999
15
Class must be Update_XXX where XXX is the same as the filename
16
17
---------8<---------------TEMPLATE:-----
18
//
19
// Copyright (c) Xerox Corporation, Codendi Team, 2001-2009. All rights reserved
20
//
21
// 
22
23
24
require_once('CodendiUpgrade.class.php');
25
26
class Update_001 extends CodendiUpgrade {
27
28
    function _process() {
29
        echo $this->getLineSeparator();
30
        echo "Execution of script : ".get_class($this);
31
        echo $this->getLineSeparator();
32
        echo "HERE PLACE THE PROCESS...";
33
        //$this->addUpgradeError("Erreur systeme");
34
        echo $this->getLineSeparator();
35
    }
36
37
}
38
---------8<-----------------------------
39
40
*/
41
42
// Defines all of the Codendi settings first (hosts, databases, etc.)
43
require_once(getenv('CODENDI_LOCAL_INC')?getenv('CODENDI_LOCAL_INC'):'/etc/codendi/conf/local.inc');
44
require($GLOBALS['db_config_file']);
45
//database abstraction
46
require_once(dirname(__FILE__).'/../../common/dao/include/DataAccessObject.class.php');
47
require_once(dirname(__FILE__).'/../../common/dao/CodendiDataAccess.class.php');
48
49
define("WEB_ENVIRONMENT", "web");
50
define("CONSOLE_ENVIRONMENT", "console");
51
52
/*abstract*/ class CodendiUpgrade extends DataAccessObject {
53
54
    //abstract public function _process();    // signature for the _process function.
55
56
    /**
57
     * @var array{string} $_upgradeError an array of errors appeared in upgrade process
0 ignored issues
show
Documentation introduced by
The doc-type array{string} could not be parsed: Unknown type name "array{string}" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
58
     */
59
    var $_upgradeErrors = array();
60
    /**
61
     * @var string $_environment execution environment
62
     */
63
    var $_environment;
64
    
65
    
66
    function CodendiUpgrade() {
67
        $this->_upgradeError = null;
68
        $this->setEnvironment();
69
        $da =& CodendiDataAccess::instance();
70
        parent::DataAccessObject($da);
0 ignored issues
show
Comprehensibility Bug introduced by
It seems like you call parent on a different method (DataAccessObject() instead of CodendiUpgrade()). Are you sure this is correct? If so, you might want to change this to $this->DataAccessObject().

This check looks for a call to a parent method whose name is different than the method from which it is called.

Consider the following code:

class Daddy
{
    protected function getFirstName()
    {
        return "Eidur";
    }

    protected function getSurName()
    {
        return "Gudjohnsen";
    }
}

class Son
{
    public function getFirstName()
    {
        return parent::getSurname();
    }
}

The getFirstName() method in the Son calls the wrong method in the parent class.

Loading history...
71
    }
72
    
73
    function getUpgradeErrors() {
74
        return $this->_upgradeErrors;
75
    }
76
    function addUpgradeError($upgradeError) {
77
        $this->_upgradeErrors[] = $upgradeError;
78
    }
79
    function isUpgradeError() {
80
        return (count($this->getUpgradeErrors()) > 0); 
81
    }
82
    function setEnvironment() {
83
        $default_environment = WEB_ENVIRONMENT;
84
        $this->_environment = $default_environment;
85
        if ($this->_isWebExecution()) {
86
            $this->_environment = WEB_ENVIRONMENT;
87
        } else {
88
            $this->_environment = CONSOLE_ENVIRONMENT;
89
        }
90
    }
91
    function getEnvironment() {
92
        return $this->_environment;
93
    }
94
    function _isWebExecution() {
95
        if (isset($_SERVER["HTTP_HOST"])) {
96
            return true;
97
        }
98
        return false;
99
    }
100
    
101
    /**
102
     * Set a connection to the database
103
     */
104
    function databaseConnect() {
105
        return true;
106
    }
107
    /**
108
     * Returns if the database connection is set or not
109
     * @return true if the database connection is set, false otherwise
110
     */
111
    function isDatabaseConnected() {
112
        /*$isConnected = false;
113
        if (getConnection()) {
114
            $isConnected = true;
115
        }
116
        return $isConnected;*/
117
        return true;
118
    }
119
    
120
    /**
121
     * Test if the current upgrade has already been applied or not
122
     *
123
     * @return boolean true if the current upgrade has already been applied, false otherwise.
124
     */
125
    function isAlreadyApplied() {
126
        $upgrade_name = get_class($this);
127
        $sql = "SELECT * FROM plugin_serverupdate_upgrade WHERE script = '".$upgrade_name."'";
128
        $dar = $this->retrieve($sql);
129
        if ($dar && !$dar->isError() && $dar->rowCount() > 0) {
130
            return true;
131
        }
132
        return false;
133
    }
134
    
135
    /**
136
     * Test if the current upgrade has already been applied WITH SUCCESS or not
137
     *
138
     * @return boolean true if the current upgrade has already been applied with success, false otherwise.
139
     */
140
    function isAlreadyAppliedWithSuccess() {
141
        $upgrade_name = get_class($this);
142
        $sql = "SELECT * FROM plugin_serverupdate_upgrade WHERE script = '".$upgrade_name."' AND success = 1";
143
        $dar = $this->retrieve($sql);
144
        if ($dar && !$dar->isError() && $dar->rowCount() > 0) {
145
            return true;
146
        }
147
        return false;
148
    }
149
    
150
    /**
151
     * Test if a table exists.
152
     *
153
     * @return boolean true if given table exists in database.
154
     */
155
    function tableExists($table) {
156
        $sql = sprintf('SHOW TABLES LIKE %s', 
157
                       $this->da->quoteSmart($table));
158
        $dar = $this->retrieve($sql);
159
        if($dar && !$dar->isError() && $dar->rowCount() == 1) {
160
            return true;
161
        } else {
162
            return false;
163
        }
164
    }
165
166
    /**
167
     * Test if field exists in given table.
168
     *
169
     * @return boolean true if given field exists in given table.
170
     */
171
    function fieldExists($table, $field) {
172
        $sql = sprintf('SHOW COLUMNS FROM %s LIKE %s', 
173
                       $table,
174
                       $this->da->quoteSmart($field));
175
        $dar = $this->retrieve($sql);
176
        if($dar && !$dar->isError() && $dar->rowCount() == 1) {
177
            return true;
178
        } else {
179
            return false;
180
        }
181
    }
182
183
    /**
184
     * Test if index exists in given table.
185
     *
186
     * @return boolean true if given index exists in given table.
187
     */
188
    function indexNameExists($table, $index) {
189
        $sql = sprintf('SHOW INDEX FROM %s',
190
                       $table);
191
        $dar = $this->retrieve($sql);
192
        if($dar && !$dar->isError()) {
193
            while($row = $dar->getRow()) {
194
                if($row['Key_name'] == $index) {
195
                    return true;
196
                }
197
            }
198
        }
199
        return false;
200
    }
201
202
    /**
203
     * Apply the upgrade
204
     * This is the generic function :
205
     * It checks some recurrent things (database connection, etc.)
206
     * and call the _process function redefined in the concrete subclasses
207
     *
208
     */
209
    function apply() {
210
        // 1) Connection to the database
211
        $this->databaseConnect();
0 ignored issues
show
Unused Code introduced by
The call to the method CodendiUpgrade::databaseConnect() seems un-needed as the method has no side-effects.

PHP Analyzer performs a side-effects analysis of your code. A side-effect is basically anything that might be visible after the scope of the method is left.

Let’s take a look at an example:

class User
{
    private $email;

    public function getEmail()
    {
        return $this->email;
    }

    public function setEmail($email)
    {
        $this->email = $email;
    }
}

If we look at the getEmail() method, we can see that it has no side-effect. Whether you call this method or not, no future calls to other methods are affected by this. As such code as the following is useless:

$user = new User();
$user->getEmail(); // This line could safely be removed as it has no effect.

On the hand, if we look at the setEmail(), this method _has_ side-effects. In the following case, we could not remove the method call:

$user = new User();
$user->setEmail('email@domain'); // This line has a side-effect (it changes an
                                 // instance variable).
Loading history...
212
        if ($this->isDatabaseConnected()) {
213
            // 2) Check that the script has not already been applied
214
            if (!$this->isAlreadyApplied()) {
215
                // 3) execute the upgrade
216
                $this->_process();
217
            } else {
218
                $this->addUpgradeError("Upgrade already applied.");
219
            }
220
            // 4) store the upgrade in database
221
            $store_success = $this->storeUpgrade();
222
            if (!$store_success) {
223
                $this->addUpgradeError("Upgrade store in database failed : ".$this->da->isError());
224
            }
225
        } else {
226
            // No database connection (impossible to store it in tha database, because no connection)
227
            $this->addUpgradeError("No database connection. Upgrade failed.");
228
        }
229
    }
230
231
    /**
232
     * Store the result of the upgrade in the database.
233
     *
234
     * @return boolean true if the storage was fine, false otherwise
235
     */
236
    function storeUpgrade() {
237
        $upgrade_stored = false;
238
        if ($this->isDatabaseconnected()) {
239
            /*$errors = array();
240
            foreach( $this->getUpgradeErrors() as $e) {
241
                $errors[] = $this->da->quoteSmart($e);
242
            }*/
243
            // Store the upgrade into database
244
            $sql = "INSERT INTO plugin_serverupdate_upgrade(date, script, execution_mode, success, error) ";
245
            $sql .= "VALUES (UNIX_TIMESTAMP(), '".get_class($this)."', '".$this->getEnvironment()."', '".(($this->isUpgradeError())?0:1)."', ".$this->da->quoteSmart(implode("; ", $this->getUpgradeErrors())).")";
246
            $updated = $this->update($sql);
247
            if($updated && $this->da->affectedRows() === 1) {
248
                $upgrade_stored = true;
249
            }
250
        }
251
        return $upgrade_stored;
252
    }
253
254
255
    /**
256
     * Write a message in the ad-hoc output.
257
     * - the web interface if the execution is a web one
258
     * - the standard output error if the execution if a console one
259
     *
260
     * @param string $feedback the text to display
261
     */
262
    function writeFeedback($feedback) {
263
        switch ($this->getEnvironment()) {
264
            case WEB_ENVIRONMENT:
265
                echo $feedback;
266
                break;
267
            case CONSOLE_ENVIRONMENT:
268
                $stderr = fopen('php://stderr', 'w');
269
                fwrite($stderr, $feedback);
270
                fclose($stderr);
271
                break;
272
            default:
273
                break;
274
        }
275
    }
276
    
277
    /** 
278
     * Returns the line separator regarding the execution environment
279
     *
280
     * @return string the string representing the line separator depending the execution mode
281
     */
282
    function getLineSeparator() {
283
        switch ($this->getEnvironment()) {
284
            case WEB_ENVIRONMENT:
285
                return  "<br />";
286
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
287
            case CONSOLE_ENVIRONMENT:
288
                return "\n";
289
                break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
290
            default:
291
                break;
292
        }
293
    }
294
295
}
296
297
?>
298