Duplicate code is one of the most pungent code smells. A rule that is often used is to re-structure code once it is duplicated in three or more places.
Common duplication problems, and corresponding solutions are:
Complex classes like Batiment 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 Batiment, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 9 | class Batiment { |
||
| 10 | //pour quand on recup un batiment |
||
| 11 | private $nom_batiment; |
||
| 12 | private $nom_batiment_sql; |
||
| 13 | private $niveau_batiment; |
||
| 14 | private $temps_construction; |
||
| 15 | private $ressource_construire; |
||
| 16 | private $id_batiment; |
||
| 17 | |||
| 18 | private $info_batiment; |
||
| 19 | private $info_batiment_next; |
||
| 20 | |||
| 21 | //pour les constructions |
||
| 22 | private $nom_batiment_construction; |
||
| 23 | private $date_fin_construction; |
||
| 24 | private $niveau_batiment_construction; |
||
| 25 | |||
| 26 | //-------------------------- BUILDER ----------------------------------------------------------------------------// |
||
| 27 | public function __construct() { |
||
| 30 | //-------------------------- END BUILDER ----------------------------------------------------------------------------// |
||
| 31 | |||
| 32 | |||
| 33 | |||
| 34 | //-------------------------- GETTER ----------------------------------------------------------------------------// |
||
| 35 | public function getNomBatiment() { |
||
| 56 | |||
| 57 | public function getNomBatimentConstruction() { |
||
| 66 | |||
| 67 | /** |
||
| 68 | * @param $nom_batiment |
||
| 69 | * @return int |
||
| 70 | * pour recuperer le niveau d'un batiment |
||
| 71 | */ |
||
| 72 | public function getNiveauBatiment($nom_batiment_sql, $id_base = null) { |
||
| 99 | |||
| 100 | /** |
||
| 101 | * @param $ressource |
||
| 102 | * @return int |
||
| 103 | * recuperation de la production de chaque ressource en fonction du lvl des batiments |
||
| 104 | */ |
||
| 105 | public function getProduction($ressource, $id_base = null) { |
||
| 134 | |||
| 135 | /** |
||
| 136 | * @return int |
||
| 137 | * fonction qui retourne le stockage de l'entrepot |
||
| 138 | */ |
||
| 139 | public function getStockageEntrepot($id_base = null) { |
||
| 161 | |||
| 162 | /** |
||
| 163 | * permet de récupérer toutes les infos d'un batiment dans la popup |
||
| 164 | * @param $nom_batiment |
||
| 165 | */ |
||
| 166 | public function getUnBatiment($nom_batiment) { |
||
| 167 | $dbc = App::getDb(); |
||
| 168 | $dbc1 = Bataille::getDb(); |
||
| 169 | |||
| 170 | $construction = $this->getTestBatimentConstruction($nom_batiment); |
||
| 171 | |||
| 172 | //recuperation des infos du batiment |
||
| 173 | $query = $dbc->select() |
||
| 174 | ->from("_bataille_batiment") |
||
| 175 | ->where("nom_batiment", "=", $construction[0], "AND") |
||
| 176 | ->where("ID_base", "=", Bataille::getIdBase()) |
||
| 177 | ->get(); |
||
| 178 | |||
| 179 | if ((is_array($query)) && (count($query) > 0)) { |
||
| 180 | foreach ($query as $obj) { |
||
| 181 | $this->nom_batiment_sql = $obj->nom_batiment_sql; |
||
| 182 | $this->niveau_batiment = $obj->niveau; |
||
| 183 | $this->id_batiment = $obj->ID_batiment; |
||
| 184 | } |
||
| 185 | |||
| 186 | if (($construction[1] == true) && ($this->niveau_batiment > 1)) { |
||
| 187 | $this->niveau_batiment = $this->niveau_batiment + 1; |
||
| 188 | } |
||
| 189 | |||
| 190 | $max_level = $this->getInfoUpgradeBatiment(); |
||
| 191 | } |
||
| 192 | else { |
||
| 193 | $query = $dbc1->select("nom_table") |
||
| 194 | ->from("liste_batiment") |
||
| 195 | ->where("nom", "=", $nom_batiment) |
||
| 196 | ->get(); |
||
| 197 | |||
| 198 | if ((is_array($query)) && (count($query) > 0)) { |
||
| 199 | foreach ($query as $obj) { |
||
| 200 | $this->nom_batiment_sql = $obj->nom_table; |
||
| 201 | } |
||
| 202 | } |
||
| 203 | |||
| 204 | $this->niveau_batiment = 0; |
||
| 205 | $this->getInfoUpgradeBatiment(); |
||
| 206 | $max_level = 0; |
||
| 207 | } |
||
| 208 | |||
| 209 | //permet de savoir si le batiment produit bien des ressoures |
||
| 210 | $batiment_production = []; |
||
| 211 | |||
| 212 | $query = $dbc1->select("nom")->from("liste_batiment")->where("type", "=", "ressource")->get(); |
||
| 213 | |||
| 214 | if ((is_array($query)) && (count($query) > 0)) { |
||
| 215 | foreach ($query as $obj) { |
||
| 216 | $batiment_production[] = $obj->nom; |
||
| 217 | } |
||
| 218 | } |
||
| 219 | |||
| 220 | Bataille::setValues([ |
||
| 221 | "nom_batiment_sql" => $this->nom_batiment_sql, |
||
| 222 | "niveau_batiment" => $this->niveau_batiment, |
||
| 223 | "id_batiment" => $this->niveau_batiment, |
||
| 224 | "max_level" => $max_level, |
||
| 225 | "batiment_production" => $batiment_production |
||
| 226 | ]); |
||
| 227 | |||
| 228 | return $max_level; |
||
| 229 | } |
||
| 230 | |||
| 231 | /** |
||
| 232 | * pour récupérer la construction en cours dans la base |
||
| 233 | */ |
||
| 234 | public function getConstruction() { |
||
| 270 | |||
| 271 | /** |
||
| 272 | * pour récupérer la liste des batiments qu'il est possible de construire |
||
| 273 | */ |
||
| 274 | public function getBatimentAConstruire() { |
||
| 397 | |||
| 398 | /** |
||
| 399 | * @param $case_depart |
||
| 400 | * @param $nom_batiment |
||
| 401 | * @param $nom_batiment_sql |
||
| 402 | * @return bool |
||
| 403 | * fonction qui test si un il y a la place de construire un batiment en fonction de sa case ou il a été laché en x et y |
||
| 404 | * et en fonction de sa taille et du positionnement des autres batiments |
||
| 405 | */ |
||
| 406 | public function getEmplacementConstructionLibre($case_depart, $nom_batiment, $nom_batiment_sql) { |
||
| 459 | |||
| 460 | /** |
||
| 461 | * @param $nom_batiment_sql |
||
| 462 | * @return array |
||
| 463 | * fonction qui renvoi un tableau contenant la taille et hauteur d'un batiment en |
||
| 464 | * fonction de son nom |
||
| 465 | */ |
||
| 466 | View Code Duplication | public function getTailleBatiment($nom_batiment_sql) { |
|
| 481 | |||
| 482 | /** |
||
| 483 | * @param $nom_batiment_sql |
||
| 484 | * @param $niveau |
||
| 485 | * @return array |
||
| 486 | * recuperation des ressources nécéssaire pour construire le batiment |
||
| 487 | */ |
||
| 488 | private function getRessourceConstruireBatiment($nom_batiment_sql, $niveau) { |
||
| 514 | |||
| 515 | /** |
||
| 516 | * fonction qui renvoi un tableau avec le nom du batiment sans (en construction) |
||
| 517 | * + true pour dire que le batiment est en construction |
||
| 518 | * |
||
| 519 | * @param $nom_batiment |
||
| 520 | * @return array |
||
| 521 | */ |
||
| 522 | private function getTestBatimentConstruction($nom_batiment) { |
||
| 529 | |||
| 530 | /** |
||
| 531 | * fonction qui renvoi les informations pour augmenter le niveau d'un batiment |
||
| 532 | * @return int |
||
| 533 | */ |
||
| 534 | private function getInfoUpgradeBatiment() { |
||
| 595 | //-------------------------- END GETTER ----------------------------------------------------------------------------// |
||
| 596 | |||
| 597 | |||
| 598 | |||
| 599 | //-------------------------- SETTER ----------------------------------------------------------------------------// |
||
| 600 | /** |
||
| 601 | * fonction qui initialise la construction d'un batiment |
||
| 602 | * @param $nom_batiment |
||
| 603 | * @param $nom_batiment_sql |
||
| 604 | */ |
||
| 605 | public function setCommencerConstruireBatiment($nom_batiment, $nom_batiment_sql, $posx, $posy) { |
||
| 606 | $dbc = App::getDb(); |
||
| 607 | $dbc1 = Bataille::getDb(); |
||
| 608 | |||
| 609 | if ($this->getConstruction() == 0) { |
||
| 610 | $un_batiment = $this->getUnBatiment($nom_batiment); |
||
| 611 | |||
| 612 | //on test si assez de ressrouce pour construire le batiment |
||
| 613 | if ($un_batiment == 0) { |
||
| 614 | $ressource = $this->getRessourceConstruireBatiment($nom_batiment_sql, 0); |
||
| 615 | $this->nom_batiment_sql = $nom_batiment_sql; |
||
| 616 | $this->niveau_batiment = 0; |
||
| 617 | } |
||
| 618 | else { |
||
| 619 | $ressource = $this->getRessourceConstruireBatiment($this->nom_batiment_sql, $this->niveau_batiment); |
||
| 620 | } |
||
| 621 | |||
| 622 | //si pas assez de ressource |
||
| 623 | if (($ressource["eau"]["class"] || $ressource["electricite"]["class"] ||$ressource["fer"]["class"] ||$ressource["fuel"]["class"]) == "rouge") { |
||
| 624 | FlashMessage::setFlash("Pas assez de ressources pour construire ce batiment"); |
||
| 625 | return false; |
||
| 626 | } |
||
| 627 | else { |
||
| 628 | //recuperation du temps de construction |
||
| 629 | $query = $dbc1->select("ressource_construire") |
||
| 630 | ->select("temps_construction") |
||
| 631 | ->from($this->nom_batiment_sql) |
||
| 632 | ->where("ID_".$this->nom_batiment_sql, "=", $this->niveau_batiment+1) |
||
| 633 | ->get(); |
||
| 634 | |||
| 635 | foreach ($query as $obj) { |
||
| 636 | $temps_construction = round($obj->temps_construction-($obj->temps_construction*Bataille::getBatiment()->getNiveauBatiment("centre_commandement")/100)); |
||
| 637 | $ressource_construction = explode(", ", $obj->ressource_construire); |
||
| 638 | } |
||
| 639 | |||
| 640 | //on insere la construction dans la table batiment si new batiment |
||
| 641 | if ($un_batiment == 0) { |
||
| 642 | $dbc->insert("niveau", $this->niveau_batiment+1) |
||
| 643 | ->insert("nom_batiment", $nom_batiment) |
||
| 644 | ->insert("nom_batiment_sql", $this->nom_batiment_sql) |
||
| 645 | ->insert("posx", intval($posx)) |
||
| 646 | ->insert("posy", intval($posy)) |
||
| 647 | ->insert("construction", 1) |
||
| 648 | ->insert("ID_base", Bataille::getIdBase()) |
||
| 649 | ->into("_bataille_batiment") |
||
| 650 | ->set(); |
||
| 651 | |||
| 652 | $this->id_batiment = $dbc->lastInsertId(); |
||
| 653 | } |
||
| 654 | else { |
||
| 655 | $dbc->update("niveau", $this->niveau_batiment+1) |
||
| 656 | ->update("construction", 1) |
||
| 657 | ->from("_bataille_batiment") |
||
| 658 | ->where("ID_batiment", "=", $this->id_batiment, "AND") |
||
| 659 | ->where("ID_base", "=", Bataille::getIdBase()) |
||
| 660 | ->set(); |
||
| 661 | } |
||
| 662 | |||
| 663 | |||
| 664 | //on initialise la construction |
||
| 665 | //recuperation de la date en seconde |
||
| 666 | $today = Bataille::getToday(); |
||
| 667 | |||
| 668 | //date de la fin de la construction en seconde |
||
| 669 | $fin_construction = $today+$temps_construction; |
||
| 670 | |||
| 671 | $dbc->insert("date_fin", $fin_construction) |
||
| 672 | ->insert("ID_base", Bataille::getIdBase()) |
||
| 673 | ->insert("ID_batiment", $this->id_batiment) |
||
| 674 | ->into("_bataille_construction") |
||
| 675 | ->set(); |
||
| 676 | |||
| 677 | //on retire les ressources de la base |
||
| 678 | Bataille::getRessource()->setUpdateRessource($ressource_construction[2], $ressource_construction[3], $ressource_construction[0], $ressource_construction[1], 0, "-"); |
||
| 679 | } |
||
| 680 | } |
||
| 681 | else { |
||
| 682 | FlashMessage::setFlash("Un batiment est déjà en construction, vous ne pouvez pas en construire un autre !"); |
||
| 683 | return false; |
||
| 684 | } |
||
| 685 | } |
||
| 686 | |||
| 687 | /** |
||
| 688 | * fonction qui termine la construction d'un batiment |
||
| 689 | * @param $id_batiment |
||
| 690 | */ |
||
| 691 | private function setTerminerConstruction($id_batiment) { |
||
| 711 | //-------------------------- END SETTER ----------------------------------------------------------------------------// |
||
| 712 | } |
If you define a variable conditionally, it can happen that it is not defined for all execution paths.
Let’s take a look at an example:
In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.
Available Fixes
Check for existence of the variable explicitly:
Define a default value for the variable:
Add a value for the missing path: