Git Product home page Git Product logo

shoppingcart's Introduction

ShoppingCart - REDAXO Warenkorb AddOn

Ein flexibles, modernes Warenkorb-Framework (ohne Bezahlprozess)

Voraussetzungen

  • REDAXO >= 5.1.0
  • PHP >= 5.6.0

Installation

  • Release herunterladen und entpacken.
  • Ordner umbenennen in shoppingcart.
  • In den Addons-Ordner legen: /redaxo/src/addons.

Oder den REDAXO-Installer / ZIP-Upload AddOn nutzen!

Navigation

Warenkorb

Einen neuen Warenkorb erstellen

Um eine neue Warenkorb-Instanz zu erstellen, musst du eine ID und eine Storage Implementation übermitteln. Wie man eigene Storage Implementationen zur Verfügung stellt, erfährst du am Ende der README.

/*
    die beiden Parameter sind optional, per Default wird die SessionID und die SessionStore Implementation genutzt.
    möchtest du mehrere Warenkörbe pro User gleichzeitig zur Verfügung stellen, solltest du immer eine eigene ID übergeben.
    public static function factory($cartId = null, $storageImplementation = 'Cart\Storage\SessionStore')
    Möchtest du den CookieStore nutzen, bitte "Cart\Storage\CookieStore" nutzen. Der CookieStore überlebt auch neue Sessions.
*/
$cart = ShoppingCart::factory($id, $cartSessionStore);

Die Storage Implementation muss Cart\Storage\Store implementieren. Die Id wird zum Speichern / Wiederherstellen der Warenkorb-Storage Implementation genutzt.

Aktuell gibt es

  • Cart\Storage\SessionStore
  • Cart\Storage\CookieStore
  • Cart\Storage\MemcachedStore
  • Cart\Storage\MemcacheStore
  • Cart\Storage\RedisStore

Unter Warenkorb Storage Implementation wird noch mal genauer erklärt, wie Memcache(d) und Redis konfiguriert werden können.

Einen Artikel zum Warenkorb hinzufügen

Benutze die add Methode um einen Artikel zum Warenkorb hinzuzufügen. Ein gültiges Cart\CartItem muss der Methode übergeben werden. Der Namespace wird bereits automatisch von ShoppingCartItem gesetzt, nur interessant, falls du den Wrapper nicht nutzen möchtest. (siehe vendor-lib)

$item = new ShoppingCartItem;
$item->name = 'Macbook Pro';
$item->sku = 'MBP8GB';
$item->price = 1200;
$item->tax = 200;
// du kannst unbegrenzt eigene Keys mit eigenen Werten hinzufügen, z.B
// $item->description = "Meine Beschreibung zu diesem Artikel"; 
// bitte beachte, das Price und Tax nur gültige Zahlen erwarten

// hier die Warenkorb Instanz nutzen um den Artikel hinzuzufügen
$cart->add($item);

Wenn der Artikel bereits im Warenkorb existiert, wird die Menge um 1 erhöht.

Einen Artikel aus dem Warenkorb entfernen

Um einen Artikel aus dem Warenkorb zu entfernen, musst du die interne, vom AddOn generierte Item-Id nutzen und die remove Methode aufrufen.

$cart->remove('e4df90d236966195b49b0f01f5ce360a356bc76b');
// diese ID ist nicht deine Datenbank-ID oder Artikel-Id, sondern die Warenkorb-Item-Id. 
// du kommst an diesen Wert über $item->getId() (z.B. in deiner Warenkorb-Ausgabe, als hidden input-feld oder auf einen "Mülleimer-Icon"

Artikel im Warenkorb aktualisieren

Um eine Eigenschaft eines Artikels im Warenkorb zu ändern, muss die update Methode genutzt werden. Du musst die Warenkorb-Artikel-Id, den Namen der Eigenschaft (der "Key", z.B. price) und den neuen Wert übermitteln. Die Methode wird dir die neue Warenkorb-Artikel-ID als Rückgabe übermitteln (falls es sich durch das Update verändert hat)

$newId = $cart->update('e4df90d236966195b49b0f01f5ce360a356bc76b', 'price', 959.99);

Wenn du versuchst einen Artikel im Warenkorb zu verändern, welcher nicht existiert, wird ein InvalidArgumentException geworfen.

