Manière moderne de réécrire des fichiers lib

21

Le problème est bien connu: les libclasses sont chargées exclusivement via l'autochargeur, et nous ne pouvons pas les changer autrement que:

  • Les copier entièrement dans un codePool vérifié plus tôt que lib.
  • Installation de l' autochargeur PSR-0 , spécification d'un plan de classe de chargement automatique, puis copie complète du fichier dans cette structure de dossiers. [ma solution actuelle]

Je suis dans une situation difficile parce que je veux potentiellement toucher un grand nombre de ces fichiers - mais pour ma santé mentale et la stabilité / évolutivité du magasin, je ne veux pas copier des classes de bibliothèque entières.

Maintenant, évidemment, il existe des solutions potentielles à ce problème, mais ils viennent tous avec leur propre ensemble de problèmes:

  • Suivez la route AOP et utilisez une bibliothèque PHP comme Go! AOP : Enfin, j'ai vérifié que les classes Magento doivent être chargées par l'autochargeur du compositeur, et pas seulement une disponible. Flyingmana a fait du travail dans ce domaine mais il n'est certainement pas prêt pour une utilisation en production et mes besoins sont plus immédiats. Je veux également expédier en tant qu'extension, et cela nécessiterait plus de configuration du compositeur.
  • Suivez la route AOP et utilisez une extension PHP native : probablement la plus favorable à ce stade, mais cela nécessiterait l'installation d'une extension distincte, sans oublier qu'elle ne fonctionnerait pas avec HHVM.
  • Utilisez le classkit et / ou le runkit de PHP : c'est une autre extension PHP native, donc elle a le même problème que ci-dessus.
  • Corrigez les sites d'appels pour utiliser ma propre \Danslo\Varien_Xversion namespaced ( ), puis étendez-vous à partir de l'original ( \Varien_X): il y a juste trop de sites d'appels à patcher et cela nécessiterait une quantité stupide de réécritures. Pas une option.
  • Lancez le mien: Il devrait être possible de:

    1. Écrivez mon propre chargeur automatique.
    2. Copiez la classe d'origine dans un dossier séparé ( {root_dir}/var/tmp), enveloppez-la namespace \Magento { < original contents > }.
    3. Incluez ce fichier.
    4. Inclure ma classe modifiée OriginalClass extends Magento\OriginalClass {}

L'inconvénient est évident: génération de code dynamique, regex, un peu de surcharge pour charger des classes réécrites. Mais je suis presque sûr qu'à ce stade, il serait préférable de copier ~ 5000 lignes de code lorsque je veux juste toucher / ajouter ~ 100 lignes.

Je sais que j'en demande beaucoup, mais y a-t-il quelque chose de moderne et de relativement propre qui aide à résoudre ce problème?

Daniel Sloof
la source
1
Avez-vous déjà trouvé une solution d'observation Alans? stackoverflow.com/a/4636662/158325
B00MER

Réponses:

9

Décidé de mettre en œuvre Go! Framework AOP dans Magento.

Voir Danslo_Aop sur github.

Daniel Sloof
la source
2

Suivez la route AOP et utilisez une bibliothèque PHP comme Go! AOP: Enfin, j'ai vérifié que les classes Magento doivent être chargées par l'autochargeur du compositeur, et pas seulement une disponible. Flyingmana a fait du travail dans ce domaine mais il n'est certainement pas prêt pour une utilisation en production et mes besoins sont plus immédiats. Je veux également expédier en tant qu'extension, et cela nécessiterait plus de configuration du compositeur.

Je veux ajouter ça Go! Le framework AOP peut fonctionner sans compositeur, je peux aider à la configuration (il suffit de créer un problème sur github pour cela). Composer n'est nécessaire que pour une intégration transparente avec des applications modernes.

Remplacez simplement un include $filenameou require $filenamedans votre bootstrap par include FilterInjectorTransformer::rewrite($filename)et configurez un chargeur automatique pour Go! AOP lui-même.

lisachenko
la source
1
Wow, sympa. Je vais certainement essayer ça.
Daniel Sloof
0

Optez pour l'approche du chargeur automatique. Renommez / all / classes en lib avec un préfixe:

find lib -name '*.php' -exec sed -e 's,^class ,class Oldlib_,' {} +

Exécutez le "fixateur de remplacement" suivant chaque fois que vous ajoutez un fichier à mylib:

find lib -name '*.php' -print | while read FILE
do
    classname=$(echo ${FILE}|sed -e 's,^lib/,,' -e 's,\.php$,,' -e 's,/,_,g')
    if [ ! -f mylib/${FILE#lib/} ]; then
        # ensure is_a works by providing a stub with correct classname
        echo "class ${classname} extends Oldlib_${classname} {}" > mylib/${classname}.php
    elif [ -f mylib/${classname}.php ]; then
        # we have a new override, but the old file still exists
        rm mylib/${classname}.php
    fi
done

Apprenez à l'autochargeur à retourner mylib/${classname}.phps'il existe et mylib/full/path/to/class.phps'il ne fonctionne pas et s'il existe mylib/full/path/to/class.php.

Mettez vos substitutions mylib/full/path/to/class.phpet étendez la version Oldlib_.

Les mises à niveau annulent simplement le préfixe dans lib / upgrade, réappliquent le préfixe, réexécutez le fixateur de remplacement. Ce qui reste est des choses qui ont été déplacées lib/et qui ont été précédemment remplacées, mais ce n'est pas lié au problème. Votre problème peut être le nombre de fichiers du répertoire mylib /, mais j'espère que vous pouvez résoudre ce problème :).

Melvyn
la source
Cette approche présente de nombreux risques et éléments à maintenir, notamment en ce qui concerne les mises à niveau. Il enfreint également la règle «ne touchez pas au cœur». De plus, ce n'est pas une option viable pour les développeurs d'extensions.
beeplogic
Avec tout le respect que je vous dois, bien que votre solution fonctionne ... elle ne peut pas être considérée comme un a modernmoyen de réécrire des fichiers lib. La programmation impérative est de la vieille école;)
Eddie B
0

Vous pouvez également définir un flux personnalisé et l'ajouter en haut du chemin de chargement automatique. Il fonctionne avec n'importe quel chargeur automatique et nécessite une adoption minimale. Voir l' exemple

KAndy
la source