Magento-Erweiterungen herunterladen und analysieren

Magento Connect bietet leider keine Möglichkeit eine gepackte Erweiterung direkt herunterzuladen, um sie vor der Installation in den Shop analysieren zu können.

Eine Möglichkeit wäre die Erweiterung über freegento.com herunterzuladen. Die andere Möglichkeit bietet Magento selbst: Die Erweiterung kann über den Download-Manager in Ihrer Magento-Testumgebung heruntergeladen und installiert werden. Die gepackte tgz-Datei ist danach im Magento-Verzeichnis unter downloader/.cache/community zu finden!

Unsere Empfehlung für eine sichere Installation von Magento-Erweiterungen:

  1. Reviews und Kommentare auf Magento Connect lesen
  2. Veröffentlichungsdatum der letzten Version der Erweiterung nachschlagen
  3. Automatisch ermittelte Qualität der Erweiterung bei Judge nachschlagen
  4. Die Erweiterung herunterladen (s. o.) und den Code von einem Magento-Entwickler überfliegen lassen, insbesondere nach curl-Aufrufen und externen Ressourcen (darunter externe Logo-Grafiken) Ausschau halten!
  5. In einer Magento-Entwicklungsumgebung installieren und vollständig testen
  6. Produktivumgebung sichern
  7. In die Produktivumgebung übertragen
  8. Cache-Aktualisierung
  9. Vollständiger Test der Produktivumgebung
Veröffentlicht unter Magento Erweiterungen, Tipps und Tricks | Hinterlasse einen Kommentar

Shop während der Entwicklung vor Google-Indizierung und unerwünscheten Besuchern schützen

Mit dem HTTP-Passwort lässt sich der Shop in der Aufbauphase gut vor unerwünschten Besuchern und Indizierung durch Suchmaschinen schützen.

Der etwas umständlichere Weg ist die Einrichtung des HTTP-Passwors über die Server-Konfigurationsdateien .htaccess und .htusers (mehr Details dazu bei SELFHTML).

Da in Magento alle relevanten Anfragen über die index.php abgearbeitet werden (Single Point of Entry), kann der Passwort-Schutz direkt dort umgesetzt werden. Dazu kann am Anfang der index.php nach dem <?php der folgende Code eingebaut werden:

<?php

define('ADMIN_USERNAME','user');
define('ADMIN_PASSWORD','geheim123');

if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']) ||
        $_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME ||$_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD) {

    Header("WWW-Authenticate: Basic realm=\"Magento Development Environment\"");
    Header("HTTP/1.0 401 Unauthorized");
    echo 'Access Denied. ' . time();
    exit;
}

Damit werden Frontend und Backend geschützt. Doch im Backend kann der Flash-Uploader für Produktbilder mit dem Passwortschutz nicht umgehen und meldet den Fehler “Upload HTTP Error”:

Da der Zugang zum Backend bereits geschützt ist, kann er durch eine entsprechende Erweiterung des Codes vom HTTP-Passwortschutz ausgeschlossen werden:

define('ADMIN_URL','admin');
define('ADMIN_USERNAME','user');
define('ADMIN_PASSWORD','geheim123');

if(strpos($_SERVER['REQUEST_URI'], ADMIN_URL) === false) {
    if (!isset($_SERVER['PHP_AUTH_USER']) || !isset($_SERVER['PHP_AUTH_PW']) ||
               $_SERVER['PHP_AUTH_USER'] != ADMIN_USERNAME ||$_SERVER['PHP_AUTH_PW'] != ADMIN_PASSWORD) {

        Header("WWW-Authenticate: Basic realm=\"Magento Development Environment\"");
        Header("HTTP/1.0 401 Unauthorized");
        echo 'Access Denied. ' . time();
        exit;
    }
}
Veröffentlicht unter Fehlerbehebung, Serverkonfiguration, Tipps und Tricks | Hinterlasse einen Kommentar

SEPA-Lastschrift mit DebitPayment

Mit der kostenfreien Erweiterung DebitPayment ist die grundlegende Abwicklung der Zahlung per Lastschrift möglich.