Einen Artikel-Objekt aus dem Warenkorb holen

Hol dir ein Artikel-Objekt aus dem Warenkorb mit der Warenkorb-Artikel-ID und der get Methode. Wenn der Artikel nicht existiert, wird null zurückgegeben.

$item = $cart->get('e4df90d236966195b49b0f01f5ce360a356bc76b');

if ($item) {
    // ...
}

Alle Artikel aus dem Warenkorb holen

Hole alle Artikel aus dem Warenkorb mit der all Methode. Es wird ein array aller Artikel aus dem Warenkorb zurückgegeben.

$cartItems = $cart->all();

if (count($cartItems) > 0) {
    foreach ($cartItems as $item) {
        // ...
    }
}

Prüfen, ob ein Artikel im Warenkorb existiert

Prüft ob ein Artikel im Warenkorb existiert. Nutze dazu die has Methode. Liefert true or false zurück.

if ($cart->has('e4df90d236966195b49b0f01f5ce360a356bc76b')) {
    // ...
}

Den Warenkorb leeren

Leere den Warenkorb mit der clear Methode.

$cart->clear();

Diese Methode leert auch den gespeicherten State für den ausgewählten Warenkorb.

Warenkorb State speichern / wiederherstellen

Du kannst den aktuellen Warenkorb mit der save Methode speichern.

$cart->save();

Die Methode wird die aktuellen Warenkorb-Artikel und Warenkorb-ID in den Store speichern. Du kannst den Warenkorb wiederherstellen, indem du die restore Methode verwendest.

$cart->restore();

Diese Methode wird alle zwischengespeicherten Artikel wieder zum Warenkorb hinzufügen und die Warenkorb-Id setzen. Falls es ein Problem geben sollte, wird ein Cart\CartRestoreException geworfen. Dies passiert nur, wenn:

  • Die gespeicherten Daten nicht serialisiert werden können
  • Die nicht-serialisierten Daten ungülig sind (kein array)
  • Die Warenkorb-Id nicht in den unserialisierten Daten vorhanden ist
  • Die Warenkorb-Artikel nicht in den unserialisierten Daten vorhanden sind
  • Die Warenkorb-ID ungültig ist (kein String)
  • Die Warenkorb-Artikel ungültig sind (kein Array)

Weitere Warenkorb-Methoden

Alle einzigartiken Artikel (totalUniqueItems)

Liefert die gesamte Anzahl der eindeutigen Artikel (ohne Mengen einzelner Artikel) im Warenkorb.

$cart->totalUniqueItems();
Alle Artikel (totalItems)

Liefert die Anzahl aller Artikel (inkl. Mengen) aus dem Warenkorb

$cart->totalItems();
Gesamtsumme (total)

Die Gesamtsumme aller Artikel aus dem Warenkorb inkl. Steuern. (Brutto)

$cart->total();

Du kannst die Gesamtsumme auch Netto (ohne Steuern) aus dem Warenkorb holen. Dazu nutzt du einfach die totalExcludingTax Methode.

$cart->totalExcludingTax();
Steuern (tax)

Die Gesamtsumme der Steuern für alle Artikel im Warenkorb.

$cart->tax();
toArray

Liefert den Warenkorb-Inhalt als array

$cartData = $cart->toArray();

Das Array wird folgendermaßen strukturiert sein:

[
    'id' => 'xxyfwq3235werw23wer...', // Warenkorb-ID
    'items' => [
        // Warenkorb-Artikel als Array
    ]
]
getId

Liefert die ID des Warenkorbs (Default: session_id(), wenn kein eigener Wert übergeben wurde)

$cart->getId();
getStore

Zeigt an, welche Storage Implementation genutzt wurde (Default: SessionStore)

$cart->getStore();

Warenkorb Artikel

Füge einen Artikel zum Warenkorb hinzu

$item = new ShoppingCartItem;

$item->name = 'Macbook Pro';
$item->sku = 'MBP8GB';
$item->price = 1200;
$item->tax = 200;
// oder jeder eigene Key, z.B:
// $item->description = "Meine Beschreibung";
$item->options = [
    'ram' => '8 GB',
    'ssd' => '256 GB'
];

// hier wird erst hinzugefügt, bitte $cart Objekt nutzen.
$cart->add($item);

Cart\CartItem implementiert ArrayAccess so dass die Eigenschaften des Artikels auch wie ein Array behandelt werden können:

$item = new ShoppingCartItem;

$item['name'] = 'Macbook Pro';
$item['sku'] = 'MBP8GB';
$item['price'] = 1200;
$item['tax'] = 200;
// oder $item['description'] oder $item['wasauchimmer']
$item['options'] = [
    'ram' => '8 GB',
    'ssd' => '256 GB'
];

// hier wird erst hinzugefügt, bitte $cart Objekt nutzen.
$cart->add($item);

Die Daten können auch direkt als Array an den Warenkorb-Artikel Konstruktor übergeben werden:

$itemData = [
    'name' => 'Macbook Pro',
    'sku' => 'MBP8GB',
    'price' => 1200,
    'tax' => 200,
    'whatever' => 'Mein Wert',
    'options' => [
        'ram' => '8 GB',
        'ssd' => '256 GB'
    ]
];

$item = new ShoppingCartItem($itemData);

// hier wird erst hinzugefügt, bitte $cart Objekt nutzen.
$cart->add($item);
  • Wird keine Menge (quantity) an den Konstruktor übergeben, wird quantity per default auf 1 gesetzt. Die Menge kann also auch gleich beeinflusst werden.
  • Wird kein Preis (price) übergeben, wird per default 0.00 für den Artikel gesetzt.
  • Wird keine Steuer (tax) übergeben wird per default 0.00 für den Artikel gesetzt. Bitte beachte, dass du die Steuer pro Artikel selbst berechnen musst. Dadurch bist du für jedes Land, jede Steuerart etc. flexibel. Eine einfache, eigene 19 % Berechnung ist auch schnell umgesetzt. Falls du nicht weisst wie, schreib ein Issue.

Warenkorb-Artikel ID

Jeder Artikel hat eine einzigartige ID. Diese ID wird anhand der Artikeleigenschaften automatisch generiert. Du kannst die ID mit der getId Methode oder der Eigenschaft id aufrufen. Die interne ID kann nicht selbst gesetzt werden. Falls du eine Relation zu deiner Datenbank benötigst, kannst du eine eigene Eigenschaft mittels $item->meinIdKey = 'foobar' setzen.

$id = $item->getId();
$id = $item->id;
$id = $item['id'];

Wird eine Eigenschaft (also ein Artikel-Key) geändert, verändert sich auch die interne Artikel-ID.

Warenkorb-Artikel Methoden

get

Hol dir den Wert einer Artikel Eigeschaft über seinen Keynamen.

$name = $item->get('name');

Ist nur eine Abkürzung für:

$name = $item['name'];
$name = $item->name;

set

Setze einen Wert für einen Artikel:

$item->set('name', 'Macbook Pro');

Ist nur eine Abkürzung für:

$item['name'] = 'Macbook Pro';
$item->name = 'Macbook Pro';

Wenn du die Menge (quantity) setzt, muss der Wert ein integer sein, ansonsten wird ein InvalidArgumentException geworfen.

$item->quantity = 1; // ok
$item->quantity = '1' // wird einen Fehler werfen

Wenn du für einen Artikel den Preis oder die Steuer setzt, muss der Wert numerisch (numeric) sein, ansonsten wird ein InvalidArgumentException geworfen.

$item->price = 10.00; // ok
$item->price = '10' // ok
$item->price = 'ten' // wird einen Fehler werfen
getTotalPrice

