| Total Complexity | 107 |
| Total Lines | 557 |
| Duplicated Lines | 0 % |
| Changes | 0 | ||
Complex classes like setup_detection 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.
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 setup_detection, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 19 | class setup_detection |
||
| 20 | { |
||
| 21 | /** |
||
| 22 | * Get available application versions and data from filesystem |
||
| 23 | * |
||
| 24 | * @return array $setup_info |
||
| 25 | */ |
||
| 26 | function get_versions() |
||
| 27 | { |
||
| 28 | $setup_info = array(); |
||
| 29 | $d = dir(EGW_SERVER_ROOT); |
||
| 30 | while($entry=$d->read()) |
||
| 31 | { |
||
| 32 | if($entry != ".." && $entry != 'setup' && is_dir(EGW_SERVER_ROOT . '/' . $entry)) |
||
| 33 | { |
||
| 34 | $f = EGW_SERVER_ROOT . '/' . $entry . '/setup/setup.inc.php'; |
||
| 35 | if (@file_exists ($f)) |
||
| 36 | { |
||
| 37 | include($f); |
||
| 38 | $setup_info[$entry]['filename'] = $f; |
||
| 39 | } |
||
| 40 | } |
||
| 41 | } |
||
| 42 | $d->close(); |
||
| 43 | |||
| 44 | // _debug_array($setup_info); |
||
| 45 | @ksort($setup_info); |
||
|
|
|||
| 46 | return $setup_info; |
||
| 47 | } |
||
| 48 | |||
| 49 | /** |
||
| 50 | * Get versions of installed applications from database |
||
| 51 | * |
||
| 52 | * @param array $setup_info |
||
| 53 | * @return array $setup_info |
||
| 54 | */ |
||
| 55 | function get_db_versions($setup_info=null) |
||
| 56 | { |
||
| 57 | try { // catch DB errors |
||
| 58 | $GLOBALS['egw_setup']->set_table_names(); |
||
| 59 | |||
| 60 | if($GLOBALS['egw_setup']->table_exist(array($GLOBALS['egw_setup']->applications_table),true)) |
||
| 61 | { |
||
| 62 | /* one of these tables exists. checking for post/pre beta version */ |
||
| 63 | if($GLOBALS['egw_setup']->applications_table != 'applications') |
||
| 64 | { |
||
| 65 | foreach($GLOBALS['egw_setup']->db->select($GLOBALS['egw_setup']->applications_table,'*',false,__LINE__,__FILE__) as $row) |
||
| 66 | { |
||
| 67 | $app = $row['app_name']; |
||
| 68 | if (!isset($setup_info[$app])) // app source no longer there |
||
| 69 | { |
||
| 70 | $setup_info[$app] = array( |
||
| 71 | 'name' => $app, |
||
| 72 | 'tables' => $row['app_tables'], |
||
| 73 | 'version' => 'deleted', |
||
| 74 | ); |
||
| 75 | } |
||
| 76 | $setup_info[$app]['currentver'] = $row['app_version']; |
||
| 77 | $setup_info[$app]['enabled'] = $row['app_enabled']; |
||
| 78 | } |
||
| 79 | /* This is to catch old setup installs that did not have phpgwapi listed as an app */ |
||
| 80 | $tmp = @$setup_info['phpgwapi']['version']; /* save the file version */ |
||
| 81 | if (isset($setup_info['api']['version'])) |
||
| 82 | { |
||
| 83 | // new api, dont care about old pre egroupware stuff |
||
| 84 | } |
||
| 85 | elseif(!@$setup_info['phpgwapi']['currentver']) |
||
| 86 | { |
||
| 87 | $setup_info['phpgwapi']['currentver'] = $setup_info['admin']['currentver']; |
||
| 88 | $setup_info['phpgwapi']['version'] = $setup_info['admin']['currentver']; |
||
| 89 | $setup_info['phpgwapi']['enabled'] = $setup_info['admin']['enabled']; |
||
| 90 | // _debug_array($setup_info['phpgwapi']);exit; |
||
| 91 | // There seems to be a problem here. If ['phpgwapi']['currentver'] is set, |
||
| 92 | // The GLOBALS never gets set. |
||
| 93 | $GLOBALS['setup_info'] = $setup_info; |
||
| 94 | $GLOBALS['egw_setup']->register_app('phpgwapi'); |
||
| 95 | } |
||
| 96 | else |
||
| 97 | { |
||
| 98 | $GLOBALS['setup_info'] = $setup_info; |
||
| 99 | } |
||
| 100 | $setup_info['phpgwapi']['version'] = $tmp; /* restore the file version */ |
||
| 101 | } |
||
| 102 | else |
||
| 103 | { |
||
| 104 | foreach($GLOBALS['egw_setup']->db->query('select * from applications') as $row) |
||
| 105 | { |
||
| 106 | if($row['app_name'] == 'admin') |
||
| 107 | { |
||
| 108 | $setup_info['phpgwapi']['currentver'] = $row['app_version']; |
||
| 109 | } |
||
| 110 | $setup_info[$row['app_name']]['currentver'] = $row['app_version']; |
||
| 111 | } |
||
| 112 | } |
||
| 113 | } |
||
| 114 | } |
||
| 115 | catch (Api\Db\Exception $e) { |
||
| 116 | unset($e); |
||
| 117 | // ignore db errors |
||
| 118 | } |
||
| 119 | // remove emailadmin, if it is not already installed, it exists only to allow to update to from versions before 16.1 |
||
| 120 | if (isset($setup_info['emailadmin']) && empty($setup_info['emailadmin']['currentver'])) |
||
| 121 | { |
||
| 122 | unset($setup_info['emailadmin']); |
||
| 123 | } |
||
| 124 | // _debug_array($setup_info); |
||
| 125 | return $setup_info; |
||
| 126 | } |
||
| 127 | |||
| 128 | /** |
||
| 129 | * Compare versions from filesystem and database and set status: |
||
| 130 | * U Upgrade required/available |
||
| 131 | * R upgrade in pRogress |
||
| 132 | * C upgrade Completed successfully |
||
| 133 | * D Dependency failure |
||
| 134 | * P Post-install dependency failure |
||
| 135 | * F upgrade Failed |
||
| 136 | * V Version mismatch at end of upgrade (Not used, proposed only) |
||
| 137 | * M Missing files at start of upgrade (Not used, proposed only) |
||
| 138 | */ |
||
| 139 | function compare_versions($setup_info,$try_downgrade=false) |
||
| 140 | { |
||
| 141 | foreach($setup_info as $key => $value) |
||
| 142 | { |
||
| 143 | //echo '<br>'.$value['name'].'STATUS: '.$value['status']; |
||
| 144 | /* Only set this if it has not already failed to upgrade - Milosch */ |
||
| 145 | if(!( (@$value['status'] == 'F') || (@$value['status'] == 'C') )) |
||
| 146 | { |
||
| 147 | //if ($setup_info[$key]['currentver'] > $setup_info[$key]['version']) |
||
| 148 | if(!$try_downgrade && $GLOBALS['egw_setup']->amorethanb($value['currentver'],@$value['version']) || |
||
| 149 | $value['version'] == 'deleted') |
||
| 150 | { |
||
| 151 | $setup_info[$key]['status'] = 'V'; |
||
| 152 | } |
||
| 153 | elseif(@$value['currentver'] == @$value['version']) |
||
| 154 | { |
||
| 155 | $setup_info[$key]['status'] = 'C'; |
||
| 156 | } |
||
| 157 | elseif($GLOBALS['egw_setup']->alessthanb(@$value['currentver'],@$value['version'])) |
||
| 158 | { |
||
| 159 | $setup_info[$key]['status'] = 'U'; |
||
| 160 | } |
||
| 161 | else |
||
| 162 | { |
||
| 163 | $setup_info[$key]['status'] = 'U'; |
||
| 164 | } |
||
| 165 | } |
||
| 166 | } |
||
| 167 | // _debug_array($setup_info); |
||
| 168 | return $setup_info; |
||
| 169 | } |
||
| 170 | |||
| 171 | function check_depends($setup_info) |
||
| 172 | { |
||
| 173 | /* Run the list of apps */ |
||
| 174 | foreach($setup_info as $key => $value) |
||
| 175 | { |
||
| 176 | /* Does this app have any depends */ |
||
| 177 | if(isset($value['depends'])) |
||
| 178 | { |
||
| 179 | /* If so find out which apps it depends on */ |
||
| 180 | foreach($value['depends'] as $depkey => $depvalue) |
||
| 181 | { |
||
| 182 | /* I set this to False until we find a compatible version of this app */ |
||
| 183 | $setup_info['depends'][$depkey]['status'] = False; |
||
| 184 | /* Now we loop thru the versions looking for a compatible version */ |
||
| 185 | |||
| 186 | foreach($depvalue['versions'] as $depsvalue) |
||
| 187 | { |
||
| 188 | $currentver = $setup_info[$depvalue['appname']]['currentver']; |
||
| 189 | if ($depvalue['appname'] == 'phpgwapi' && substr($currentver,0,6) == '0.9.99') |
||
| 190 | { |
||
| 191 | $currentver = '0.9.14.508'; |
||
| 192 | } |
||
| 193 | $major = $GLOBALS['egw_setup']->get_major($currentver); |
||
| 194 | if ($major >= $depsvalue || $major == $depsvalue && substr($major,0,strlen($depsvalue)+1) == $depsvalue.'.') |
||
| 195 | { |
||
| 196 | $setup_info['depends'][$depkey]['status'] = True; |
||
| 197 | } |
||
| 198 | else // check if majors are equal and minors greater or equal |
||
| 199 | { |
||
| 200 | $major_depsvalue = $GLOBALS['egw_setup']->get_major($depsvalue); |
||
| 201 | $tmp = explode('.',$depsvalue); $minor_depsvalue = array_pop($tmp); |
||
| 202 | $tmp2 = explode('.',$currentver); $minor = array_pop($tmp2); |
||
| 203 | if ($major == $major_depsvalue && $minor <= $minor_depsvalue) |
||
| 204 | { |
||
| 205 | $setup_info['depends'][$depkey]['status'] = True; |
||
| 206 | } |
||
| 207 | } |
||
| 208 | //echo "<p>app=$key depends on $depvalue[appname](".implode(',',$depvalue['versions']).") current=$currentver, major=$major, depsvalue=$depsvalue, major_depsvalue=$major_depsvalue, minor_depsvalue=$minor_depsvalue, minor=$minor ==> ".(int)$setup_info['depends'][$depkey]['status']."</p>\n"; |
||
| 209 | } |
||
| 210 | } |
||
| 211 | /* |
||
| 212 | Finally, we loop through the dependencies again to look for apps that still have a failure status |
||
| 213 | If we find one, we set the apps overall status as a dependency failure. |
||
| 214 | */ |
||
| 215 | foreach($value['depends'] as $depkey => $depvalue) |
||
| 216 | { |
||
| 217 | if ($setup_info['depends'][$depkey]['status'] == False) |
||
| 218 | { |
||
| 219 | /* Only set this if it has not already failed to upgrade - Milosch */ |
||
| 220 | if($setup_info[$key]['status'] != 'F')//&& $setup_info[$key]['status'] != 'C') |
||
| 221 | { |
||
| 222 | /* Added check for status U - uninstalled apps carry this flag (upgrade from nothing == install). |
||
| 223 | * This should fix apps showing post-install dep failure when they are not yet installed. |
||
| 224 | */ |
||
| 225 | if($setup_info[$key]['status'] == 'C' || $setup_info[$key]['status'] == 'U') |
||
| 226 | { |
||
| 227 | $setup_info[$key]['status'] = 'D'; |
||
| 228 | } |
||
| 229 | else |
||
| 230 | { |
||
| 231 | $setup_info[$key]['status'] = 'P'; |
||
| 232 | } |
||
| 233 | } |
||
| 234 | } |
||
| 235 | } |
||
| 236 | } |
||
| 237 | } |
||
| 238 | return $setup_info; |
||
| 239 | } |
||
| 240 | |||
| 241 | /** |
||
| 242 | * Called during the mass upgrade routine (Stage 1) to check for apps |
||
| 243 | * that wish to be excluded from this process. |
||
| 244 | */ |
||
| 245 | function upgrade_exclude($setup_info) |
||
| 255 | } |
||
| 256 | |||
| 257 | /** |
||
| 258 | * Check if header exists and is up to date |
||
| 259 | * |
||
| 260 | * @return int 1=no header.inc.php, 2=no header admin pw, 3=no instances, 4=need upgrade, 10=ok |
||
| 261 | */ |
||
| 262 | function check_header() |
||
| 290 | } |
||
| 291 | |||
| 292 | /** |
||
| 293 | * Check if database exists |
||
| 294 | * |
||
| 295 | * @param array $setup_info =null default use $GLOBALS['setup_info'] |
||
| 296 | * @return int 1=no database, 3=empty, 4=need upgrade, 10=complete |
||
| 297 | */ |
||
| 298 | function check_db($setup_info=null) |
||
| 299 | { |
||
| 300 | if (!$setup_info) $setup_info = $GLOBALS['setup_info']; |
||
| 301 | |||
| 302 | try { // catch DB errors |
||
| 303 | if (!$GLOBALS['egw_setup']->db->Link_ID) |
||
| 304 | { |
||
| 305 | $old = error_reporting(); |
||
| 306 | error_reporting($old & ~E_WARNING); // no warnings |
||
| 307 | $GLOBALS['egw_setup']->db->connect(); |
||
| 308 | error_reporting($old); |
||
| 309 | |||
| 310 | $GLOBALS['egw_setup']->set_table_names(); |
||
| 311 | } |
||
| 312 | } |
||
| 313 | catch(Api\Db\Exception $e) { |
||
| 314 | // ignore error |
||
| 315 | } |
||
| 316 | |||
| 317 | if (!$GLOBALS['egw_setup']->db->Link_ID || !$GLOBALS['egw_setup']->db->Link_ID->_connectionID) |
||
| 318 | { |
||
| 319 | $GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 1 (Create Database)'; |
||
| 320 | return 1; |
||
| 321 | } |
||
| 322 | if(!isset($setup_info['api']['currentver'])) |
||
| 323 | { |
||
| 324 | $setup_info = $this->get_db_versions($setup_info); |
||
| 325 | } |
||
| 326 | // first check new api installed and up to date |
||
| 327 | if (isset($setup_info['api']['currentver'])) |
||
| 328 | { |
||
| 329 | if($setup_info['api']['currentver'] == $setup_info['api']['version']) |
||
| 330 | { |
||
| 331 | $GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 1 (Tables Complete)'; |
||
| 332 | return 10; |
||
| 333 | } |
||
| 334 | else |
||
| 335 | { |
||
| 336 | $GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 1 (Tables need upgrading)'; |
||
| 337 | return 4; |
||
| 338 | } |
||
| 339 | } |
||
| 340 | // then check old phpgwapi |
||
| 341 | elseif (isset($setup_info['phpgwapi']['currentver'])) |
||
| 342 | { |
||
| 343 | if($setup_info['phpgwapi']['currentver'] == $setup_info['phpgwapi']['version']) |
||
| 344 | { |
||
| 345 | $GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 1 (Tables Complete)'; |
||
| 346 | return 10; |
||
| 347 | } |
||
| 348 | else |
||
| 349 | { |
||
| 350 | $GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 1 (Tables need upgrading)'; |
||
| 351 | return 4; |
||
| 352 | } |
||
| 353 | } |
||
| 354 | else |
||
| 355 | { |
||
| 356 | /* no tables, so checking if we can create them */ |
||
| 357 | try { |
||
| 358 | $GLOBALS['egw_setup']->db->query('CREATE TABLE egw_testrights ( testfield varchar(5) NOT NULL )'); |
||
| 359 | $GLOBALS['egw_setup']->db->query('DROP TABLE egw_testrights'); |
||
| 360 | $GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 3 (Install Applications)'; |
||
| 361 | return 3; |
||
| 362 | } |
||
| 363 | catch (Api\Db\Exception $e) { |
||
| 364 | unset($e); |
||
| 365 | $GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 1 (Create Database)'; |
||
| 366 | return 1; |
||
| 367 | } |
||
| 368 | } |
||
| 369 | } |
||
| 370 | |||
| 371 | /** |
||
| 372 | * Check if EGw configuration exists |
||
| 373 | * |
||
| 374 | * @return int 1 = Needs config, ..., 10 = Config Ok |
||
| 375 | */ |
||
| 376 | function check_config() |
||
| 377 | { |
||
| 378 | if(@$GLOBALS['egw_info']['setup']['stage']['db'] != 10) |
||
| 379 | { |
||
| 380 | return ''; |
||
| 381 | } |
||
| 382 | |||
| 383 | try { // catch db errors |
||
| 384 | foreach($GLOBALS['egw_setup']->db->select($GLOBALS['egw_setup']->config_table, |
||
| 385 | 'config_name,config_value',array('config_app' => 'phpgwapi'),__LINE__,__FILE__) as $row) |
||
| 386 | { |
||
| 387 | $config[$row['config_name']] = $row['config_value']; |
||
| 388 | } |
||
| 389 | } |
||
| 390 | catch (Api\Db\Exception $e) { |
||
| 391 | unset($e); |
||
| 392 | // ignore db errors |
||
| 393 | } |
||
| 394 | $GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 2 (Needs Configuration)'; |
||
| 395 | if(!count($config)) |
||
| 396 | { |
||
| 397 | return 1; |
||
| 398 | } |
||
| 399 | $config_errors =& $GLOBALS['egw_info']['setup']['config_errors']; |
||
| 400 | $GLOBALS['egw_info']['setup']['config_errors'] = array(); |
||
| 401 | $error_msg = null; |
||
| 402 | if (!$this->check_dir($config['temp_dir'],$error_msg)) |
||
| 403 | { |
||
| 404 | $config_errors[] = lang("Your temporary directory '%1' %2",$config['temp_dir'],$error_msg); |
||
| 405 | } |
||
| 406 | |||
| 407 | if (!$this->check_dir($config['files_dir'],$error_msg,true)) |
||
| 408 | { |
||
| 409 | $config_errors[] = lang("Your files directory '%1' %2",$config['files_dir'],$error_msg); |
||
| 410 | } |
||
| 411 | // set and create the default backup_dir |
||
| 412 | if (@is_writeable($config['files_dir']) && empty($config['backup_dir'])) |
||
| 413 | { |
||
| 414 | $config['backup_dir'] = $config['files_dir'].'/db_backup'; |
||
| 415 | if (!is_dir($config['backup_dir']) && mkdir($config['backup_dir'])) |
||
| 416 | { |
||
| 417 | $GLOBALS['egw_setup']->db->insert($GLOBALS['egw_setup']->config_table,array( |
||
| 418 | 'config_value' => $config['backup_dir'], |
||
| 419 | ),array( |
||
| 420 | 'config_app' => 'phpgwapi', |
||
| 421 | 'config_name' => 'backup_dir', |
||
| 422 | ),__LINE__,__FILE__); |
||
| 423 | } |
||
| 424 | } |
||
| 425 | if (isset($config['backup_mincount'])) |
||
| 426 | { |
||
| 427 | $GLOBALS['egw_setup']->db->insert($GLOBALS['egw_setup']->config_table,array( |
||
| 428 | 'config_value' => $config['backup_mincount'], |
||
| 429 | ),array( |
||
| 430 | 'config_app' => 'phpgwapi', |
||
| 431 | 'config_name' => 'backup_mincount', |
||
| 432 | ),__LINE__,__FILE__); |
||
| 433 | } |
||
| 434 | if (isset($config['backup_files'])) |
||
| 435 | { |
||
| 436 | $GLOBALS['egw_setup']->db->insert($GLOBALS['egw_setup']->config_table,array( |
||
| 437 | 'config_value' => (int)$config['backup_files'], |
||
| 438 | ),array( |
||
| 439 | 'config_app' => 'phpgwapi', |
||
| 440 | 'config_name' => 'backup_files', |
||
| 441 | ),__LINE__,__FILE__); |
||
| 442 | } |
||
| 443 | if (!$this->check_dir($config['backup_dir'],$error_msg,true)) |
||
| 444 | { |
||
| 445 | $config_errors[] = lang("Your backup directory '%1' %2",$config['backup_dir'],$error_msg); |
||
| 446 | } |
||
| 447 | if ($config_errors) |
||
| 448 | { |
||
| 449 | return 2; |
||
| 450 | } |
||
| 451 | $GLOBALS['egw_info']['setup']['header_msg'] = 'Stage 2 (Configuration OK)'; |
||
| 452 | return 10; |
||
| 453 | } |
||
| 454 | |||
| 455 | /** |
||
| 456 | * Verify that all of an app's tables exist in the db |
||
| 457 | * |
||
| 458 | * @param $appname |
||
| 459 | * @param $any optional, set to True to see if any of the apps tables are installed |
||
| 460 | */ |
||
| 461 | function check_app_tables($appname,$any=False) |
||
| 531 | } |
||
| 532 | } |
||
| 533 | |||
| 534 | /** |
||
| 535 | * Checks if a directory exists, is writable by the webserver and optionaly is in the docroot |
||
| 536 | * |
||
| 537 | * @param string $dir path |
||
| 538 | * @param string &$msg error-msg: 'does not exist', 'is not writeable by the webserver' or 'is in the webservers docroot' (run through lang) |
||
| 539 | * @param boolean $check_in_docroot =false run an optional in docroot check |
||
| 540 | * @return boolean |
||
| 541 | */ |
||
| 542 | static function check_dir($dir,&$msg,$check_in_docroot=false) |
||
| 576 | } |
||
| 577 | } |
||
| 578 |
If you suppress an error, we recommend checking for the error condition explicitly: