Wanneer moet ik de kernklassen van Magento uitbreiden, welke XML-structuur moet ik wijzigen om mijn wijzigingen door te voeren?

Ik werk met een Magento 1.3 (Community Edition) -installatie en probeer de functionaliteit van een van de kernklassen uit te breiden. Ik heb het kernbestand rechtstreeks op een ontwikkelserver gewijzigd en de functionaliteit daar gebruikt. Nu, naar aanleiding van Alan Storm's advies , zet ik de kernbestanden terug naar de stock en implementeer ik mijn wijzigingen in de /app/code/local boom. Ik heb Alan Storm's pagina gelezen en een gids van Josh Pratt , maar ik kan er niet helemaal achter komen hoe ik die voorbeelden in mijn geval moet toepassen.

De kern van de vraag is - hoeveel van het skelet van een volledige Magento-module moet ik implementeren om core-klassen met apen te verlengen?

  • Moet ik mijn eigen naamruimte maken?
  • Wanneer ik klassen een naam geef, welke onderstrepingstekens moet ik dan verwachten dat deze syntactisch significant zijn?
  • Wanneer ik de xml schrijf, welke tags komen overeen met de klassehiërarchie en welke niet?
  • Welke andere delen van de code moeten worden gewijzigd om te profiteren van mijn eventuele wijzigingen?

Eigenlijk zou ik dit niet willen cultiveren.

The particulars of my scenario: I'm trying to alter the product review functionality of Magento. The code for this functionality lives in /app/code/core/Mage/Review/. I'm adding an additional step to the server-side validation when new reviews are submitted (our store is having a spam issue, so I'm adding an extra form field, hiding it from humans with CSS, and throwing out reviews that fill in that form field; I'm doing it this way because CAPTCHAs are a sub-optimal UI choice). I added code to /app/code/core/Mage/Review/controllers/ProductController.php's Mage_Review_ProductController->postAction() method and to /app/code/core/Mage/Review/Model/Review.php's Mage_Review_Model_Review->validate() method.

Ik isoleerde de toegevoegde code vervolgens, plaats deze in /app/code/local/Mage/Review/controllers/ProductController.php en /app/code/local/Mage/Review/Model/Review.php , gebruikt de aanbevelingen "class My_Review_Foo extends Mage_Review_Foo" en "parent :: method" uit de tutorials van Alan Storm. Dat, voorspelbaar, brak de productpagina's. Dus ik ben bezig met /app/code/local/Mage/Review/etc/config.xml en probeer uit te vinden hoe Magento mijn klassen kan gebruiken om extend de kernklassen. Helaas kan ik niet zeggen wat de onderliggende logica van de xml is, dus ik kan niet achterhalen hoe ik de juiste xml moet maken om Magento te vertellen - "gebruik mijn klassen in plaats van de kernklassen, wanneer u de kernklassen zou gebruiken ."

Het lijkt erop dat vrijwel elke verandering in de kernklassen uiteindelijk de volledige pracht en praal van een Magento-plug-in vereist. Is dat correct? Hoeveel moet ik eigenlijk doen om mijn veranderingen in te vullen, en wat is de logica achter het op die manier doen?

2

1 antwoord

Bij Magento draait alles om configuratie. De eenvoudigste functionele module die er is, zal niets anders bevatten dan configuratie-XML die bestaande configuratie-XML toevoegt of overschrijft. Dat gezegd hebbende, vereisen de meeste ontwikkelingsbehoeften implementatie-configuratie die afzonderlijke nieuwe functionaliteit toevoegt aan het systeem en/of bestaande functionaliteit verandert.

Er zijn twee manieren om het blok te herschrijven (wat overeenkomt met de "view" in MVC), helper en modelklassen, en deze werken vanwege de pad-volgorde (ingesteld in de Mage -hubklasse en gebruikt door Varien_Autoload ), of - meer geschikt - via op configuratie gebaseerde herschrijvingen, die worden geëvalueerd in de Mage_Core_Model_Config :: getGroupedClassName() -methode. Zie hieronder voor herschrijfinstructies gebaseerd op het herschrijven van Mage_Review_Model_Review .

By design (as a security feature) neither of these approaches works for controllers; ultimately the controller class definitions are protected from being autoloaded. What follows then is an explanation on how to rewrite action controller classes by non-deprecated means (1.3.0 to 1.6.1.1 at this time). Note that prior to Magento CE 1.3.0, the way to rewrite functionality in action controller classes was via configuration XML.

To rewrite controller definitions one must understand how controller classes are invoked in Magento, and this occurs through the router classes. Magento core has four router classes. Routers sit between the FrontController class (Mage_Core_Controller_Front), and they are responsible for matching the request and altering the response body. The FrontController will loop through each class, and each class will be evaluated to determine whether it should handle the current request. Often this is a matter of configuration + filepath convention. Essentially, Magento matches a frontname to an initial directory and then matches the rest of the request to a path and file under that directory. For example, a product page's literal path in the application may be http://demo.magentocommerce.com/review/product/list/id/51/. In this URL structure, review is the frontName (a node from the configuration), and it is mapped to app/code/core/Mage/Review/controllers/. From there, product maps to a path & filename under that directory, i.e. ProductController.php, and from there the resolved class is checked for a listAction method. See? review + product + list are the frontName, controller class path, and method "resolution params". Anything after that is passed as a request param (e.g. id=51).

Sinds CE 1.3.0 is het mogelijk om eenvoudig een actiecontroller klasse toe te voegen aan een lijst met mappen waarin de router zal controleren of er paden zijn die kunnen worden herleid (zie Mage_Core_Controller_Varien_Router_Standard :: collectRoutes() voor meer info). Hoe dit werkt is typisch Magento: via config XML! Overigens werkt deze techniek zowel voor het toevoegen van nieuwe controller-klassenpaden als voor controllerherschrijvingen.

Een controller herschrijfmodule heeft minimaal drie bestanden nodig:

  • een module-declaratiebestand (een bestand eindigend in .xml onder de app/etc/modules/ map)
  • een config.xml in de map etc van de module
  • een controllerbestand met dezelfde padresolutie als de klasse die wordt herschreven . In het geval van een klassenpad van "product" uit het bovenstaande voorbeeld, moet het bestand de naam ProductController.php hebben en zich boven aan de controllersdirectory bevinden die wordt toegevoegd, anders zal het niet overeenkomen met de params van de klassenresolutie. Ook moet de actie die wordt herschreven om dezelfde reden overeenkomen met het origineel.

Het aangiftebestand bevat het volgende:

<?xml version="1.0" ?>

    
        
            true
            local <!-- or community -->
        
    

Based on the above and nodes, the application will attempt to load app/code/local/Example/Extension/etc/config.xml. In this file, if one were seeking to rewrite the Review module's ProductController class, one would need the following:

<?xml version="1.0" ?>

    
        
            
                
                    
                        Example_Extension
                        <!--
                            This will map to the controllers directory under the
                            app/code/local/Example/Extension/ directory. Had this
                            value been "Example_Extension_Rewrites", the mapping
                            would be to the
                            app/code/local/Example/Extension/controllers/Rewrites/
                            directory. That is just how controller class paths are
                            evaluated: with a "controllers" directory after two levels
                            of folders.
                        -->
                    
                
            
        
    

Vanwege het kenmerk before = "Mage_Review" wordt de controllers-directory van de Example_Extension-module toegevoegd vóór de controlemap van de hoofdcontrolemodule-controller. Als de params van de controller en de actie-resolutie overeenkomen in de module Example_Extension, wordt daarom de klasse ervan gebruikt. Zo niet, dan speelt het standaardscenario zich af.

Ten slotte is het resterende bestand dat moet worden gemaakt de klasse van de actiecontroller zelf. Als het de bedoeling is om te erven van de kernfunctionaliteit, dan is het zinvol om uit te breiden van de kernklasse. Om ervoor te zorgen dat de PHP de definitie laadt voor de kernklasse, moet er direct naar de kernklasse worden verwezen omdat PHP geen manier heeft om de definitie te vinden via de autoloader zoals vermeld. Dit betekent dat een require_once vóór de herschreven klassedefinitie wordt toegevoegd.

<?php

require_once 'Mage'.DS.'Review'.DS.'controllers'.DS.'ProductController.php';

class Example_Extension_ProductController extends Mage_Review_ProductController
{
    //rewritten and/or new method(s)
}

Net zoals het geval is met blok-, helper- en modellessen in Magento, verwacht de toepassing dat klassen een specifieke naam hebben die betrekking heeft op hun locatie in het bestandssysteem.

Met betrekking tot herschrijvingen van model (en blok en helper): er hoeft alleen de noodzakelijke configuratie-XML en klassedefinitie te worden toegevoegd. Gezien de voorbeelden hier, zou een herschrijving van Mage_Review_Model_Review een toevoeging moeten zijn aan de config.xml van Example_Extension:


    <!-- ... -->
    
        
            
                
                    Example_Extension_Model_Review
                
            
        
    

Based on this, Mage::getModel('review/review') (or Mage::getSingleton('review/review')) will internally map to the classname given in the node and will return the rewritten class instance. Due to how the autoloader works (see Varien_Autoload at lib/Varien/Autoload.php), that class definition will need to be located at Example/Extension/Model/Review.php and should be under the codePool specified in the Example_Extension's declaration file.

Ik hoop dat dit helpt. Voor meer informatie, voel je vrij om te kijken naar andere berichten op SO evenals Magento U.

6
toegevoegd
Dat was een indrukwekkend grondig antwoord. Dank je! Dat soort antwoorden is een geweldige evangelisatie voor Magento. :)
toegevoegd de auteur Brighid McDonnell, de bron