Liefert den gesamten Preis eines Artikels mit Steuern (Brutto). ((artikel preis + artikel steuer) * menge) [`((item price + item tax) * quantity)]

$item->getTotalPrice();

Du kannst die Gesamtsumme des Artikels auch ohne Steuern ermitteln (Netto). Nutze dazu einfach die Methode getTotalPriceExcludingTax. (item price * quantity)

$item->getTotalPriceExcludingTax();
getSinglePrice

Ermittle den Einzelpreis des Artikels im Warenkorb inkl. Steuern (item price + item tax)

$item->getSinglePrice();

Ohne Steuern nutzt du einfach die getSinglePriceExcludingTax Methode.

$item->getSinglePriceExcludingTax();
getTotalTax

Liefert die Gesammtsumme der Steuern für den gewählten Artikel, abhängig zur Menge (item tax * quantity).

$item->getTotalTax();
getSingleTax

Liefert die Gesamtsumme der Steuern für den gewählten Artikel unabhängig von der Menge.

$item->getSingleTax();
toArray

Liefert den Artikel als Array.

$itemArr = $item->toArray();

Array wird folgendermaßen strukturiert sein:

[
    'id' => 'e4df90d236966195b49b0f01f5ce360a356bc76b', // einzigartike Warenkorb-Artikel-Id
    'data' => [
        'name' => 'Macbook Pro',
        'sku' => 'MBP8GB',
        'price' => 1200,

        // ... weitere Artikel Eigenschaften
    ]
]

Warenkorb Storage Implementation

Ein Warenkorb Storage muss Cart\Storage\Store implementieren.

Das AddOn liefern einige Basis Sicherungs-Implementations: Cart\Storage\SessionStore, Cart\Storage\CookieStore, Cart\Storage\MemcachedStore, Cart\Storage\MemcacheStore, Cart\Storage\RedisStore.

Memcache(d) und Redis laufen Out-of-the-box, wenn die Einstellungen per Default eingestellt sind. Authentifizierung wird nicht unterstützt. Sollte das gewünscht sein, kannst du die Classes unter eigenem Namen duplizieren (zu finden unter lib/Storage). Es kann der Port und der Server eingestellt werden.

    $cart = ShoppingCart::factory($id = null, (new Cart\Storage\MemcachedStore($server, $port, $expireInMillisekunden)))
    $cart = ShoppingCart::factory($id = null, (new Cart\Storage\MemcacheStore($server, $port, $expireInMillisekunden)))
    $cart = ShoppingCart::factory($id = null, (new Cart\Storage\RedisStor($server, $port, $expireInSekunden)))

Wenn die save Methode des Warenkorbs aufgerufen wird, übermittelt das AddOn die Warenkorb-ID und die serialisierten Daten an die put Methode der Storage Implementation.

Wenn die restore Methode des Warenkorbs aufgerufen wird, übermittelt das AddOn die Warenkorb-ID an die get Methode der Storage Implementation.

Wenn die clear Methode des Warenkorbs aufgerufen wird, übermittelt das AddOn die Warenkorb-ID an die flush Methode der Storage Implementation.

Eine Beispiel-Implementation könnte so aussehen (kannst du mit Redis, Memcached, MySQL oder wie auch immer umsetzen. Erstelle einfach eine Klasse dazu und leg diese in deinem project AddOn unter "lib" ab)

use Cart\Store;

class SessionStore implements Store
{
    /**
     * {@inheritdoc}
     */
    public function get($cartId)
    {
        return isset($_SESSION[$cartId]) ? $_SESSION[$cartId] : serialize([]);
    }

    /**
     * {@inheritdoc}
     */
    public function put($cartId, $data)
    {
        $_SESSION[$cartId] = $data;
    }

    /**
     * {@inheritdoc}
     */
    public function flush($cartId)
    {
        unset($_SESSION[$cartId]);
    }
}

Beispiel Modulausgabe

<?php
$cart = ShoppingCart::factory();

$itemData = [
    'name' => 'Macbook Pro',
    'sku' => 'MBP8GB',
    'price' => 1200,
    'tax' => 200,
    'options' => [
        'ram' => '8 GB',
        'ssd' => '256 GB'
    ]
];
$item = new ShoppingCartItem($itemData);
$cart->add($item);

dump($item);

$item = new ShoppingCartItem;
$item->name = 'Macbook Pro';
$item->sku = 'MBP8GB';
$item->price = 1200;
$item->tax = 200;
$item->meinkey = 'is cool';
$cart->add($item);

$cart->update($item->getId(), 'price', 959.99);

dump($item);
dump($item->getId());
dump($cart);
dump($cart->getStore());
dump($cart->getId());
dump($cart->toArray());

Credits

shoppingcart's People

Contributors

hirbod avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

shoppingcart's Issues

ToDo: Checkout Plugin

Das AddOn stellt nur ein flexibles Warenkorb-Framework bereit, jedoch muss man sich um den Bezahlvorgang selbst kümmern. Ich werde das definitiv nicht umsetzen. Ich hab da zwar schon etwas mittels PayPal umgesetzt, aber es ist zu kundenspezifisch. Ich würde mir etwas smartes, flexibles wünschen, aber da muss sich jemand von FOR bereiterklären, Code beizusteuern.

  • PayPal REST SDK mit Express Checkout (sehr einfach zu bauen)
  • PayPal Plus
  • Stripe
  • Micropayment
  • Rechnung (eigene Implementation)
  • SEPA_Lastschrift (mit Mandatsgenerierung, Sepa.XML Erstellung als Export)

Das AddOn könnte ein super Shop-Plugin für REDAXO werden, da der Warenkorb sehr flexibel ist. Ich hab es selbst bereits mehrfach im Einsatz und bin zufrieden.

Jeder Bezahlprozess sollte ein eigenes Plugin sein und als PR übermittelt werden. Ich bezweifle, das jemals ein PR eingeht, aber ich darf ja noch hoffen.

Sollte das Plugin für das saubere Abarbeiten eine Datenbank nutzen müssen, sollte die install.php diese installieren. Die uninstall.php sollte jedoch niemals die erstelle Datenbank löschen. Das sollte zur Sicherheit bedacht werden.

Falls es keine PRs gibt, kann ich auch gerne für einen Job beauftragt werden. Ich würde mich aber über eine Beteiligung am Code eher freuen.

einleitung hilfe

hallo,
ich benötige hier mal eine kurze einleitung.

ich erstelle ein modul für produkte und schreibe die produkt details in den warenkorb

$cart = ShoppingCart::factory();
$item = new ShoppingCartItem;
$item->name = 'Macbook Pro';
$item->sku = 'MBP8GB';
$item->price = 1200;
$item->tax = 200;
$item->meinkey = 'is cool';
$cart->add($item);

nun habe ich ein zweites produkt mit dem gleichen modul mit:

$cart = ShoppingCart::factory();
$item = new ShoppingCartItem;
$item->name = 'Macbook Light';
$item->sku = 'MBP4GB';
$item->price = 900;
$item->tax = 200;
$item->meinkey = 'is cool';
$cart->add($item);

nun möchte ich den warenkorb auslesen mit einem neuen modul

$cart = ShoppingCart::factory();
dump($cart);

allerdings bekomme ich nun mit dem neuen modul keine ausgabe..?
was mache ich falsch?

working help

hallo,
ich brauche eine kurze einleitung im umgang mit dem addon.

ich habe das addon installiert und das demo modul eingebunden.
jetzt habe ich ein zweites modul erstellt und wollte die cart damit auf einer zweiten seite auslesen

$cart = ShoppingCart::factory(); dump($cart->getId()); dump($cart); dump($cart->getStore()); dump($cart->toArray());

die cart Id ist die gleiche wie im demo modul aber es sind keine items enthalten.
was mache ich falsch?

ToDo: Weitere Storage Implementationen

Das AddOn stellt einen CookieStore und SessionStore zur Verfügung. Der CookieStore überdauert einige Tage, der SessionStore eine Browser Session. Die Umsetzung weiterer Stores ist super einfach und dauert wenige Minuten

Man kann Redis, Memcached. MySQL oder PDO nutzen. Ich werde keine weiteren implementieren, bin jedoch für PRs offen. Diese sollten nicht im Vendor liegen, sondern als eigene Class.

  • MySQL Storage
  • Redis Storage
  • Memcached Storage
  • Memcache Storage

Die Storages könnte man dann auch ziemlich smart an eine User-ID binden, um z.B. einen Warenkorb überdauernd zu erstellen, welcher noch Monate danach mit den gewählten Artikleln befüllt sein kann. Außerdem könnte man mit einem MySQL Storage z.B. auch User anschreiben und hinweisen, dass der Warenkorb noch Artikel etc. enthält.

Ich würde mich über einen PR freuen, ansonsten gerne als bezahlter Auftrag.

Stand?

Hey, ich hab das Addon gerade zufällig entdeckt und hab bei einem Shop nahezu das gleiche gebaut vor kurzem. Warum ist das Addon nicht im Installer? Wird es noch weiterentwickelt oder was ist der Plan?

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.