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 OledrionOledrion_commandsHandler 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 OledrionOledrion_commandsHandler, and based on these observations, apply Extract Interface, too.
| 1 | <?php |
||
| 120 | class OledrionOledrion_commandsHandler extends Oledrion_XoopsPersistableObjectHandler |
||
| 121 | { |
||
| 122 | /** |
||
| 123 | * OledrionOledrion_commandsHandler constructor. |
||
| 124 | * @param XoopsDatabase|null $db |
||
| 125 | */ |
||
| 126 | public function __construct(XoopsDatabase $db) |
||
| 130 | |||
| 131 | /** |
||
| 132 | * Indique si c'est la première commande d'un client |
||
| 133 | * |
||
| 134 | * @param integer $uid Identifiant de l'utilisateur |
||
| 135 | * @return boolean Indique si c'est le cas ou pas |
||
| 136 | */ |
||
| 137 | public function isFirstCommand($uid = 0) |
||
| 149 | |||
| 150 | /** |
||
| 151 | * Indique si un produit a déajà été acheté par un utilisateur |
||
| 152 | * |
||
| 153 | * @param integer $uid Identifiant de l'utilisateur |
||
| 154 | * @param integer $productId Identifiant du produit |
||
| 155 | * @return boolean Indique si c'est le cas ou pas |
||
| 156 | */ |
||
| 157 | public function productAlreadyBought($uid = 0, $productId = 0) |
||
| 158 | { |
||
| 159 | if ($uid == 0) { |
||
| 160 | $uid = OledrionUtility::getCurrentUserID(); |
||
| 161 | } |
||
| 162 | $sql = 'SELECT Count(*) AS cpt FROM ' . $this->db->prefix('oledrion_caddy') . ' c, ' . $this->db->prefix('oledrion_commands') . ' f WHERE c.caddy_product_id = ' . (int)$productId . ' AND c.caddy_cmd_id = f.cmd_id AND f.cmd_uid = ' . (int)$uid; |
||
| 163 | $result = $this->db->query($sql); |
||
| 164 | if (!$result) { |
||
| 165 | return 0; |
||
| 166 | } |
||
| 167 | list($count) = $this->db->fetchRow($result); |
||
| 168 | if ($count > 0) { |
||
| 169 | return true; |
||
| 170 | } else { |
||
| 171 | return false; |
||
| 172 | } |
||
| 173 | } |
||
| 174 | |||
| 175 | /** |
||
| 176 | * Mise à jour des stocks pour chaque produit composant la commande |
||
| 177 | * |
||
| 178 | * @param object $order La commande à traiter |
||
| 179 | * @return void |
||
| 180 | */ |
||
| 181 | public function updateStocks($order) |
||
| 182 | { |
||
| 183 | global $h_oledrion_caddy, $h_oledrion_products, $h_oledrion_persistent_cart; |
||
| 184 | $orderId = $order->getVar('cmd_id'); |
||
| 185 | // Recherche de tous les produits du caddy |
||
| 186 | $caddy = $h_oledrion_caddy->getCaddyFromCommand($orderId); |
||
| 187 | $tblTmp = $tblProducts = array(); |
||
| 188 | foreach ($caddy as $item) { |
||
| 189 | $tblTmp[] = $item->getVar('caddy_product_id'); |
||
| 190 | } |
||
| 191 | // Chargement de tous les produits |
||
| 192 | $critere = new Criteria('product_id', '(' . implode(',', $tblTmp) . ')', 'IN'); |
||
| 193 | $tblProducts = $h_oledrion_products->getObjects($critere, true); |
||
| 194 | // Boucle sur le caddy pour mettre à jour les quantités |
||
| 195 | foreach ($caddy as $item) { |
||
| 196 | if (isset($tblProducts[$item->getVar('caddy_product_id')])) { |
||
| 197 | $product = $tblProducts[$item->getVar('caddy_product_id')]; |
||
| 198 | $h_oledrion_products->decreaseStock($product, $item->getVar('caddy_qte')); |
||
| 199 | $h_oledrion_products->verifyLowStock($product); // Vérification du stock d'alerte |
||
| 200 | $h_oledrion_persistent_cart->deleteUserProduct($item->getVar('caddy_product_id'), $order->getVar('cmd_uid')); |
||
| 201 | } |
||
| 202 | } |
||
| 203 | |||
| 204 | return true; |
||
| 205 | } |
||
| 206 | |||
| 207 | /** |
||
| 208 | * Retourne la liste des URLs de téléchargement liés à une commande |
||
| 209 | * |
||
| 210 | * @param object|Oledrion_commands $order La commande en question |
||
| 211 | * @return array Les URL |
||
| 212 | */ |
||
| 213 | public function getOrderUrls(Oledrion_commands $order) |
||
| 214 | { |
||
| 215 | global $h_oledrion_caddy, $h_oledrion_products; |
||
| 216 | $retval = array(); |
||
| 217 | // Recherche des produits du caddy associés à cette commande |
||
| 218 | $carts = $productsList = $products = array(); |
||
| 219 | $carts = $h_oledrion_caddy->getObjects(new Criteria('caddy_cmd_id', $order->getVar('cmd_id'), '=')); |
||
| 220 | foreach ($carts as $item) { |
||
| 221 | $productsList[] = $item->getVar('caddy_product_id'); |
||
| 222 | } |
||
| 223 | if (count($productsList) > 0) { |
||
| 224 | $products = $h_oledrion_products->getObjects(new Criteria('product_id', '(' . implode(',', $productsList) . ')', 'IN'), true); |
||
| 225 | if (count($products) > 0) { |
||
| 226 | foreach ($carts as $item) { |
||
| 227 | $produit = null; |
||
| 228 | if (isset($products[$item->getVar('caddy_product_id')])) { |
||
| 229 | $produit = $products[$item->getVar('caddy_product_id')]; |
||
| 230 | if (xoops_trim($produit->getVar('product_download_url')) != '') { |
||
| 231 | $retval[] = OLEDRION_URL . 'download.php?download_id=' . $item->getVar('caddy_pass'); |
||
| 232 | } |
||
| 233 | } |
||
| 234 | } |
||
| 235 | } |
||
| 236 | } |
||
| 237 | |||
| 238 | return $retval; |
||
| 239 | } |
||
| 240 | |||
| 241 | /** |
||
| 242 | * Envoi du mail chargé de prévenir le client et le magasin qu'une commande est validée |
||
| 243 | * |
||
| 244 | * @param object|Oledrion_commands $order La commande en question |
||
| 245 | * @param string $comment Optionel, un commentaire pour le webmaster |
||
| 246 | */ |
||
| 247 | public function notifyOrderValidated(Oledrion_commands $order, $comment = '') |
||
| 248 | { |
||
| 249 | global $xoopsConfig; |
||
| 250 | $msg = array(); |
||
| 251 | $Urls = array(); |
||
| 252 | $Urls = $this->getOrderUrls($order); // On récupère les URL des fichiers à télécharger |
||
| 253 | $msg['ADDITIONAL_CONTENT'] = ''; |
||
| 254 | $msg['NUM_COMMANDE'] = $order->getVar('cmd_id'); |
||
| 255 | $msg['COMMENT'] = $comment; |
||
| 256 | if (count($Urls) > 0) { |
||
| 257 | $msg['ADDITIONAL_CONTENT'] = _OLEDRION_YOU_CAN_DOWNLOAD . "\n" . implode("\n", $Urls); |
||
| 258 | } |
||
| 259 | OledrionUtility::sendEmailFromTpl('command_shop_verified.tpl', OledrionUtility::getEmailsFromGroup(OledrionUtility::getModuleOption('grp_sold')), _OLEDRION_GATEWAY_VALIDATED, $msg); |
||
| 260 | OledrionUtility::sendEmailFromTpl('command_client_verified.tpl', $order->getVar('cmd_email'), sprintf(_OLEDRION_GATEWAY_VALIDATED, $xoopsConfig['sitename']), $msg); |
||
| 261 | } |
||
| 262 | |||
| 263 | /** |
||
| 264 | * Validation d'une commande et mise à jour des stocks |
||
| 265 | * |
||
| 266 | * @param object|Oledrion_commands $order La commande à traiter |
||
| 267 | * @param string $comment Optionel, un commentaire pour le mail envoyé au webmaster |
||
| 268 | * @return bool Indique si la validation de la commande s'est bien faite ou pas |
||
| 269 | */ |
||
| 270 | public function validateOrder(Oledrion_commands $order, $comment = '') |
||
| 271 | { |
||
| 272 | $retval = false; |
||
| 273 | $order->setVar('cmd_state', OLEDRION_STATE_VALIDATED); |
||
| 274 | $order->setVar('cmd_comment', $comment); |
||
| 275 | $retval = $this->insert($order, true); |
||
| 276 | if ($retval) { |
||
| 277 | $this->updateStocks($order); |
||
| 278 | // B.R. Validation emails redundant since order emails now sent @gateway (paypal) validation |
||
| 279 | // B.R. $this->notifyOrderValidated($order, $comment); |
||
| 280 | } |
||
| 281 | |||
| 282 | return $retval; |
||
| 283 | } |
||
| 284 | |||
| 285 | /** |
||
| 286 | * pack d'une commande et mise à jour des stocks |
||
| 287 | * |
||
| 288 | * @param object|Oledrion_commands $order La commande à traiter |
||
| 289 | * @param string $comment Optionel, un commentaire pour le mail envoyé au webmaster |
||
| 290 | * @return bool Indique si la validation de la commande s'est bien faite ou pas |
||
| 291 | */ |
||
| 292 | View Code Duplication | public function packOrder(Oledrion_commands $order, $comment = '') |
|
| 301 | |||
| 302 | /** |
||
| 303 | * submit d'une commande et mise à jour des stocks |
||
| 304 | * |
||
| 305 | * @param object|Oledrion_commands $order La commande à traiter |
||
| 306 | * @param string $comment Optionel, un commentaire pour le mail envoyé au webmaster |
||
| 307 | * @return bool Indique si la validation de la commande s'est bien faite ou pas |
||
| 308 | */ |
||
| 309 | View Code Duplication | public function submitOrder(Oledrion_commands $order, $comment = '') |
|
| 318 | |||
| 319 | /** |
||
| 320 | * delivery d'une commande et mise à jour des stocks |
||
| 321 | * |
||
| 322 | * @param object|Oledrion_commands $order La commande à traiter |
||
| 323 | * @param string $comment Optionel, un commentaire pour le mail envoyé au webmaster |
||
| 324 | * @return bool Indique si la validation de la commande s'est bien faite ou pas |
||
| 325 | */ |
||
| 326 | View Code Duplication | public function deliveryOrder(Oledrion_commands $order, $comment = '') |
|
| 335 | |||
| 336 | /** |
||
| 337 | * Informe le propriétaire du site qu'une commande est frauduleuse |
||
| 338 | * |
||
| 339 | * @param object|Oledrion_commands $order La commande en question |
||
| 340 | * @param string $comment Optionel, un commentaire pour le mail envoyé au webmaster |
||
| 341 | */ |
||
| 342 | View Code Duplication | public function notifyOrderFraudulent(Oledrion_commands $order, $comment = '') |
|
| 349 | |||
| 350 | /** |
||
| 351 | * Applique le statut de commande frauduleuse à une commande |
||
| 352 | * |
||
| 353 | * @param obejct|Oledrion_commands $order La commande à traiter |
||
| 354 | * @param string $comment Optionel, un commentaire pour le mail envoyé au webmaster |
||
| 355 | */ |
||
| 356 | public function setFraudulentOrder(Oledrion_commands $order, $comment = '') |
||
| 363 | |||
| 364 | /** |
||
| 365 | * Informe le propriétaire du site qu'une commande est en attente |
||
| 366 | * |
||
| 367 | * @param object|Oledrion_commands $order La commande en question |
||
| 368 | * @param string $comment Optionel, un commentaire pour le mail envoyé au webmaster |
||
| 369 | */ |
||
| 370 | View Code Duplication | public function notifyOrderPending(Oledrion_commands $order, $comment = '') |
|
| 377 | |||
| 378 | /** |
||
| 379 | * Applique le statut de commande en attente à une commande |
||
| 380 | * |
||
| 381 | * @param object|Oledrion_commands $order La commande à traiter |
||
| 382 | * @param string $comment Optionel, un commentaire pour le mail envoyé au webmaster |
||
| 383 | */ |
||
| 384 | public function setOrderPending(Oledrion_commands $order, $comment = '') |
||
| 391 | |||
| 392 | /** |
||
| 393 | * Informe le propriétaire du site qu'une commande à échoué (le paiement) |
||
| 394 | * |
||
| 395 | * @param object|Oledrion_commands $order La commande en question |
||
| 396 | * @param string $comment Optionel, un commentaire pour le mail envoyé au webmaster |
||
| 397 | */ |
||
| 398 | View Code Duplication | public function notifyOrderFailed(Oledrion_commands $order, $comment = '') |
|
| 405 | |||
| 406 | /** |
||
| 407 | * Applique le statut de commande échouée à une commande |
||
| 408 | * |
||
| 409 | * @param object|Oledrion_commands $order La commande à traiter |
||
| 410 | * @param string $comment Optionel, un commentaire pour le mail envoyé au webmaster |
||
| 411 | */ |
||
| 412 | public function setOrderFailed(Oledrion_commands $order, $comment = '') |
||
| 419 | |||
| 420 | /** |
||
| 421 | * Informe le propriétaire du site qu'une commande à échoué (le paiement) |
||
| 422 | * |
||
| 423 | * @param object|Oledrion_commands $order La commande en question |
||
| 424 | * @param string $comment Optionel, un commentaire pour le mail envoyé au webmaster |
||
| 425 | */ |
||
| 426 | public function notifyOrderCanceled(Oledrion_commands $order, $comment = '') |
||
| 434 | |||
| 435 | /** |
||
| 436 | * Applique le statut de commande annulée à une commande |
||
| 437 | * |
||
| 438 | * @param object|Oledrion_commands $order La commande à traiter |
||
| 439 | * @param string $comment Optionel, un commentaire pour le mail envoyé au webmaster |
||
| 440 | */ |
||
| 441 | public function setOrderCanceled(Oledrion_commands $order, $comment = '') |
||
| 448 | |||
| 449 | /** |
||
| 450 | * Retourne une commande à partir de son mot de passe d'annulation |
||
| 451 | * |
||
| 452 | * @param string $cmd_cancel Le mot de passe d'annulation |
||
| 453 | * @return mixed Soit un objet soit null |
||
| 454 | */ |
||
| 455 | public function getOrderFromCancelPassword($cmd_cancel) |
||
| 468 | |||
| 469 | /** |
||
| 470 | * Retourne la dernière commande d'un utilisateur (si elle existe) |
||
| 471 | * |
||
| 472 | * @param integer $uid Identifiant de la commande |
||
| 473 | * @return null |
||
| 474 | */ |
||
| 475 | public function getLastUserOrder($uid) |
||
| 492 | |||
| 493 | /** |
||
| 494 | * Supprime une commande et tout ce qui s'y rattache |
||
| 495 | * |
||
| 496 | * @param oledrion_commands $order |
||
| 497 | * @return boolean |
||
| 498 | */ |
||
| 499 | public function removeOrder(Oledrion_commands $order) |
||
| 512 | } |
||
| 513 |
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.