J. Danse Posted October 20, 2012 Share Posted October 20, 2012 Dans la version 1.5 de PrestaShop, il est possible d'ajouter un dossier "override" au module permettant, si besoin en est, d'installer un override via l'ajout du module. Il existe deux méthodes: addOverride et removeOverride. /** * Add all methods in a module override to the override class * * @param string $classname * @return bool */ public function addOverride($classname) { $path = Autoload::getInstance()->getClassPath($classname.'Core'); // Check if there is already an override file, if not, we just need to copy the file if (!($classpath = Autoload::getInstance()->getClassPath($classname))) { $override_src = $this->getLocalPath().'override'.DIRECTORY_SEPARATOR.$path; $override_dest = _PS_ROOT_DIR_.DIRECTORY_SEPARATOR.'override'.DIRECTORY_SEPARATOR.$path; if (!is_writable(dirname($override_dest))) throw new Exception(sprintf(Tools::displayError('directory (%s) not writable'), dirname($override_dest))); copy($override_src, $override_dest); return true; } // Check if override file is writable $override_path = _PS_ROOT_DIR_.'/'.Autoload::getInstance()->getClassPath($classname); if (!is_writable($override_path)) throw new Exception(sprintf(Tools::displayError('file (%s) not writable'), $override_path)); // Make a reflection of the override class and the module override class $override_file = file($override_path); eval(preg_replace(array('#^\s*<\?php#', '#class\s+'.$classname.'\s+extends\s+([a-z0-9_]+)(\s+implements\s+([a-z0-9_]+))?#i'), array('', 'class '.$classname.'OverrideOriginal'), implode('', $override_file))); $override_class = new ReflectionClass($classname.'OverrideOriginal'); $module_file = file($this->getLocalPath().'override'.DIRECTORY_SEPARATOR.$path); eval(preg_replace(array('#^\s*<\?php#', '#class\s+'.$classname.'(\s+extends\s+([a-z0-9_]+)(\s+implements\s+([a-z0-9_]+))?)?#i'), array('', 'class '.$classname.'Override'), implode('', $module_file))); $module_class = new ReflectionClass($classname.'Override'); // Check if none of the methods already exists in the override class foreach ($module_class->getMethods() as $method) if ($override_class->hasMethod($method->getName())) throw new Exception(sprintf(Tools::displayError('The method %1$s in the class %2$s is already overriden.'), $method->getName(), $classname)); // Check if none of the properties already exists in the override class foreach ($module_class->getProperties() as $property) if ($override_class->hasProperty($property->getName())) throw new Exception(sprintf(Tools::displayError('The property %1$s in the class %2$s is already defined.'), $property->getName(), $classname)); // Insert the methods from module override in override $copy_from = array_slice($module_file, $module_class->getStartLine() + 1, $module_class->getEndLine() - $module_class->getStartLine() - 2); array_splice($override_file, $override_class->getEndLine() - 1, 0, $copy_from); $code = implode('', $override_file); file_put_contents($override_path, $code); return true; } /** * Remove all methods in a module override from the override class * * @param string $classname * @return bool */ public function removeOverride($classname) { $path = Autoload::getInstance()->getClassPath($classname.'Core'); if (!Autoload::getInstance()->getClassPath($classname)) return true; // Check if override file is writable $override_path = _PS_ROOT_DIR_.'/'.Autoload::getInstance()->getClassPath($classname); if (!is_writable($override_path)) return false; // Make a reflection of the override class and the module override class $override_file = file($override_path); eval(preg_replace(array('#^\s*<\?php#', '#class\s+'.$classname.'\s+extends\s+([a-z0-9_]+)(\s+implements\s+([a-z0-9_]+))?#i'), array('', 'class '.$classname.'OverrideOriginal_remove'), implode('', $override_file))); $override_class = new ReflectionClass($classname.'OverrideOriginal_remove'); $module_file = file($this->getLocalPath().'override/'.$path); eval(preg_replace(array('#^\s*<\?php#', '#class\s+'.$classname.'(\s+extends\s+([a-z0-9_]+)(\s+implements\s+([a-z0-9_]+))?)?#i'), array('', 'class '.$classname.'Override_remove'), implode('', $module_file))); $module_class = new ReflectionClass($classname.'Override_remove'); // Remove methods from override file $override_file = file($override_path); foreach ($module_class->getMethods() as $method) { if (!$override_class->hasMethod($method->getName())) continue; $method = $override_class->getMethod($method->getName()); $length = $method->getEndLine() - $method->getStartLine() + 1; array_splice($override_file, $method->getStartLine() - 1, $length, array_pad(array(), $length, '#--remove--#')); } // Remove properties from override file foreach ($module_class->getProperties() as $property) { if (!$override_class->hasProperty($property->getName())) continue; // Remplacer la ligne de déclaration par "remove" foreach ($override_file as $line_number => &$line_content) if (preg_match('/(public|private|protected)\s+(static\s+)?\$'.$property->getName().'/i', $line_content)) { $line_content = '#--remove--#'; break; } } // Rewrite nice code $code = ''; foreach ($override_file as $line) { if ($line == '#--remove--#') continue; $code .= $line; } file_put_contents($override_path, $code); return true; } A la première lecture du code, il semblerait qu'il soit possible d'écrire du code qui sera "retiré" par la suite. Je propose qu'on discute ici et commente ces deux méthodes pour une meilleure utilisation de celles-ci. Je les lirais plus en profondeur et réaliserais des tests pour voir le fonctionnement de celles-ci. 1 Link to comment Share on other sites More sharing options...
coeos.pro Posted October 20, 2012 Share Posted October 20, 2012 (edited) oui c'est ce que j'ai déjà expliqué: il suffit de mettre un dossier override dans le dossier modules : http://www.prestasho...post__p__969817 ces fonctions permettent d'installer et de désinstaller des modules ayant les mêmes classes avec des fonctions différentes SANS passer par le FTP (évidemment si tu installes un override contenant une fonction qui est déjà overridé il faut le faire par FTP et c'est la seule limitation) : http://www.prestashop.com/forums/index.php?/topic/195568-moduleoverride-gratuit-theme-switcher/page__view__findpost__p__969828 : il n'y a qu'une seule limite : le nouveau module contient une fonction dans un override qui est déjà installé dans l'override de la boutique. J'ai une boutique test en local avec une quinzaine de modules que je viens de mettre à jour et aucun soucis, j'installe un module j'en désinstalle un autre, tout est automatisé et se passe à merveille... Edited October 20, 2012 by coeos.pro (see edit history) Link to comment Share on other sites More sharing options...
J. Danse Posted October 20, 2012 Author Share Posted October 20, 2012 On est d'accord, mais... qu'en est-il du code que j'ai mis dans le premier message ? Je peux y voir figurer du _remove, et ainsi de suite. Le fait de mettre l'override dans un dossier, c'est déjà dit, là. L'intéressant est de discuter de la manière propre et correcte d'utiliser ce code, éventuellement ! Link to comment Share on other sites More sharing options...
jeckyl Posted October 20, 2012 Share Posted October 20, 2012 Bonjour, j'ai beau me dire que tout est possible et coes.pro nous le prouve chaque jours, j'ai du mal à faire confiance à 100% à une gestion automatisé des overides multiples de différents modules. Mais plus parce que je ne fait pas confiance au multiple développeur arrivant sur la solution et nous proposant leur vision plus ou moins académique du développement. N'étant mois même pas assez chevronné sur la maitrise du code objet et de cette nouvelle structure apparue sur la 1.5 je ne m'aventurerais pas à donner une analyse du code, mais juste une expérience sur l'utilisation de ces fonctionnalités qui peuvent être risqués, si mal utilisées. Mais peut être que vous arriverais à me convaincre que le codage de cette fonction arrivera à gérer tous les cas possibles. Link to comment Share on other sites More sharing options...
J. Danse Posted October 20, 2012 Author Share Posted October 20, 2012 Je voulais justement voir, au travers d'une bonne (et véritable) analyse, si il était possible de fournir une sureté dans l'utilisation de cette mécanique. Et voir si on ne peut pas proposer une solution alternative (tel qu'un nom comme proposé par Damien, à savoir ClassNameOverride<NomDuModule> ; par exemple). Mais pour ça, je voudrais être sur des possibilités déjà offertes par ces petits bouts de codes, qui vont bien plus loin que le simple fait de glisser des overrides dans un dossier, 1 Link to comment Share on other sites More sharing options...
coeos.pro Posted October 20, 2012 Share Posted October 20, 2012 j'ai fait pas mal de tests avec une quinzaine de modules avec et sans override, avec 1 et plusieurs override, avec plusieurs fonctions dans certains override, et je n'ai rencontré aucun problème aussi bien en installation qu'en désinstallation de modules... à vous de tester maintenant Link to comment Share on other sites More sharing options...
J. Danse Posted October 20, 2012 Author Share Posted October 20, 2012 Ok, on a donc tous compris: coes.pro a testé et analysé le code pour nous, mais on peut compter sur le fait qu'il n'en dira pas plus. Je ferais cela dans un futur proche (demain, grosso modo) et vous transmettrais mes analyses/conclusions. On pourra faire avancer aussi bien le débat que la documentation, je l'espère... Link to comment Share on other sites More sharing options...
coeos.pro Posted October 20, 2012 Share Posted October 20, 2012 mais on peut compter sur le fait qu'il n'en dira pas plus. je ne comprend pas, que dire de plus ??? Link to comment Share on other sites More sharing options...
J. Danse Posted October 20, 2012 Author Share Posted October 20, 2012 Commenter, le code, par exemple. C'est justement que tu sembles ne pas avoir lu le code ou pris la peine de voir ce qu'il proposait, d'aller plus loin. Je vois beaucoup de choses à dire de plus, mais avant de m'avancer là-dessus, je dois mieux analyser le code et faire des tests. Rien que le _remove ou encore #--remove--# à eux seuls m'intrigue. Si ce n'est pas ton cas, alors oui, il n'y a rien à dire de plus de ta part. Link to comment Share on other sites More sharing options...
J. Danse Posted October 29, 2012 Author Share Posted October 29, 2012 Quelques nouvelles, c'est une ligne tout droit venue de la version SVN: //$this->uninstallOverrides(); remove this line because if module a install an override, then module b install same override, this line will remove override of module a (if you find a bug related to this line please don't forget what i say before) A en croire ceci, cette méthode pose problème. On peut donc, très nettement, se renseigner sur ces méthodes plus loin que le fait de dire que, oui, cela fonctionne (mais jusqu'à quel moment, ça... !) Link to comment Share on other sites More sharing options...
Prestaspirit Posted February 15, 2013 Share Posted February 15, 2013 Salut, Je commence à peine à utiliser cette fonctionnalité et j'ai déjà repéré quelques bugs: - l'installation ce passe plutôt bien mise à part que les fichiers thème ne sont pas automatiquement surchargé, j'ai du bricoler un truc pour que les fichiers soit copiés dans le dossier override de Prestashop - Le ménages n'est pas fait complètement lors de la désinstallation, il reste tous ce qui est commentaire de méthode (pas trop gênant) et les définitions de constante dans la classe ne sont pas supprimés non plus (c'est déjà plus gênant) J'ai un module à réaliser et crois que je vais bien m'amuser. Franck 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