In System > Konfiguration > Verkäufe: Zahlarten > Bankeinzug bietet die Erweiterungen eine reihe praktischer Einstellmöglichkeiten, darunter Anzeige abhängig von der Kundengruppe und Mindest- und Höchstbestellwerte:

Nach der Aktivierung und Umstellung der Art auf SEPA, wird im Checkout die Eingabe der IBAN und BIC möglich:

Die Prüfung der Eingabe findet leider nicht statt. Die Eingabefelder sind zwar als Pflichtfelder eingestellt, doch bereits Eingabe von einem Zeichen in jedes Feld wird akzeptiert:

Die Bankverbindung wird in den Bestelldetails gespeichert. In diesem Fall wurde in jedes Feld ein “.” eingegeben:

Um die Export-Funktionalität zu nutzen, muss unter System > Konfiguration > Verkäufe: Zahlarten > Bankeinzug / Lastschrift die Bankverbindung des Shop-Betreibers eingetragen zu werden:

Danach können SEPA-Lastschrift-Daten in Verkäufe > Lastschrift-Bestellungen im CSV-Format wie folgt exportiert werden:

  1. Bestellungen abgleichen
  2. Nicht exportierte Bestellungen (Status-Spalte) filtern und wählen
  3. CSV-Export

Die Erteilung des SEPA-Mandats müsste der Shop-Betreiber manuell durchführen.

Veröffentlicht unter Empfehlungen | Hinterlasse einen Kommentar

Verteilung der E-Mail-Anbieter unter Newsletter-Abonnenten und Kunden

Beim Versand von Newslettern ist es praktisch zu wissen, welche Email-Anbieter die Kunden verwenden. Die folgende Abfrage extrahiert die Domain des Anbieters und zählt die Email-Adressen der Newsletter-Abonnenten:

SELECT provider_domain AS provider, count(subscriber_email) AS number FROM (
    SELECT
    subscriber_email,
    SUBSTRING_INDEX(subscriber_email, '@', -1) provider_full,
    SUBSTRING_INDEX(SUBSTRING_INDEX(subscriber_email, '@', -1), '.', -2) provider_domain
    FROM newsletter_subscriber
) AS t
GROUP BY provider
ORDER BY number DESC;

Leicht angepasst, kann diese Abfrage auf alle Kunden angewendet werden:

SELECT provider_domain AS provider, count(email) AS number FROM (
    SELECT
    email,
    SUBSTRING_INDEX(email, '@', -1) provider_full,
    SUBSTRING_INDEX(SUBSTRING_INDEX(email, '@', -1), '.', -2) provider_domain
    FROM customer_entity
) AS t
GROUP BY provider
ORDER BY number DESC;

Weiter optimiert, fasst die Anfrage Anbieter mit weniger als 50 Email-Adressen in eine Zeile mit dem Eintrag “OTHER” zusammen:

SELECT provider, SUM(number) number FROM (
SELECT IF(number < 50, '* OTHER', provider) provider, number FROM (
  SELECT provider_domain provider, GROUP_CONCAT(DISTINCT provider_full) domains, COUNT(email) AS number FROM (
    SELECT
    email,
    SUBSTRING_INDEX(email, '@', -1) provider_full,
    SUBSTRING_INDEX(SUBSTRING_INDEX(email, '@', -1), '.', -2) provider_domain
    FROM customer_entity
  ) AS t
  GROUP BY provider_domain
) AS v
) AS w
GROUP BY provider
ORDER BY number DESC;

Einige Anbieter-Domains (z.B. gmail und googlemail) sollten noch manuell zusammengefasst werden.

Um auch noch die Summe anzeigen zu lassen, kann WITH ROLLUP verwendet werden. Um die Liste absteigend sortiert zu lassen, ist allerdings eine weitere Schachtelung nötig:

SELECT IF(provider IS NULL, '* TOTAL', provider) provider, number FROM (
SELECT provider, SUM(number) number FROM (
SELECT IF(number < 50, '* OTHER', provider) provider, number FROM (
  SELECT provider_domain provider, GROUP_CONCAT(DISTINCT provider_full) domains, COUNT(email) AS number FROM (
    SELECT
    email,
    SUBSTRING_INDEX(email, '@', -1) provider_full,
    SUBSTRING_INDEX(SUBSTRING_INDEX(email, '@', -1), '.', -2) provider_domain
    FROM customer_entity
  ) AS t
  GROUP BY provider_domain
) AS v
) AS w
GROUP BY provider
WITH ROLLUP
) AS x
ORDER BY number DESC
Veröffentlicht unter Reports | Hinterlasse einen Kommentar

