Jump to content

Comment modifier intelligemment le code de la classe tools


Recommended Posts

Bonjour,
Je suis un nouvel utilisateur de prestashop et compétent en php.
Voilà, je souhaiterais modifier le code de tools::completeMetaTags pour introduire des motifs dépendant de la catégorie dans le title des produits.
Or il ne me plait pas de modifier directement ce code bien entendu (pb lors des MAJ notamment).
Quelle est dans ce cas la méthode préconnisée ?

Merci d'avance.

Link to comment
Share on other sites

ok,ok donc prestashop 1.4 c'est ça ?
Le pb étant que mon client est en 1.3.x et que je n'ai pas asssuré le dev moi même donc maj risquée.
Bon quoiqu'il en soit vous semblez confirmer que jusqu'à la 1.4 rien n'existe pour surcharger les classes natives ou équivallent, exact ?

Link to comment
Share on other sites

Si j'ai un peu de temps, je vous ferais un tutoriel sur la mise en place d'un module simple avec une technique d'override sur un controller existant.

Ça permettra peut-être à certains développeurs d'avancer dans le projet afin de garantir un noyau intacte pour encore plus de fonctionnalités.

Maintenant j'avoue que la rédaction d'un tel tutoriel est assez long, mais je m'y engage.

Bien cordialement

Link to comment
Share on other sites

Et +1 pour la surcharge du coeur de la 1.4 , un truc en or, et relativement facile à mettre en oeuvre.

Autant la reflexion me paraissait évidente en C# autant c'était une notion que j'avais laissé de côté en php.
Heureusement que ce n'est pas le cas de la Team...

A l'instar de DevNet , je ferais bien une petite doc sur la mise en place d'un override de classe ou de controler dans la 1.4, mais le temps .. mazette.
Si tu veux un coup de main cependant , peut être que je peux t'en prendre un bout, DevNet, (là je parle de la 1.4, pour la 1.3, autant créer une nouvelle classe dérivée comme le suggère jherbaux)

Ca mérite peut être un autre topic , mais chaque fois que je pense l'override de la 1.4 , deux idées me viennent systématiquement :

- N'est-ce pas un gros risque de bazar si deux modules veulent surcharger la même classe ? Sachant en plus qu'à supposer que deux modules surchargent des methodes différentes, un seul fichier d'override ne peut résider dans le dossier adéquat.
- Pourquoi ne pas avoir une méthode permettant l'override à partir du dossier du module (enfin là j'ai bien mon idée...) ou surtout un outil permettant l'install ou copie de la classe du dossier module vers le dossier override? Je me suis dit que c'était peut être dans les idées en stock mais personne ne m'a répondu à ce sujet sur le forum VO.

Une dernière remarque pour la route : quitte à en être arrivé là , quid d'une utilisation plus aboutie de la réflexion avec possibilité d'avoir plusieurs surcharges d'une même classe dans le dossier override, et un système de priorité administrable ?

J'entends par la :
On a par exemple 2 surcharges de Cart.php nommées Cart_modulename1.php et Cart_modulename2.php
Avec un système de priorité , l'autoload pourrait être en mesure de 'merger' proprement deux surcharges pour peu que chacune concerne des methodes différentes. Dans le cas contraire, la methode de la classe de priorité la plus élevée serait celle utilisée.

Je dis peut être n'importe quoi , mais cela ne me semble pas être insurmontable , votre avis ?

Link to comment
Share on other sites

Bonjour,
Je suis en train de mettre à jour mes modules pour les passer en 1.4 (avec surcharge de coeur) et il y a des idées qui de prima bord sont bonnes mais deviennent irréalisables ou alors donnent du fil à retordre pour ceux qui veulent surcharger la même class, pire encore quand il s'agit de la même fonction. Tu ne dits pas n'importe quoi (je te rassure), mais si la même fonction doit être modifiée pour 2 modules différents, je ne vois pas trop comment surcharger avec 2 fichiers différents (ou alors j'ai loupé un truc) et pour la priorité c'est juste impossible.

Pour déplacer un fichier j'utilise tout simplement :

if(!file_exists('../override/controllers/SearchController.php'))
   copy('../modules/mon_module_a_moi/SearchController.php', '../override/controllers/SearchController.php');




Je propose (ce que je fais actuellement) de mettre en début de fichier quel(s) module(s) nécessite(nt) cette surcharge et les modifications apportées, exemple pour Prodcut.php:

/*
* MODIFICATIONS for "mon_module_a_moi", by moi :
*
*    * 1 line in function getProductProperties (signaled by :  <---- )
*    * function fct_speciale() (signaled by :  <---- )
*/

class Product extends ProductCore
{

...

public static function getProductProperties($id_lang, $row)
{

...

// Pack management
$row['pack'] = (!isset($row['cache_is_pack']) ? Pack::isPack($row['id_product']) : (int)$row['cache_is_pack']);
$row['packItems'] = $row['pack'] ? Pack::getItemTable($row['id_product'], $id_lang) : array();
$row['nopackprice'] = $row['pack'] ? Pack::noPackPrice($row['id_product']) : 0;
$row['donnees_a_moi']=Product::fct_speciale($row['id_product']);  //  <---- addons "mon_module_a_moi"
if ($row['pack'] AND !Pack::isInStock($row['id_product']))
   $row['quantity'] =  0;
...
}

public static function fct_speciale($id_product) //    <---- addons "mon_module_a_moi"
   {
       ...
   }




Si vous avez des suggestions...

Link to comment
Share on other sites

Une solution pourrait être de placer dans ton module un dossier "classe", dans lequel tu places tes surcharges de classe de ton module qui extends la classe utilisé.
Il te suffit ensuite de charger cette classe quand nécessaire. Tu pourras donc surcharger les classes voulu en fonction du module.

donc 2 modules différent peuvent surcharger une même classe et une même fonction et donc chargé en fonction du module.

hum je sais pas si c'est très clair ...

Link to comment
Share on other sites

Autres problèmes aussi, il n'y a pas d'override possible avec les classes admin de /admin/tabs, c'est dommage car ça ouvrirai des possibilités supplémentaires, pour éviter de faire des formulaires de configuration dans des modules, alors qu'il suffirai aussi de surcharger quelques méthodes admin.

Mais cela n'enlève pas le fait que oui, effectivement, la cohabitation d'override de mêmes classes ne pourra pas se faire sans un coup de baguette magique de la part de la PrestaTeam ! S'ils nous entendent ? Ca serai bien d'avoir leur avis.

Bien cordialement

Link to comment
Share on other sites

Tu ne dits pas n’importe quoi (je te rassure), mais si la même fonction doit être modifiée pour 2 modules différents, je ne vois pas trop comment surcharger avec 2 fichiers différents (ou alors j’ai loupé un truc) et pour la priorité c’est juste impossible


Merci je suis rassuré alors ;) .
Mais je ne suis pas d'accord avec toi , enfin pas tout à fait...
Bon je me suis mal expliqué peut être, mais ce que je suggère me semble loin d'être impossible.

Ce qui est impossible est de merger deux surcharges de la même méthode, mais je crois justement avoir dit le contraire, d'ou la notion de priorité.
En revanche il me semble tout à fait possible de merger deux classes de surcharge d'une même classe, dès lors qu'elles ne contiennent pas les mêmes méthodes (=fonctions, je précise car en reflection c'est le terme - le plus naturel à mon sens - qui est utilisé).
Deux modules différents qui auraient besoin d'une modification dans des méthodes différentes, mais d'une même classe , pourraient cohabiter sainement.
Je n'ai jamais testé la reflection sur php , il est vrai , mais j'en ai apprécié la puissance dans d'autres languages, et donc à moins que cet aspect soit vraiment négligé dans php , ce que je ne crois pas en jetant un coup d'oeil rapide au nombre de méthodes existantes, je crois qu'il est possible d'aller bien plus loin.

Je pense que ce qui est fait dans autoload avec les classes pourrait l'être avec les methodes.

Dans l'absolu , la réflection pourrait parfaitement permettre des surcharge dynamiques à la volée, au moment précis ou on en aurait besoin. En terme de performances et de stabilité c'est plus une utopie, mais je reste persuadé qu'on peut aller plus loin que ce qui existe aujourd'hui , et est déja un joli cadeau que j'apprécie à sa juste valeur... je précise...

Comme je ne veux pas affirmer sans l'avoir pratiqué , je vais m'atteler à jouer un peu avec les reflections en php.

Je vous ferais part de la faisabilité ou non de ce que j'imagine assez bien mais ai encore un peu de mal à décrire.
Link to comment
Share on other sites


Deux modules différents qui auraient besoin d'une modification dans des méthodes différentes, mais d'une même classe , pourraient cohabiter sainement.


Oui dans la mesure où les deux méthodes sont dans la même classe/fichier.
Si 2 modules veulent surcharger chacun une méthode différente de la classe Tools par class Tools extends ToolsCore, il faudra créer un seul fichier /override/classes/Tools.php.

Il est possible de créer une seconde classe extends ToolsCore, mais elle ne pourra pas s'appeler Tools, et donc ne sera pas exploité par le noyau en natif.
Link to comment
Share on other sites

Oui dans la mesure où les deux méthodes sont dans la même classe/fichier.
Si 2 modules veulent surcharger chacun une méthode différente de la classe Tools par class Tools extends ToolsCore, il faudra créer un seul fichier /override/classes/Tools.php.

Il est possible de créer une seconde classe extends ToolsCore, mais elle ne pourra pas s’appeler Tools, et donc ne sera pas exploité par le noyau en natif.


Salut DevNet,
c'est tout à fait exact avec l'autoload actuel , son code est clair et j'ai absolument conscience de ce que ça implique.
Je te rassure , je n'ai aucun doute là dessus.

Je pense à un autoload différent qui utiliserait la reflection pour (Re)construire à la volée cette fameuse classe Tools qui etendrait ToolsCore en fonction de plusieurs fichiers, et avant l'eval, je ne parle pas du simple require_once actuel.
Je ne sais pas si je me fais bien comprendre...
Je suis en train de tester un peu par le code mais rien n'est fait encore , mais dans mon idée et en français dans le texte je voudrais tester un algo autoload 100% orienté sur la reflection du genre :

- Parcours du dossier à la recherde classes dérivée (on pourrait avoir plusieurs déclarations Tools extends ToolsCore puisque le code n'est pas encore évalué)
- Parcours des méthodes pour la même classe et merge par priorité (définie je sais pas ou mais c'est juste une table à créer) : en cas de définition multiple la methode du module ayant la plus haute priorité d'override sera utilisée.
- Idem pour les propriétés , le cas échéant.
- Reconstruction donc à la volée de la classe concernée et finalement, eval de la classe ainsi reconstituée .

Rien de ça ne me semble impossible en fait. Le truc c'est qu'il faudrait encore que je le démontre et que je puisse poster un exemple pour mieux me faire comprendre.

Edit: Devnet , est-ce que ça te parle plus ?
Link to comment
Share on other sites

Bon je reviens pour dire et admettre que mon idée, si elle n'est pas irréalisable (je suis parvenu à un résultat), est très mauvaise.

L'idée n'est pas intéressante car pour y parvenir (je prends l'exemple de CartCore), chaque méthode que l'on voudrait surcharger depuis plus d'un module devrait figurer dans la classe :

class Cart extends CartCore



sous la forme

    function fonctionASurcharger($param1, $param2 ....)
   {
   recursion par reflection sur les diverses classes dérivées de CartCore (ex CartModule1,CartModule2 ...) pour tester la présence de fonctionASurcharger , et ses paramètres.

       invoke de la methode de la classe de priorité la plus élevée
   }



Bref récursivité à gogo et l'histoire du chien qui se mord la queue....pas glop

Link to comment
Share on other sites

Bonjour,
Je suis en train de mettre à jour mes modules pour les passer en 1.4 (avec surcharge de coeur) et il y a des idées qui de prima bord sont bonnes mais deviennent irréalisables ou alors donnent du fil à retordre pour ceux qui veulent surcharger la même class, pire encore quand il s'agit de la même fonction. Tu ne dits pas n'importe quoi (je te rassure), mais si la même fonction doit être modifiée pour 2 modules différents, je ne vois pas trop comment surcharger avec 2 fichiers différents (ou alors j'ai loupé un truc) et pour la priorité c'est juste impossible.

Pour déplacer un fichier j'utilise tout simplement :
if(!file_exists('../override/controllers/SearchController.php'))
   copy('../modules/mon_module_a_moi/SearchController.php', '../override/controllers/SearchController.php');




Je propose (ce que je fais actuellement) de mettre en début de fichier quel(s) module(s) nécessite(nt) cette surcharge et les modifications apportées, exemple pour Prodcut.php:

/*
* MODIFICATIONS for "mon_module_a_moi", by moi :
*
*    * 1 line in function getProductProperties (signaled by :  <---- )
*    * function fct_speciale() (signaled by :  <---- )
*/

class Product extends ProductCore
{

...

public static function getProductProperties($id_lang, $row)
{

...

// Pack management
$row['pack'] = (!isset($row['cache_is_pack']) ? Pack::isPack($row['id_product']) : (int)$row['cache_is_pack']);
$row['packItems'] = $row['pack'] ? Pack::getItemTable($row['id_product'], $id_lang) : array();
$row['nopackprice'] = $row['pack'] ? Pack::noPackPrice($row['id_product']) : 0;
$row['donnees_a_moi']=Product::fct_speciale($row['id_product']);  //  <---- addons "mon_module_a_moi"
if ($row['pack'] AND !Pack::isInStock($row['id_product']))
   $row['quantity'] =  0;
...
}

public static function fct_speciale($id_product) //    <---- addons "mon_module_a_moi"
   {
       ...
   }




Si vous avez des suggestions...



Quel est l'intérêt dans ton exemple de surcharger la classe Product ?
Tu rajoutes des nouveaux champs à l'objet, avec des méthodes spécifiques à ces champs, le tout sera utlisé uniquement depuis le code de ton module....

Il vaut mieux créer dans ton module une classe dérivée
class MyExtendedProduct extends Product {
}

La surcharge du coeur doit permettre de modifier des comportements du coeur sans avoir à modifier les fichiers de base du coeur.
A mon avis, mais il faut attendre la doc de la Team sur le sujet, cette surcharge ne devrait pas servir à spécialiser des classe pour utilisation dans des modules.

Par exemple, tes nouveaux champs, seul ton module les connait et sait les exploiter, ca doit rester dans une classe dans ton module
Mais presta livre de base des classes surchargée => n'importe quel appel de méthode fait depuis le coeur ou un module utilisera le comportement modifié, sans le savoir
Link to comment
Share on other sites

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 account

Sign in

Already have an account? Sign in here.

Sign In Now
×
×
  • Create New...