DevNet Posted December 2, 2011 Share Posted December 2, 2011 Bonjour, Je mets à disposition un blog de ressources dans le développement web. Une grosse partie des ressources traitera du développement autour de PrestaShop. Si vous êtes développeurs et intéressés, n'hésitez pas à venir prendre connaissance des nouveaux articles. http://blog.dev-net.fr Edit : effacement de l'article du blog traité ci-après. Bonne lecture Link to comment Share on other sites More sharing options...
Sbizz Posted December 2, 2011 Share Posted December 2, 2011 Bonjour. J'ai du mal à comprendre vos articles. Et si dans votre code vous avez opté pour l’usage de MaClasse::MaMethode() , votre traitement (pour cette partie) ne fonctionnera plus avec vos décisions algorithmiques, mais avec celles du développeur qui a créé l’override de la méthode. J'ai peut être mal compris, mais j'ai un léger doute sur vos dires. Vous prenez déjà un mauvais départ en disant que : En d’autres termes et pour exemple, la nouvelle classe /override/classes/Language.php sera un remplacement de la classe disponible dans la « core » ou plutôt le noyau, pour les méthodes qu’elle déclare. Ce n'est pas un remplacement, c'est une surcharge. C'est le terme qu'on utilise et c'est très très différent. C'est d'ailleurs ce qui rend, je pense, votre article un peu obsolète (y'a rien à prendre mal, je vous donne mon avis). Qu'entendez-vous par "décisions algorithmiques" ? Le but de la surcharge n'est pas d'annulé les effets de la méthode mère, mais d'ajouter des fonctionnalités. En d'autre terme, si vous avez la classe MaClasseCore::MaMethodeA() qui fait un simple echo "A"; et qui est surchargée par MaClasse::MaMethodeA() qui ajoute un echo "B";, vous aurez au final echo "A";echo "B";. Lorsque vous surchargez une classe, vous devez "obligatoirement" faire appelle à la méthode parente. Sinon ce n'est plus de l'override, car le but de l'override est bien et bel de rajouter des fonctionnalités SANS rendre obsolète les autres fichiers qui utiliseraient la classe. class MaClasseCore { public function MaMethodeA() { echo "A"; } } class MaClasse extends MaClasseCore { public function MaMethodeA() { parent::MaMethodeA(); echo "B"; } } Of course, l'appel de la fonction parente peut se faire à n'importe quel endroit. Il faut bien entendu faire attention aux données qu'on voudrait récupérer ou pas. Si vous souhaitez garder un maximum d’indépendance et minimiser les interférences avec les éventuelles personnalisations de l’utilisateur final sur sa boutique, préférez l’usage des classes depuis le « core » de PrestaShop, en instanciant vos objets par MaClasseCore directement. Vous remarquerez que Prestashop n'utilise pas MaClasseCore mais MaClasse. Si un développeur surcharge MaClasseCore, alors tout le système de Prestashop sera touché. Donc il n'y a rien de dangereux et aucunes interférences si le développeur a pris soin de bien surcharger la classe. Comment faire cohabiter plusieurs overrides de provenance différente dans une boutique PrestaShop, quand leur mise en place doit se faire de façon automatique (telle que l’installation de module par exemple) ? Lorsque vous surchargez une classe, vous devez prendre en compte que quelqu'un d'autre peut venir surcharger en même temps la classe. C'est d'ailleurs très problématique. Par exemple, mon module surcharge la classe Validate.php pour rajouter des méthodes (aucune surcharge de méthode). Lors de l'installation du module, je copie le fichier si et seulement si aucun fichier Validate.php n'est présent dans l'override. Je dois donc demander à l'utilisateur de modifier le fichier déjà présent pour ajouter mes fonctionnalités. Plus ennuyant encore : si j'avais surchargé une méthode déjà existante et que le fichier déjà présent aurait fait la même chose, cela deviendrait plus compliqué. C'est un problème qui peut vite arriver. Maintenant, quelqu'un qui surcharge bien les méthodes ne modifiera pas le fonctionne de Prestashop ou des autres modules : par exemple, mettre une condition ("je me trouve sur cette page", "cette variable existe", "cette action est demandée", etc.). Pour rajouter un poids à mes arguments, voyez le fichier MySQL.php qui est surchargé par Prestashop lui-même (c'est un fichier exemple). Dans votre article, vous incitez les développeurs à utiliser MySQLCore. Problème : si ils font ça, la surcharge de la classe MySQL sera faussée et la variabe $count, par exemple, n'indiquera pas le nombre réelle de requêtes faites. Sinon, pour parler de la rédaction en elle-même : vous allez un peu trop vite, soyez plus clair. Je touche énormément à Prestashop et j'ai eu du mal à comprendre votre article. Alors pour quelqu'un qui veut apprendre, cela lui risque d'être difficile. Mon message n'est pas à prendre méchamment, mais je donne simplement mon avis : vous le prenez ou pas. Edit: concernant votre deuxième article, Prestashop est loin d'être victorieux sur la sécurité. Les fonctions mysql_ devraient vite partir et j'espère qu'ils vont se mettre à PDO, car c'est tellement plus simple et tellement plus sécurisé... Link to comment Share on other sites More sharing options...
Captain FLAM Posted December 2, 2011 Share Posted December 2, 2011 Bonne réponse. concernant votre deuxième article, Prestashop est loin d'être victorieux sur la sécurité. Les fonctions mysql_ devraient vite partir et j'espère qu'ils vont se mettre à PDO, car c'est tellement plus simple et tellement plus sécurisé... Avez-vous un lien vers un article comparatif ? et quid de "pSQL" ? Link to comment Share on other sites More sharing options...
Sbizz Posted December 2, 2011 Share Posted December 2, 2011 http://blog.secaserv...sqli-pdo-mysql/ En anglais. Par contre, j'arrive plus à trouver l'article qui disait que les fonctions mysql_ et mysqli_ tendaient à disparaitre, dans le sens où elles seront moins utilisées pour laisser place à PDO qui prend en charge nativement différentes base de données. Vu que j'arrive pas à retrouver l'article, je veux pas dire que je suis sûr de ce que j'avance. pSQL() est l'ancienne manière de protéger ses variables. PDO le fait tout seul (à l'aide de bindValue()). Mais dans Prestashop, il faut absolument l'utiliser. Pour l'instant. J'espère que ça changera. Edit: par contre, je pense pas dire de conneries en disant que PHP 6 privilégiera PDO. Link to comment Share on other sites More sharing options...
DevNet Posted December 2, 2011 Author Share Posted December 2, 2011 @Sbizz : Merci pour vos précisions, mais avez-vous bien lu mon article en entier et ses intentions ? Ce que vous annoncez ne peut pas contredire ce que j'écris dans l'article puisque vous parlez d'une extension de classe avec re-déclaration de la méthode parente et non d'un override pur et dur. En gros dans ce que vous annoncez, vous utilisez les possibilités de l'override pour utiliser une nouvelle classe qui va non pas prendre prendre la place, mais en faire une extension ("extend"). Si vous relisez mon article, et même si moi aussi je suis un adepte des extensions de classes, ce que j'annonce est la création pure et simple d'une classe extend qui va utiliser la technique de remplacement telle que PrestaShop le propose dans son autoload(). Override = outrepasser Extend = étendre Et encore une fois, ceci n'est même pas l'objet de mon article ! Donc je vous invite à relire cet article, et vous vous apercevrez par vous-même que ce que vous ajoutez ici sur le forum ne correspond pas à l’intention de l'article. Même si je pourrai aussi de mon côté créer un article expliquant le fonction des classes extends. C'est dommage que vous ayez répondu aussi vite, vos réponses vont induire le lecteur en erreur sur le sujet même de cet article. Pour ce qui est de mon ouverture interrogative de fin : Vous ne pouvez pas faire des citations de bout de phrases en les sortant du texte d’origine. Encore une fois, vous faites lire votre réponse à des lecteurs qui ne vont pas forcément lire l'article en entier, et voir vos bouts de citation avec vos commentaires me font sortir de mes gonds. Voici l'entière citation logique : En conclusion Si vous souhaitez garder un maximum d’indépendance et minimiser les interférences avec les éventuelles personnalisations de l’utilisateur final sur sa boutique, préférez l’usage des classes depuis le « core » de PrestaShop, en instanciant vos objets par MaClasseCore directement. Dans le cas contraire, si l’override est de votre confection, il est par déduction normal que vous utilisiez votre nouvelle méthode de classe par MaClasse::MaMethode(). Et cela amène une nouvelle question : Comment faire cohabiter plusieurs overrides de provenance différente dans une boutique PrestaShop, quand leur mise en place doit se faire de façon automatique (telle que l’installation de module par exemple) ? Bien cordialement 1 Link to comment Share on other sites More sharing options...
DevNet Posted December 2, 2011 Author Share Posted December 2, 2011 class MaClasseCore { public function MaMethodeA() { echo "A"; } } class MaClasse extends MaClasseCore { public function MaMethodeA() { parent::MaMethodeA(); echo "B"; } } Est-ce le cas dans mon article ? Je n'ai jamais déclaré de parent::MaMethodeA(); D'où cette citation de mon article que vous-même avez proposé : En d’autres termes et pour exemple, la nouvelle classe /override/classes/Language.php sera un remplacement de la classe disponible dans la « core » ou plutôt le noyau, pour les méthodes qu’elle déclare. Pour information aux lecteurs, l'ajout de Sbizz est la déclaration la parent::[méthode], permet d'effectuer le traitement de la méthode parente (celle de la classe en extension), si celle-ci n'est pas présente, la méthode de la classe en cours va tout simple remplacer et "outrepasser" celle de la classe parente. Bien cordialement Link to comment Share on other sites More sharing options...
Sbizz Posted December 2, 2011 Share Posted December 2, 2011 Ce que vous annoncez ne peut pas contredire ce que j'écris dans l'article puisque vous parlez d'une extension de classe avec re-déclaration de la méthode parente et non d'un override pur et dur. Alors vous ne comprenez pas le mot "override". En tout cas, la façon dont Prestashop souhaite qu'il soit utilisé. En gros dans ce que vous annoncé, vous utilisez les possibilités de l'override pour utiliser une nouvelle classe qui va non pas prendre prendre la place, mais en faire une extension ("extend"). [...] Override = outrepasser Extend = étendre Pardon ? Savez-vous que le mot-clé extends est justement présent pour faire de l'overriding ? Il faut arrêter de traduire l'anglais mot pour mot. Override = surcharge (concept donc du extends). Citation de PHP.net pour une fonction d'overriding : override_function() surcharge les fonctions intégrées http://php.net/manua...de-function.php Vous incitez les développeurs à utiliser MaClasseCore pour ne pas subir les modifications apportées, éventuelles, de d'autres add-on. Or, je vous ai sorti un exemple concret qui déconseille cette utilisation : Pour rajouter un poids à mes arguments, voyez le fichier MySQL.php qui est surchargé par Prestashop lui-même (c'est un fichier exemple). Dans votre article, vous incitez les développeurs à utiliser MySQLCore. Problème : si ils font ça, la surcharge de la classe MySQL sera faussée et la variabe $count, par exemple, n'indiquera pas le nombre réelle de requêtes faites. Si le client ayant installé des add-on a souhaité faire des modifications générales, les modules des développeurs ne vont pas prendre en compte ces modifications si ils utilisent MaClasseCore. la méthode de la classe en cours va tout simple remplacer et "outrepasser" celle de la classe parente. Elle outre passe rien du tout. Elle surcharge. C'est le but de extends. Ce qui va faire que vous reprenez ou non les fonctionalités de la fonction parente c'est parent::method, mais dans TOUS les cas, c'est de l'overriding. vous faites lire votre réponse à des lecteurs qui ne vont pas forcément lire l'article en entier Alors ce ne sont pas de bons lecteurs et/ou des lecteurs qui ne sont pas intéressés. Link to comment Share on other sites More sharing options...
Captain FLAM Posted December 2, 2011 Share Posted December 2, 2011 http://blog.secaserv...sqli-pdo-mysql/ Merci pour le lien, et comme il est dit (2 fois) dans cet article : So, when writing an application that is 100% guaranteed to always use MySQL, using mysql or mysqli extension will work better than PDO. But when we need the flexibility of a database abstraction layer, PDO will make your code much more solid and portable. PDO offer great security than other without much hassle, but for transition i would suggest you to move to mysqli since it faster, easier than PDO, and most api/syntax are quite same with the old mysql extension. Sincèrement, je ne pense pas que le choix de la Team Presta de ne pas basculer à PDO soit un mauvais choix. Perso, je n'aime pas trop les sur-couches (Java, .Net, etc ...) sources de ralentissements ... Difficile de se prononcer en l'absence de Benchmarks ... (y compris benchmarks comparatifs entre protection par PHP avec opCode cache et protection par PDO) Link to comment Share on other sites More sharing options...
Sbizz Posted December 2, 2011 Share Posted December 2, 2011 Oui, c'est un défaut de PDO mais je trouve que ce défaut est largement comblé par les autres qualités de PDO. Par contre, je trouve PDO bien plus simple et il se rapproche plus de ce qu'on veut maintenant : de la POO. Mais c'est que mon avis ! Link to comment Share on other sites More sharing options...
DevNet Posted December 2, 2011 Author Share Posted December 2, 2011 Si le client ayant installé des add-on a souhaité faire des modifications générales, les modules des développeurs ne vont pas prendre en compte ces modifications si ils utilisent MaClasseCore. D'où le titre de mon article : Classes core ou classes de l’override ? Je pense qu'on parle le même langage, et je vous suis pour tout ce que vous annoncez. La seule différence c'est que vous abordez d'autres problèmes / explications qui n'ont rien à voir avec le sujet. Cette article retrace justement le fait qu'il est préférable pour un développement indépendant, et qui se greffe au noyau, d'utiliser directement les classes "core" dans le développement de module. Auquel cas, utiliser les classes susceptibles d'être extend par l'override, le développeur se bloque à des problèmes éventuels dans les fonctionnements futurs de son module. L'exemple est simple : Si je veux envoyer un mail depuis mon module et que j'utilise Mail::Send(...), mon module fonctionnera dans la mesure où la méthode Mail::Send(...) fait ce que je souhaite. Hors, si on autre développeur propose un override de la méthode Mail::Send(...), où dans cette méthode il ne rappelle pas la méthode parente (comme dans mon exemple de l'article), mais il raz complétement le fonctionnement normal de cette méthode, le module que vous venez de développer ne fonctionnera plus tel que vous l'avez souhaité. Au contraire, si dès votre développement, vous optez pour MailCore::Send(...), tout autre développeur aura beau créer quoi que ce soit en override sur la méthode Mail::Send(...), votre code ne sera pas impacté et vous garantissez le fonctionnement dans le temps de votre module. Les seules évolutions a surveiller sont celles du noyau PrestaShop lui-même. Pour ce qui est de votre exemple MySQLCore, vous avez entièrement raison. Seul incompréhension, c'est pourquoi le fonctionnement du cœur passe par certains overrides ? Et même si ceci ouvre à d'autres discutions, ce n'est toujours pas le sujet de l'article en question. Pour finir, je pense qu'on parle le même langage, mais que vous n'avez pas bien cerné l’intérêt de mon article. Bien cordialement Link to comment Share on other sites More sharing options...
Sbizz Posted December 2, 2011 Share Posted December 2, 2011 Cette article retrace justement le fait qu'il est préférable pour un développement indépendant, et qui se greffe au noyau, d'utiliser directement les classes "core" dans le développement de module. C'est là sur ce quoi j'interviens : votre module PEUT être indépendant à vos yeux, mais pour les yeux d'un autre développeur il ne doit pas l'être. Exemple avec la classe Mail.php : Si l'on surcharge cette méthode, qu'on rajoute des fonctionnalités ou qu'on fait une refonte de celle-ci, elle doit avoir le même but : envoyer un email, avec les même paramètres. Exemple: Admettons, moi, client de plusieurs modules, j'ai téléchargé un module qui va faire que ma méthode Mail::Send() doit passer par diverses étapes que Prestashop ne gère pas naturellement parce que mon hébergeur me le demande / parce que je préfère passer par un autre système / parce que je suis chiant. J'installe votre module : mince, il reprend la fonction de base de Prestashop. Le module devient obsolète car il marche pas. Je parle d'un seul exemple, mais imaginez si plusieurs modules sont installés. Certains modules vont effectivement être indépendant pour certaines raisons. Mais dès lors où vous utilisez une classe de Prestashop, celle-ci peut être modifiée car le client veut que ce soit comme ça. Après, mettons-nous d'accord : dans certains cas, ça peut être intéressant. Mais il y a trop de risque. Je vous prends un exemple, mon cas à moi, si on suit votre logique : j'ai mon module qui s'amuse à toucher le listing des produits des catégories : ils rajoutent de nombreuses données et surtout, il modifie lourdement la requête. Je vois un module intéressant qui a un impacte sur les catégories, pour X ou Y raison : si votre module reprend la fonction de base, il me sert à rien, car si j'ai changé mon listing ce n'est pas pour le retrouver via un module. Seul incompréhension, c'est pourquoi le fonctionnement du cœur passe par certains overrides ? Ceux sont, de base, des fichiers exemples pour l'overriding. Pour MySQL.php, elle permet d'ajouter un compteur de requêtes, un timing sur les requêtes, un listing des requêtes, etc. Il y a un underscore (_) qui faut enlever pour activer la classe. Link to comment Share on other sites More sharing options...
DevNet Posted December 2, 2011 Author Share Posted December 2, 2011 Après, mettons-nous d'accord : dans certains cas, ça peut être intéressant. Mais il y a trop de risque. Personnellement je n'adhère pas à vos propos. Les risques sont tout aussi important dans votre sens. Si je pars dans votre principe, par ordre chronologique : 1) MaClasseCore est lancée et est disponible par le noyau 2) MaClasseCore::MaMethode() est disponible 3) override de MaClasseCore::MaMethode() par MaClasse::MaMethode() grâce à MaClasse extend MaClasseCore, et ceci depuis le module BETA qui installe automatiquement /override/classes/maclasse.php. Dans cet méthode override nous appelons la méthode parente par : // Module BETA class MaClasse extends MaClasseCore { public static function MaMethode() { // traitement avant parent::MaMethode(); // traitement après $MaValeur = 'ma nouvelle valeur Beta'; } } Jusque là on se réjouie déjà de cette superbe possibilité modulaire. Je poursuis : 4) override de MaClasseCore::MaMethode() par MaClasse::MaMethode() grâce à MaClasse extend MaClasseCore, et ceci depuis le module GAMA qui installe automatiquement /override/classes/maclasse.php. Resultat, premier blocage, l'override est déjà existant, et le module GAMA ne peut pas s'installer. Est-ce la faute de GAMA ou BETA ? Le client va donc se reporter vers le développer du module GAMA. 5) après explication du développeur de GAMA, voici la nouvelle méthode override spécialement en place pour la cohabitation : // Module BETA + GAMA class MaClasse extends MaClasseCore { public static function MaMethode() { // traitement avant parent::MaMethode(); // traitement après // $MaValeur = 'ma nouvelle valeur Beta'; $MaValeur = 'ma nouvelle valeur GAMA'; } } 6) zut ... le module BETA ne fonctionne plus car le traitement ne fait plus ce qu'il est censé faire à l'origine de l'override. 7) cercle vicieux ... Tout le monde ne sait pas manipuler la POO, encore moins monsieur tout le monde qui ne comprends pas que les modules ne peuvent pas cohabiter. C'est logique, pour les faire cohabiter il faut : - soit être un développeur habitué en POO - soit utiliser les méthodes mères du noyau, soit dans mon exemple MaClasseCore Libre ensuite à chaque développeur d'améliorer les fonctionnalités qui resteront indépendantes certes, mais fonctionnelles. Dernière chose, pour un cas concret, imaginons que 5 modules entièrement fonctionnels avec Mail::Send(...), et qu'un override en place soit celui-ci : class Mail extends MailCore { public static function Send($id_lang, $template, $subject, $templateVars, $to, $toName = NULL, $from = NULL, $fromName = NULL, $fileAttachment = NULL, $modeSMTP = NULL, $templatePath = _PS_MAIL_DIR_, $die = false) { return false; } } Aucun des modules, ni traitements ayant utilisé Mail::Send(...) ne fonctionneront. Hors, MailCore::Send(...) fonctionnera toujours avec le traitement du noyau en vigueur. Bien cordialement Link to comment Share on other sites More sharing options...
Sbizz Posted December 2, 2011 Share Posted December 2, 2011 Je réponds simplement à ceci : le module BETA qui installe automatiquement /override/classes/maclasse.php le module GAMA qui installe automatiquement /override/classes/maclasse.php par ça : Lorsque vous surchargez une classe, vous devez prendre en compte que quelqu'un d'autre peut venir surcharger en même temps la classe. C'est d'ailleurs très problématique. Par exemple, mon module surcharge la classe Validate.php pour rajouter des méthodes (aucune surcharge de méthode). Lors de l'installation du module, je copie le fichier si et seulement si aucun fichier Validate.php n'est présent dans l'override. Je dois donc demander à l'utilisateur de modifier le fichier déjà présent pour ajouter mes fonctionnalités. Plus ennuyant encore : si j'avais surchargé une méthode déjà existante et que le fichier déjà présent aurait fait la même chose, cela deviendrait plus compliqué. C'est un problème qui peut vite arriver. et ceci : Aucun des modules, ni traitements ayant utilisé Mail::Send(...) ne fonctionneront. par ça : Si l'on surcharge cette méthode, qu'on rajoute des fonctionnalités ou qu'on fait une refonte de celle-ci, elle doit avoir le même but : envoyer un email, avec les même paramètres. Si vous vendez votre module par le biais de Prestashop Add-on, ces derniers vérifiront votre module. Si vous vous amusez à détruire des fichiers existants, il sera refusé. Si vous vous amusez à overrider des classes pour les rendre obsolètes, il sera refusé. Les limites des modules peuvent vite se faire ressentir, quand on installe un nombre important de module. Si vous surchargez un module, c'est à VOUS de faire en sorte que celui-ci s'adapte au site du client. Donc éviter de c/c trop rapidement le fichier et surtout de mettre des conditions d’exécutions si vous souhaitez rajouter ou faire une refonte d'une méthode. Link to comment Share on other sites More sharing options...
DevNet Posted December 2, 2011 Author Share Posted December 2, 2011 Je pense qu'on tourne en rond à coup de citation, car vous avez raison autant que moi puisque nous disons la même chose Sauf que vous orientez plus les développeurs à adapter leur code en fonction de ce qui pourrait exister, et moi je les oriente plus à créer du code qui sera fonctionnel pour leur développement à eux. Bien cordialement Link to comment Share on other sites More sharing options...
olea Posted December 2, 2011 Share Posted December 2, 2011 DevNet, SBizz, Comme le dit DevNet juste au dessus, je pense que vous avez tous les 2 raisons. L'override tel qu'il est proposé dans prestashop permet de faire soit de l'override, soit de l'extension, c'est ouvert, et c'est suivant les besoins. 1/ Une méthode override doit-elle appeler la méthode mère ? -> ca dépend du besoin. Dans les listes de produits, s'il faut remonter plus d'infos, on appelera la mère et on complètera avec ce dont on a besoin en plus : extension Pour un checkPassword d'un client, on peut ne pas vouloir utiliser la méthode presta : surcharge Sur ce point, il n'y a pas vraiment de règle sur plutôt l'une ou l'autre des options 2/ Faut-il appeler les méthodes Class_core ou Class ? -> idem, c'est selon la finalité Lors du développement d'un module, si on utilise Customer_core::checkpassword() on est sûr d'utiliser la méthode presta, mais si elle a été surchargée, il valait mieux appeler Customer::checkPassword() pour appeler la bonne méthode de check perso, je propose un module de gestion de prix par client, suivant le principe : si prix client existe, l'utiliser sinon appliquer le prix du groupe (géré par presta). Pour cela, je fournis la méthode (et ses associées) Product::getPriceStatic() : elle appelle la mère, elle récupère les données du module (prix client) et décide quel est le prix à retourner. Si un autre module appelle Product_core::::getPriceStatic(), ce module est sûr de ne pas récupérer le bon prix. Pour ce 2ie point, en tant que développeur de module, je préconise d'appeler la méthode générale et non la _core pour tous les objets ou controllers natifs de prestashop. En effet, étant dans un module, on ne sait pas quelle surcharge ont était faites. DevNet, pour ton exemple de Mail::Send() je ne suis pas d'accord avec ta vision qui consiste à dire : j'appelle le Mail_core::Send() parce que je sais ce qu'il fait. -> on ne doit pas présupposer de ce que font les méthodes internes. Celle là elle m'envoie un mail par le moyen qu'elle veut. Si je veux qu'elle l'envoie par un moyen bien précis, spécifique à mon module, je dérive l'objet Mail en un objet MailPerso, je code le Send() qui me convient et seul mon module est capable d'appeler ce Send Ca me semble très risqué de prendre comme règle l'appel des méthodes des ClassCore. Link to comment Share on other sites More sharing options...
DevNet Posted December 2, 2011 Author Share Posted December 2, 2011 Bonjour olea, Merci pour tes précisions qui confortent certainement tout ce qui précède. La dérive de classe à son profit pour un usage propre au module est d'ailleurs un article que je souhaitais détailler. Ca me semble très risqué de prendre comme règle l'appel des méthodes des ClassCore. Quels sont les risques ? Bien cordialement Link to comment Share on other sites More sharing options...
olea Posted December 2, 2011 Share Posted December 2, 2011 Je viens de relire ce post et ton article. La philo globale n'est pas d'appeler les ClassCore mais les Class. Tout d'abord, postulat de base : tout développement complémentaire doit se faire : - soit dans un module pour de l'ajout fonctionnel. Il embarque alors classes et controlleurs qui lui sont spécifiques - soit dans l'override pour modifier/étendre le comportement du coeur -> il n'est pas dans l'esprit de modifier les classes ou controlleur directement dans le coeur ou de rajouter ses propres classes/controlleurs dans ce coeur. Si du code d'un module a besoin d'appeler la méthode d'une classe : - soit c'est une de ses propres classes, que lui seul connait, et qui a le comportement qu'il veut - soit c'est une classe qui lui est externe et il ne DOIT pas présager de son comportement. C'est une classe Class qu'il appelle et il n'a pas à savoir si elle est surchargée ou non Si le module appelait la méthode ClassCore, il passe à côté du surcharge et tout le fonctionnel de la boutique part à la catastrophe. L'exemple de SBizz sur la class MySQL est tout à fait probant. En effet : - les appels MySQLCore::MethodeX() sont optimisés pour être performants - presta offre la classe surchargée, moins performante, puisqu'elle trace tous les appels BDD à des fins de debug (il faut enlever le '_' devant le nom de fichier pour la rendre active). Si dans un module tu appelles MySQLCore::MethodeX() (ce que tu préconises), cela n'appelle pas la méthode en override et cet appel ne fait pas partie de infos de debug, ce qui est gênant. Il en est de même pour tout autre classe : si tu appelles le ClassCore depuis un module, tu déclenches le comportement de base et non pas le comportement souhaité par l'override (qui est global à la boutique) Maintenant, si tu as un cas particulier de module qui a besoin d'un traitement spécifique qui ne soit pas global à la boutique, il faut passer par une dérivation de la classe Class en une classe ClassPerso déclarée dans ton module. Exemple qui m'est arrivé : sur une boutique, certains des clients sont des particuliers, d'autres sont des éleveurs de chiens, tout en étant des clients de la boutique. J'ai donc déclaré une classe Eleveur, dérivé de Customer dans laquelle je rajoute mes spécificités. D'un point de vue global prestashop, ce sont des Customer (ils s'inscrivent, passent commande, paient, vérifient leur historique...). Mais mon module leur offre des fonctions supplémentaires. Nulle part je n'ai fait référence à CustomerCore Link to comment Share on other sites More sharing options...
olea Posted December 2, 2011 Share Posted December 2, 2011 je les oriente plus à créer du code qui sera fonctionnel pour leur développement à eux. => tout ce code doit se trouver dans leur propre module vous orientez plus les développeurs à adapter leur code en fonction de ce qui pourrait exister => pas tout à fait. On les oriente à utiliser des objets dont on ne connait pas le comportement précis, mais on s'en fiche car on n'est pas dépendant de ce comportement. Pour l'exemple du Mail::Send() qui était plus haut, l'idée est que le module a envie d'envoyer un mail, sans savoir comment se fait l'envoi Si la méthode d'envoi est particulière au module, c'est que le module n'est plus en train d'envoyer un Mail mais un MailParticulier, dérivé d'un Mail et développé dans le module Link to comment Share on other sites More sharing options...
RUNps Posted December 3, 2011 Share Posted December 3, 2011 Salut Très intéressant, cela permet de recadrer un petit peu son approche sur la POO. Peut être que tout cela vient du choix par la Team Prestashop sur le nom de ce répertoire : override. Si on le traduit, cela veut dire : ignorer, annuler, outrepasser, etc ... On peu se poser la question si ce nom est si judicieux que ça. Il me semble que, vous m'arrêter si je m'égare, mais le principal intérêt d'une classe étendue (classe dérivée, ou surcharge de classe) c'est de l'étendre, donc de rajouter de nouvelles fonctionnalités. J'ai peut être même tendance à dire : de rajouter de nouvelles fonctionnalités sans changer le comportement de base de la classe parente. Mais là ??? Je doute tout de même que le principal but soit d'annuler le comportement d'une méthode par exemple. Si on prend les extrêmes, comme redéfinir toutes les méthodes et propriétés d'une classe, à quoi bon la dériver ? Or, cet article "Classe core ou classe de l'override" a peut être pris trop mot pour mot la signification de "override" et fait en quelque sorte l'apologie du remplacement de méthode. Par ailleurs, le terme "remplacer" ne me semble pas le terme le plus utilisé, j'utilise essentiellement le terme de "redéfinition" de méthode de classe (ou de propriété). Disons que si on a un besoin qui nous est propre, il n'est pas certain de devoir redéfinir une méthode de classe. C'est peut être cela que dégage cet article, ça laisse supposer que la surcharge d'une méthode demande à la redéfinir entièrement et systématiquement, quitte à reprendre le même code de la méthode parente. On peu donc se poser la question: Est-ce si judicieux que ça de redéfinir entièrement la méthode parente ? A titre personnel j'ai tendance à dire non, peut être même surtout pas. Dans un environnement comme celui où on se trouve (Prestashop), n'est il pas préférable de ne jamais modifier le comportement de base des méthodes des classes du core, ne pratiquer que la surcharge (on rajoute) ? Donc soit appeler la méthode parente puis ensuite rajouter ses traitements, soit rajouter une nouvelle méthode. Au final, il est très simple de pratiquer la surcharge grâce à l'override, mais quand on creuse un peu, la décision n'est pas si évidente que ça. Le danger d'ailleurs, n'est t-il pas que les contributeurs (ceux qui créent les modules) n'optent pas pour une surcharge des classes du core, mais de refaire les mêmes traitements (tout ou en partie) juste pour éviter toutes sortes de comportements inattendues qui seraient liés par la surcharge des uns et des autres. Grosso modo : J'ai besoin d'envoyer un mail, alors je crée une nouvelle classe d'envoie de mail dans le module (donc aucun fichier dans ./classes ou ./override/classes et je reste indépendant du comportement de Prestashop. (exemple basique voir absurde, mais c'est juste pour exemple). En tout cas, je débute avec Prestashop, je connais mal ce qui ce fait autour, mais c'est un des phénomènes que j'ai remarqué pour le blog WordPress. Quelle serait selon vous la bonne pratique concernant cette surcharge de classe dans l'override ? Quelles seraient les dérives, les dangers, les précautions à prendre ? Link to comment Share on other sites More sharing options...
DevNet Posted December 3, 2011 Author Share Posted December 3, 2011 Merci à tous pour vos précisions. Je vais éditer cet article, pour détailler un peu plus la partie des risques liés à un override non conventionnel. C'est à dire, dans le cas où des développeurs chercheraient à utiliser le remplacement d'un traitement d'une méthode au lieu d'étendre son traitement (voix normale d'une classe extend). Comme ça, je mettrai tout le monde d'accord. J'aurai certainement dû le faire avant de présenter l'article, mais quand on part sur de telles explications, il est difficile d'avoir les mots juste dès le départ. Edit : Le contenu de l'article a été amélioré. Bonne continuation Link to comment Share on other sites More sharing options...
olea Posted December 3, 2011 Share Posted December 3, 2011 Je ne vois pas trop ce que tu appelles "override conventionnel". Quand tu développes une évolution : A/ soit le comportement de objet MaClass t'es indifférent (c'est le cas la plupart du temps) B/ soit tu as un besoin spécifique sur cet objet, mais uniquement pour ton évolution C/ soit un comportement nominal du coeur ne te convient/suffit pas Je reviens sur les exemples que j'ai déjà donnés : pour A/ : lorsqu'on développe une évolution, on ne réécrit pas l'ensemble des objets. On se base sur le comportement global qui nous est indifférent (on sait que ca marche, c'est l'essentiel). On utilise les Cookie, Mail, Category, Product.....Presta tout seul appelle les Core s'il ne trouve pas le comportement global. Pour B/ : Customer est un objet natif de prestashop Je le dérive dans un module vers un objet Eleveur (class Eleveur extends Customer) Mes Eleveur sont traités comme des Customer par l'ensemble du code Prestashop et mon module les étends en tant qu'éleveurs Voir même d'autres modules les utilise comme Customer, sans savoir que ce sont des Eleveurs Pour C/: Si un autre développeur souhaite changer le comportement de la vérification des password, dans override, il réécrit la méthode Customer::checkPassword(). Mon module n'est pas impacté par cet override. Partout dans le code, il faut bien avoir appelé Customer->checkpassword(). Si à un endroit, on a un appel à CustomerCore->checkPassword(), cet appel va vérifier le password selon la méthode native de Prestashop, ce qui est incohérent. Il risque de laisser passer un pass qui ne devrait pas ou de refuser un pass qui devrait être OK. Quand on développe, on s'appuie sur les comportements globaux des objets MaClass, on ne s'appuie pas sur le comportement natif MaClassCore. Tout autre développeur modifiera comme bon lui semble l'override, notre évolution n'est (dans la plupart des cas) pas impacté. Si un comportement natif ne nous convient pas, il faut le modifier par un override : - soit l'override concerné n'existe pas déjà => on l'écrit comme on veut (avec ou sans appel à la méthode mère) - soit l'override existe et il faut intégrer le comportement qu'on souhaite au comportement déjà écrit La préconisation est bien d'appeler les Class et non les ClassCore. Je n'ai pas encore eu de cas où j'avais un besoin explicite d'appeler les ClassCore Link to comment Share on other sites More sharing options...
DevNet Posted December 3, 2011 Author Share Posted December 3, 2011 J'ai pris la décision de supprimer cet article. Quoi que l'on écrive, en essayant de trouver des mots à des explications techniques, il y aura toujours quelqu'un pour vous contredire en voulant faire comprendre des éléments (certes tout à fait vérifiés pour lequel j'adhère) qui n'ont rien à voir avec l'intention première. On va donc ne laisser que vos commentaires et vos contenus techniques très bien détaillés sur ce topic, de manière à ce que le lecteur se retrouve dans vos discours. Bien cordialement Link to comment Share on other sites More sharing options...
Sbizz Posted December 3, 2011 Share Posted December 3, 2011 Il me semble que, vous m'arrêter si je m'égare, mais le principal intérêt d'une classe étendue (classe dérivée, ou surcharge de classe) c'est de l'étendre, donc de rajouter de nouvelles fonctionnalités.J'ai peut être même tendance à dire : de rajouter de nouvelles fonctionnalités sans changer le comportement de base de la classe parente. Mais là ??? Je doute tout de même que le principal but soit d'annuler le comportement d'une méthode par exemple. Si on prend les extrêmes, comme redéfinir toutes les méthodes et propriétés d'une classe, à quoi bon la dériver ? Oui et non. Cela va dépendre de ce que tu vas vouloir faire. Si tu veux redéfinir toutes les méthodes, tu peux. D'ailleurs, l'exemple le plus marquant c'est bien la classe Mail.php : elle ne contient que deux méthodes et si tu dois utiliser un système d'e-mail différent de celui de Prestashop, tu vas devoir surcharger la méthode sans appeler la méthode parente. Il faut comprendre le mot "surcharger" avant toute chose. extends veut effectivement dire "étendue" mais dans le cas où l'on crée vraiment une "suite" de la classe mère. Par exemple, créer la classe "Membre" et créer la classe "Administrateur" étendue de "Membre" : ici, on n'aura pas de surcharge (ou très peu, mais on comprendra que Administrateur va plus rajouter des fonctionnalités que modifier le comportement général de Membre). Dans Prestashop, c'est vraiment tout le contraire, car d'une part le dossier s'appelle "override" (qui est donc assez explicite) et d'autre part, on va nommer la classe d'override à l'identique de la classe mère (ValidateCore => Validate : le suffixe core n'est présent ici que pour signaler que c'est le coeur de la classe et cela permet de gérer facilement l'override avec la classe ControllerFactory.php). Il faut aussi se mettre en tête qu'on est sous une architecture MVC. Rappel : M : Model V : View C : Controller Cela veut dire que vous pouvez modifier une partie sans se soucier d'une autre. Il faut réfléchir dans la même optique avec l'overriding : j'ai une classe Mail, une méthode Send : le commentaire de la classe me dit "C'est une fonction pour envoyer un e-mail avec ces paramètres" : OK. Moi j'm'en fous de ce qu'il y a l'intérieur : je sais qu'elle envoie des e-mails, c'est tout ce que je dois savoir. Je pense qu'une image vaut mieux qu'un long discours : Pour le développeur créant la classe, on obtient ça comme image : Pour le développeur utilisant la classe, on obtient ça : Source : http://www.siteduzer...ntee-objet.html Bienvenue dans le monde de la POO. Je relis votre article plus tard. Week-end, toussa.. Edit: J'ai pris la décision de supprimer cet article. Quoi que l'on écrive, en essayant de trouver des mots à des explications techniques, il y aura toujours quelqu'un pour vous contredire en voulant faire comprendre des éléments (certes tout à fait vérifiés pour lequel j'adhère) qui n'ont rien à voir avec l'intention première. Quelle réaction... En écrivant un article, quel qu'il soit, vous auriez dû vous attendre à des critiques, négatives comme positives. Le supprimer c'est pas une solution. Le plus gros problème de votre article, c'est que vous incitez les développeurs à utiliser la classe mère. Prestashop ne fait pas comme ça (et des modules ont été développés par Prestashop, pour rappel !). Pourquoi les développeurs, externes et créateurs de module, devrait le faire ? Si Prestashop a créé l'overriding de cette manière, c'est bien parce qu'il y a une raison : la raison, je vous l'ai donné et dans ce poste, je suis même allé plus loin. Écrire un article sur l'overriding est, à mon humble avis, en rien difficile. Néanmoins, si l'on part dans la mauvaise direction, on prend un faux départ. On vous a apporté des idées et des avis, utilisez-les. Si on rédige des pavés, ce n'est pas pour qu'au final vous veniez nous dire "J'ai supprimé cet article parce que vous n'avez pas les même intentions dont parle ce dernier". Si nous, développeur ayant des connaissances dans Prestashop, on a du mal à comprendre votre article, alors imaginez les débutants : mettez-vous à leur place. Link to comment Share on other sites More sharing options...
Captain FLAM Posted December 3, 2011 Share Posted December 3, 2011 @ RUNps : l'override Presta permet le remplacement et/ou l'extension des méthodes d'une classe. ex1 : remplacer juste la fonction qui gère les Hooks de FrontController, afin de rajouter un Hook perso : pour cela, tu override juste la function dans ton nouveau fichier ex2 : tu peux aussi étendre la classe en rajoutant des fonctions personnalisées ( function MaFonction {} ) Link to comment Share on other sites More sharing options...
RUNps Posted December 4, 2011 Share Posted December 4, 2011 @ RUNps : l'override Presta permet le remplacement et/ou l'extension des méthodes d'une classe.Merci pour ce rappel, ceci est le BABA de la POO, qui par ailleurs n'est en rien propre à l'override de Prestashop.Il me semble que tous les intervenants sur ce post ont tous les bases de la POO, et même au-delà. Il était surtout question de l'art et la manière de faire évoluer Prestashop via l'override, qui n'est qu'autre que la surcharge de classe. Donc oui, on a le choix, cependant, le plus intéressant c'est le choix qu'il y a entre ces 2 là par exemple. Pour le développeur utilisant la classe, on obtient ça : (image coffre fort)Oui, tout à fait, mais c'est un idéal, c'est ce que doit peut être proposer Prestashop, mais ce n'est pas du tout le cas.La plupart des classes du core ont des méthodes soient pupliques ou protégées, rarement privés, de même que je n'ai pas vu une seule classe finale, etc ... Donc quasi tout peut être redéfini, surchargé ... dans l'absolu, on pourrai faire un forum en guise de boutique en ligne. Pas sur que les clients vont apprécié. On est très loin du coffre fort vois tu. Dans Prestashop, c'est vraiment tout le contraire, car d'une part le dossier s'appelle "override" (qui est donc assez explicite) et d'autre part, on va nommer la classe d'override à l'identique de la classe mère (ValidateCore => Validate : le suffixe core n'est présent ici que pour signaler que c'est le coeur de la classe et cela permet de gérer facilement l'override avec la classe ControllerFactory.php).Je ne le perçois pas vraiment ainsi.Je ne vois pas comment Prestashop pourrait faire autrement se que propose la POO, la philosophie de l'override est à mon sens la même, cela ne peut pas être autrement. Aussi, et sauf erreur, il ne me semble pas qu'il y ait une restriction sur le nom de la classe. On peut créer une classe dans l'override avec comme nom Toto qui étend la classe CustomerCore. Ceci dit, par convention il est mieux de respecter les noms, j'en conviens. Disons que s'il y a une restriction, je ne l'ai pas vu. Cela vient d'être dit : On a le choix de soit étendre une classe (de rajouter des fonctionnalités), soit de la redéfinir (de refaire tout autrement). Quelque part, ce nom "override" porte à confusion, peut créer un amalgame. Override signifie "annuler", or, quand on étend une classe, on annule rien, la nouvelle classe par défaut reprend toutes les propriétés et méthodes de la classe parente. Mais ça, on le sait tous. Ceci dit, Override signifierait aussi "Substitution", cette définition serait peut être plus juste, encore que. Il me semble (la, encore une fois), que le principal objectif de ce mécanisme override est d'offrir aux codeurs/développeur d'étendre les fonctionnalités de bases, de les accroitre, mais pas de refaire ce qui est déjà fait. C'est une généralité, et comme toute généralité il y a des particularités, évidemment. Disons que ce terme "override" me laisse un peu dubitatif, je ne le perçois pas comme un synonyme de "extends", qui est pourtant le mécanisme déclenché. La seule particularité peut être, vient de l'autoload, du chargement automatique des classes, donc de l'ordre et où seront chargées les classes. C'est d'ailleurs à ce niveau qu'on voit qu'il est préférable de ne pas appeler directement la classe du core (genre MaClasseCore) mais plutôt la classe MaClasse. D'autre part, si on regarde la futur version 1.5, toutes les classes du core sont reprises dans le répertoire override, et toutes surchargées, sans plus. Exemple : class Address extends AddressCore { } Cela renforce un peu plus le fait de privilégier l'appel à la classe plutôt que directerment de celle du core. Le choix du nom "override" serait alors plus lié au mécanisme de l'autoload que celui de "extends" (surcharge). Tout ceci sauf erreur ... et bon Week end Link to comment Share on other sites More sharing options...
Recommended Posts
Create an account or sign in to comment
You need to be a member in order to leave a comment
Create an account
Sign up for a new account in our community. It's easy!
Register a new accountSign in
Already have an account? Sign in here.
Sign In Now