Varnish und Google Analytics

Links mit Analytics-Kamagnen-Parametern werden in der Standard-Konfiguration von Varnish nicht als Seiten mit identischem Inhalt erkannt. Die beiden nachfolgenden URL werden von Varnish als verschiedene Seiten erkannt und deshalb unabhängig voneinander gecacht:

  1. URL: http://xonu.de
  2. URL: http://xonu.de?utm_campaign=ny2014&utm_medium=banner&utm_source=extern

Während die erste URL von einem Cache-Warmer vorbereitet wird, ist die zweite URL dem Cache-Warmer typischerweise nicht bekannt, sodass der erste Besucher etwas länger auf die Inhalte warten muss, obwohl sie aus dem Cache hätten geliefert werden können.

Damit dies geschieht, muss Varnish mitgeteilt werden, dass Analytics-Parameter den Inhalt nicht verändern. Varnish berechnet einen Hash basierend auf der angefragten URL. Diese URL kann in vcl_recv vor der Berechnung des Hashs manipuliert werden.

Durch Entfernen aller Analytics-Parameter aus der URL wird dem Varnish mitgeteilt, dass sie die Inhalte nicht verändert, sodass für die erste und zweite URL gleiche Inhalte ausgeliefert werden können.

In vcl_recv wird der folgende Zusatzblock hinzugefügt:

sub vcl_recv {

  if (req.url ~ "(\?|&)(utm_[^=]+)=") {
    set req.url = regsub(req.url, "\\\?", "?");
    set req.url = regsuball(req.url, "&(utm_[^=]+)=([^&]+)", "");
    set req.url = regsuball(req.url, "\?(utm_[^=]+)=([^&]+)", "?");
    set req.url = regsub(req.url, "\?&", "?");
    set req.url = regsub(req.url, "\?$", "");
  }

  ....

}

Alle Analytics-Parameter (s. Analytics URL Builder) starten mit “utm_”:

  • utm_source: Kampagnenquelle
  • utm_medium: Kampagnenmedium
  • utm_term: Kampagnenbegriff
  • utm_content: Kampagnen-Content
  • utm_campaign: Kampagnenname

Wird also ein solcher Parameter erkannt, wird die URL davon bereinigt:

  • Zeile 4 ersetzt /? durch ? (ohne Slash).
  • Zeile 5 entfernt Analytics-Parameter, die nicht an erster Stelle stehen. In URL 2 werden hierdurch &utm_medium=banner und &utm_source=extern entfernt.
  • Zeile 6 entfernt Analytics-Parameter, die an erster Stelle stehen. In URL 2 wird dadurch ?utm_campaign=ny2014 entfernt.
  • Zeile 7 entfernt das überflüssige &-Zeichen, wenn die URL neben Analytics nicht weitere GET-Parameter an nicht-erster Stelle enthalten hatte (aus ?utm_campaign=ny2014&p=2 wäre ohne dieser Zeile ?&p=2 geworden).
  • In dem Fall, dass alle GET-Parameter in der URL Analytics-Parameter waren, entfernt die Zeile 8 das übrig gebliebene ?-Zeichen.

Da die Auswertung der Kampagnen-Parameter durch den Analytics-Tracker Client-seitig durch JavaScripte geschieht, bleibt das Tracking davon unbetroffen.

Veröffentlicht unter Performance Optimierung | Hinterlasse einen Kommentar

Update auf 1.8.1 und Kunden können sich nicht mehr einloggen, Magento-Frontend-Login funktioniert nicht mehr

Berichte häufen sich, dass das Frontend-Login nach Update auf Magento 1.8.1 nicht mehr funktioniert, d. h. nach Eingabe der richtigen Login-Daten wird ohne Fehlermeldungen erneut das Login-Formular angezeigt, während bei Eingabe falscher Benutzerdaten eine entsprechende Fehlermeldung angezeigt wird.

In einem Shop konnten wir den Fehler durch Hinzufügen des folgenden hidden-Felds in das Login-Formular beheben:

<input type="hidden" name="form_key" value="<?php echo Mage::getSingleton('core/session')->getFormKey(); ?>" />

Pfad der zu bearbeitenden Template-Datei:

app/design/frontend/base/default/template/persistent/customer/form/login.phtml

Der Code kann direkt in der nächsten Zeile nach nach <form …> eingefügt werden. Vor dem Neuladen des Formulars im eigenen Browser kann das Löschen von Cookies hilfreich sein.

Über FireBug können dabei gezielt die Cookies der Shop-Domain gelöscht werden:

Veröffentlicht unter Fehlerbehebung | 4 Kommentare

Texthinweise im Magento-Checkout: Statische Blöcke oberhalb und unterhalb der Zusammenfassung einbauen

Diese Anleitung zeigt, wie man eigene Texthinweise im letzten Checkout-Schritt anzeigen lassen kann. Die Inhalte werden über statische Blöcke verwaltet, die dann über ein Layout-Update eingebunden werden.

Wir gehen davon aus, dass im Shop German Setup verwendet wird, es ist aber keine Voraussetzung. Wir wollen oberhalb der Zusammenfassung “Bei Zahlungseingang vor 15:00 Uhr erfolgt die Lieferung noch am gleichen Tag.” und unterhalb “Bei Lieferungen in das Nicht-EU-Ausland fallen zusätzliche Zölle, Steuern und Gebühren an.” anzeigen. Der zweite Hinweis ist für das Bestehen der TrustedShops-Zertifizierung erforderlich.

Der nachfolgende Screenshot demonstriert das Ergebnis:

Texte als statische Blöcke

Statische Blöcke lassen sich im Backend bequem verwalten. Deshalb sollen die beiden Hinweise als statische Blöcke angelegt werden. Wir legen zwei statische Blöcke mit den folgenden Bezeichnern an (die Namen wurden frei gewählt):

  • checkout_review_before
  • checkout_review_after

Der Inhalt des Blocks checkout_review_before ist:

<div style="border-color: #D9DDE3; border-style: solid; border-width: 0 1px; padding: 7px;">
Bei Zahlungseingang vor 15:00 Uhr erfolgt die Lieferung noch am gleichen Tag.
</div>

Der Inline-Style wurde aus der CSS-Regel-Definition für .opc .checkout-agreements aus styles.css übernommen, der CSS-Datei des Magento-Base-Themes. Die Gestaltung sorgt für die Fortsetzung des hellgrauen Rahmens und des Abstands des Texts vom Rand.

Der Inhalt des Blocks checkout_review_after ist:

<div style="border-width: 0 2px; border-style: none solid; padding-left: 10px;">
Bei Lieferungen in das Nicht-EU-Ausland fallen zus&auml;tzliche Z&ouml;lle, Steuern und Geb&uuml;hren an.
</div>

Auch hier sorgt der Inline-Style für die Fortsetzung des schwarzen Rahmens, der nach der Button-Lösung vorgeschrieben und für das Bestehen der TrustedShops-Zertifizierung erforderlich ist.

Der schwarze Rahmen wird von German Setup in skin/frontend/base/default/css/germansetup/checkout.css gestaltet. Der Inline-Style wurde von dort übernommen.

Statische Blöcke über Layout-Update im Checkout anzeigen

Über ein Layout-Update, ganz ohne Template-Anpassung, lassen sich statische Blöcke in Checkout-Schritte integrieren. Die vorher angelegte statische Blöcke können mit dem folgenden XML-Layout-Code oberhalb und unterhalb des letzten Checkout-Schritts eingebaut werden:

<?xml version="1.0"?>
<layout version="0.1.0">

    <checkout_onepage_review>
        <reference name="checkout.onepage.review.info.items.before">
            <block type="cms/block" name="checkout_review_before_block" before="-">
                <action method="setBlockId">
                    <block_id>checkout_review_before</block_id>
                </action>
            </block>
        </reference>

        <reference name="checkout.onepage.review.info.items.after">
            <block type="cms/block" name="checkout_review_after_block" after="-">
                <action method="setBlockId">
                    <block_id>checkout_review_after</block_id>
                </action>
            </block>
        </reference>
    </checkout_onepage_review>

</layout>

Der XML-Layout-Code wird in der Datei local.xml in app/design/frontend/default/default/layout/ oder im entsprechenden Theme-Verzeichnis gespeichert. Legen Sie die Datei an, falls sie noch nicht existiert.

Der Layout-Handle checkout_onepage_review und die beiden referenzierten Blöcke checkout.onepage.review.info.items.before und checkout.onepage.review.info.items.after werden in app/design/frontend/base/default/layout/checkout.xml erstmalig definiert und von German Setup in germansetup.xml (gleiches Verzeichnis) noch weiter modifiziert. Diese Anleitung wird also auch ohne installierten German Setup funktionieren.

Die beiden statischen Blöcke werden über XML-Layout-Code definiert. Da die Blöcke checkout.onepage.review.info.items.before und checkout.onepage.review.info.items.after als Strukturblöcke definiert wurden (type=core/text_list), werden die Inhalte aller untergeordneten Blöcke, also auch der statischen Blöcke, ausgegeben.

Nach dem Update des Layout-Cache in System > Cache Verwaltung sind die beiden Blöcke im Checkout sichtbar.

 

Weiterlesen:

Veröffentlicht unter Tutorials | Verschlagwortet mit , , , | Hinterlasse einen Kommentar

Google Sitemaps und internationale Magento-Shops mit mehreren Domains

Google Webmaster Tools helfen die Indizierung eines Shops zu überwachen und zu kontrollieren. Wenn Sie einen internationalen Magento-Shop betreiben/einrichten, der unter verschiedenen Top-Level-Domains erreichbar sein soll, müssen einige Details bei der Verwaltung von Sitemaps beachtet werden.

Die sitemap.xml ist dabei sehr hilfreich und kann von Magento automatisch erstellt werden: Katalog > Google Sitemap.

Auch wenn Magento bei der Sitemap-Erstellung ein Feld für den Dateinamen anbietet, muss die XML-Datei unbedingt sitemap.xml heißen. Bei Verwendung eines anderen Namens, z. B. sitemap_de.xml, bekommt man eine seltsame Fehlermeldung:

Pfad “…” ist nicht verfügbar und kann nicht verwendet werden.

Englische Version:

Path “…” is not available and cannot be used.

Die Sitemaps für die verschiedenen Shops der gleichen Magento-Installation können in verschiedenen Unterverzeichnissen des Shop-Verzeichnisses erstellt werden:

  • sitemap/en/sitemap.xml
  • sitemap/de/sitemap.xml

Die Sitemaps sollen in die robots.txt eingetragen werden:

Sitemap: /sitemap/sitemap.xml

Da unter verschiedenen Shop-Domains die gleiche Datei robots.txt vorliegt, können mehrere Sitemaps in der robots.txt eingetragen werden. Laut sitemaps.org: Sitemaps & Cross Submits muss in diesem Fall der vollständige Domainname eingetragen werden:

Sitemap: http://www.mein-shop.de/sitemap/de/sitemap.xml
Sitemap: http://www.mein-shop.de/sitemap/en/sitemap.xml

Dabei ist es unerheblich, welche der Shop-Domains hier verwendet wird; Auch diese Variante wäre zulässig:

Sitemap: http://www.mein-shop.de/sitemap/de/sitemap.xml
Sitemap: http://www.mein-shop.com/sitemap/en/sitemap.xml

Wenn Sie unter der jeweiligen Shop-Domain jeweils die passende Sitemap unter der gleichen URL verwenden wollen, lässt sich dies über eine .htaccess-Weiche realisieren:

sitemap/.htaccess

RewriteEngine on

RewriteCond %{HTTP_HOST} ^(www.)?mein-shop.de$
RewriteRule sitemap.xml de/sitemap.xml [L]

RewriteCond %{HTTP_HOST} ^(www.)?mein-shop.com$
RewriteRule sitemap.xml en/sitemap.xml [L]

RewriteRule .* / [L]

robots.txt

Sitemap: /sitemap/sitemap.xml

Die beiden Sitemaps befinden sich weiterhin in den Unterverzeichnissen en und de:

  • sitemap/en/sitemap.xml
  • sitemap/de/sitemap.xml
  • sitemap/.htaccess

Mit der .htaccess-Weiche können wir die Sitemap unter http://www.mein-shop.de/sitemap/sitemap.xml und unter http://www.mein-shop.com/sitemap/sitemap.xml (ohne Angabe der Unterverzeichnisse en bzw. de) aufrufen und bekommen die sitemap.xml jeweils aus dem passenden Unterverzeichnis ausgegeben.

Damit die Sitemap regelmäßig automatisch erneuert wird, kann dazu ein Magento-interner Cronjob konfiguriert werden:
System > Konfiguration > Katalog: Google Sitemap > Einstellungen für die Erstellung

Die Voraussetzung, dass die Sitemap dann tatsächlich automatisch erstellt wird, ist der regelmäßige Aufruf der cron.php bzw. cron.sh im Hauptverzeichnis von Magento durch Crontab.

Um Ihren Shop vor DDoS-Attaken durch häufigen Aufruf von cron.php zu Schützen, sollten die Zugriffsrechte der cron.php so konfiguriert sein, dass sie nicht im Browser aufgerufen werden kann. Alternativ kann sie z.B. in cron123.php umbenannt werden (der Inhalt von cron.sh muss angepasst werden).

Gerne beraten und unterstützen wir Sie bei der Suchmaschinenoptimierung Ihres Online-Shops.

Veröffentlicht unter Tutorials | Verschlagwortet mit , , , | Hinterlasse einen Kommentar

JavaScript und CSS über das Layout-XML-Code hinzufügen

Layout XML kann im Backend von Magento in Kategorien, Produkten und CMS-Seiten verwendet werden. XML-Code wird jeweils in das Feld Custom Layout Update im Register Design eingegeben. Das eingegebene Layout-XML-Code gilt dann für das bearbeitete Produkt, die Kategorie oder die CMS-Seite.

Zum Bearbeiten des globalen Layouts sollte in Magento die eigene local.xml im Layout-Verzeichnis app/design/frontend/default/mytheme des aktuellen Themes mytheme angelegt und bearbeitet werden. Alle Befehle müssen sich innerhalb des Knotens layout befinden:

<?xml version="1.0"?>
<layout version="0.1.0">

    ...

</layout>

Im Backend der der Layout-XML-Code ohne diesen Knoten verwendet.

In app/design/frontend/base/default/layout/page.xml ist der Block mit dem Namen head definiert und gibt die Inhalte des HTML-Bereichs <head> aus. Mit der Block-Methode addItem() kann diesem Bereich ein JavaScript oder CSS hinzugefügt werden. Die Methode erwartet zwei Parameter: Pfad-Typ und den Dateinamen relativ zum Pfad-Typ.

Vordefinierte Pfad-Typen:

  • js: js/*.js
  • skin_js: skin/*/*.js
  • js_css: js/*.css
  • skin_css: skin/*/*.css

Quelle: Mage_Page_Block_Html_Head::getCssJsHtml()

Es sind noch weitere Alias-Methoden definiert, die jeweils addItem() mit einem bestimmten Pfad-Typ aufrufen. Folgende Alias-Methoden sind in Mage_Page_Block_Html_Head vorhanden:

  • addCss: ruft addItem mit dem type=skin_css
  • addJs: ruft addItem mit dem type=js
  • addCssIe: ruft addItem mit dem type=skin_css und dem parameter IE
  • addJsIe: ruft addItem mit dem type=js und dem parameter IE

Die local.xml, die dem HTML-Bereich <head> custom.css aus dem Verzeichnis skin/frontend/default/mytheme/css hinzufügt, würde wie folgt aussehen:

<?xml version="1.0"?>
<layout version="0.1.0">

    <default>

        <reference name="head">
            <action method="addItem">
                <param1>skin_css</param1>
                <param2>css/custom.css</param2>
            </action>
        </reference>

    </default>

</layout>

Alternativ kann die Alias-Methode addCss verwendet werden:

<?xml version="1.0"?>
<layout version="0.1.0">

    <default>

        <reference name="head">
            <action method="addCss">
                <param1>css/custom.css</param1>
            </action>
        </reference>

    </default>

</layout>

Die beiden Layout-XML-Codes führen zum gleichen Ergebnis; Sie fügen dem HTML-Bereich <head> auf allen von Magento generierten Seiten die folgende Zeile hinzu:

<head>
...
   <link rel="stylesheet" type="text/css" href="http://domain.tld/skin/frontend/default/mytheme/css/custom.css" media="all" />
...
</head>

Die Alias-Methode addCssIe würde diese Zeilen erzeugen:

<head>
...
<!--[if IE]>
<link rel="stylesheet" type="text/css" href="http://domain.tld/skin/frontend/default/mytheme/css/custom.css" media="all" />
<![endif]-->
...
</head>

Layout-Handles definieren den Kontext, in dem die Layout-Befehle gelten sollen. Das in den Beispielen verwendete Layout-Handle default bezieht sich auf alle Seiten. Neben diesem werden die folgende Handles bei Magento mit zusätzlichem Layout-Code erweitert:

  • catalog_product_view – Alle Produkt-Detailseiten
  • catalog_category_default – Alle Kategorien
  • catalog_category_layered – Alle Ankerkategorien
  • cms_index_defaultindex – Startseite

Mit dem folgenden Layout-XML-Code kann allen Produkt-Detailseiten ein JavaScript aus dem Skin-Verzeichnis des aktuellen Themes mytheme hinzugefügt werden:

<?xml version="1.0"?>
<layout version="0.1.0">

    <catalog_product_view>

        <reference name="head">
            <action method="addItem">
                <param1>skin_js</param1>
                <param2>js/custom.js</param2>
            </action>
        </reference>

    </catalog_product_view>

</layout>

Das Ergebnis wäre die folgende Zeile im HTML-Bereich <head> auf jeder Produktseite:

<head>
...
   <link rel="stylesheet" type="text/css" href="http://domain.tld/skin/frontend/default/mytheme/js/custom.js" media="all" />
...
</head>
Veröffentlicht unter Entwicklung | Hinterlasse einen Kommentar

Nachbesserung der Rundungsfehlerkorrektur in Magento und PayPal

Rounding Error Fix for Magento and PayPal 1.0.4 auf Magento ConnectRounding Error Fix for Magento and PayPal

Nach der Veröffentlichung unserer Erweiterung, die den Rundungsfehler ausschließlich durch bedingte Erhöhung der Rundungsgenauigkeit korrigieren sollte, wurden uns Konstellationen berichtet, in den der Fehler weiterhin auftritt.

In unserer bisherigen Lösung haben wir die Manipulation der Beträge durch Addition oder Subtraktion des Rundungsfehlers vermieden.

Um sicherzustellen, dass die Warenkorbdaten nach PayPal so übertragen werden, dass die Schlüsselbeträge mit den der Bestellung in Magento übereinstimmen, haben wir uns entschieden nun doch die Formulardaten des PayPal-Moduls zu manipulieren!

Wir erweitern die Methode Mage_Paypal_Model_Api_Standard::getStandardCheckoutRequest, die die Formulardaten für PayPal-Zahlungen bereitstellt. Die Schlüsselbeträge sind die Mehrwertsteuer und der Gesamtbetrag. Da die Nettopreise einzelner Artikel und der Versandkosten nicht direkt in der Magento-Bestelung zu sehen sind, wird die Anpassung dieser Werte nicht auffallen.

Für die Anpassung der Formulardaten gehen wir wie folgt vor:

  • Vergleiche den für PayPal vorbereiteten Gesamtwert mit dem Gesamtwert der Bestellung: Beträgt die Differenz der beiden Werte nicht Null, wird der Rundungsfehler korrigiert. Aufgrund der in Magento bereits vorhandener Logik für die Korrektur des Rundungsfehlers, nehmen wir an, dass der gerundete Rundungsfehler +0.01 oder -0.01 betragen kann.
  • Rekonstruiere die Schlüsselwerte des PayPal-Formulars aus den Bestelldaten: Netto-Gesamtwert der Bestellung, Mehrwertsteuerbetrag, Netto-Versandkosten. Zusätzlich werden noch die Brutto-Versandkosten berechnet, um festzustellen, ob hier ein Rundungsfehler vorliegt.
  • Korrigiere den Rundungsfehler durch Anpassung von: Netto-Versandkosten oder des Netto-Preises des letzten Warenkorbartikels oder des Mehrwertsteuerbetrags. Die Anpassung wird im ersten dieser Schlüsselwerte vorgenommen, bei dem ein Rundungsfehler, berechnet im vorigen Schritt, vorliegt. Aus der Magento-eigenen Rundungsfehlerkorrektur ist uns nicht bekannt, wie der Rundungsfehler des letzten Warenkorbartikels verwendet wird. Deshalb erscheint es uns sinnvoll für die Rundungsfehlerkorrektur den Netto-Preis des letzten Warenkorbartikels anzupassen.

Es folgt die Methode, die die Rundungsfehlerkorrektur implementiert:

public function getStandardCheckoutRequest()
{
    // calculate the rounded request total
    $request = parent::getStandardCheckoutRequest();
    $requestBaseGrandTotal = round($request['amount'] + $request['tax'] - $request['discount_amount'], 2);

    // get the rounded order total
    $orderObj = Mage::getSingleton('sales/order')
                ->loadByIncrementId(Mage::getSingleton('checkout/session')->getLastRealOrderId());
    $orderBaseGrandTotal = round($orderObj->getBaseGrandTotal(), 2);

    // get the rounded rounding error
    $roundingError = round($orderBaseGrandTotal - $requestBaseGrandTotal, 2); // -0.01 or +0.01

    // fix the rounding error
    if($roundingError) {
        $order = array(); // create an array from order data resembling the structure or the request array
        $roundingDeltas = array(); // save the rounding error

        $order['amount'] = round($orderObj->getBaseSubtotal() + $orderObj->getBaseShippingAmount(), 2);
        $roundingDeltas['amount'] = ($orderObj->getBaseSubtotal() + $orderObj->getBaseShippingAmount()) - $order['amount'];

        $order['tax'] = round($orderObj->getBaseTaxAmount(), 2);
        $roundingDeltas['tax'] = $orderObj->getBaseTaxAmount() - $order['tax'];

        $order['shipping'] = round($orderObj->getBaseShippingAmount(), 2);
        $roundingDeltas['shipping'] = $orderObj->getBaseShippingAmount() - $order['shipping'];

        // not contained in the request but useful to determine if there is a rounding error in shipping
        $order['shipping_incl_tax'] = round($orderObj->getBaseShippingAmount() + $orderObj->getBaseShippingTaxAmount(), 2);
        $roundingDeltas['shipping_incl_tax'] = ($orderObj->getBaseShippingAmount() + $orderObj->getBaseShippingTaxAmount()) - $order['shipping_incl_tax'];

        $orderTotalItemCount = $orderObj->getTotalItemCount();

        // hide rounding error in shipping
        if($roundingDeltas['shipping_incl_tax'] && $order['shipping'] > 0) {
            if(isset($request['amount_'.($orderTotalItemCount+1)])) { // ensure that the shipping item is there
                $request['amount_'.($orderTotalItemCount+1)] += $roundingError;
            }
            $request['shipping'] += $roundingError;
            $request['amount'] += $roundingError;

        // hide rounding error in the last cart item
        } elseif($roundingDeltas['amount'] && $order['amount'] > 0) {
            if(isset($request['amount_'.($orderTotalItemCount+1)])) {
                $request['amount_'.($orderTotalItemCount+1)] += $roundingError;
            }
            $request['amount'] += $roundingError;
        } else {
            // hide rounding error in tax
            if($order['tax'] > 0) {
                $request['tax'] += $roundingError;
                $request['tax_cart'] += $roundingError;
            } else {
                // do not correct rounding error in this unexpected situation
            }
        }

    }
    return $request;
}

Rounding Error Fix for Magento and PayPal 1.0.4 auf Magento ConnectRounding Error Fix for Magento and PayPal

Veröffentlicht unter Fehlerbehebung | Verschlagwortet mit , , , , , , , , | 2 Kommentare