Create a gist now

Instantly share code, notes, and snippets.

anonymous /gist:173712
Created Aug 24, 2009

* Order form that allows a user to purchase their
* order items on the
* @see CheckoutPage
* @package ecommerce
class OrderForm extends Form {
function __construct($controller, $name) {
// 1) Member and shipping fields
$member = Member::currentUser() ? Member::currentUser() : singleton('Member');
$memberFields = new CompositeField($member->getEcommerceFields());
$requiredFields = $member->getEcommerceRequiredFields();
if(ShoppingCart::uses_different_shipping_address()) {
$countryField = new DropdownField('ShippingCountry', 'Country');
$shippingFields = new CompositeField(
new HeaderField('Send goods to different address', 3),
new LiteralField('ShippingNote', '<p class="warningMessage"><em>Your goods will be sent to the address below.</em></p>'),
new LiteralField('Help', '<p>You can use this for gift giving. No billing information will be disclosed to this address.</p>'),
new TextField('ShippingName', 'Name'),
new TextField('ShippingAddress', 'Address'),
new TextField('ShippingAddress2', ''),
new TextField('ShippingCity', 'City'),
new HiddenField('UseShippingAddress', '', true),
new FormAction_WithoutLabel('useMemberShippingAddress', 'Use Billing Address for Shipping')
$requiredFields[] = 'ShippingName';
$requiredFields[] = 'ShippingAddress';
$requiredFields[] = 'ShippingCity';
$requiredFields[] = 'ShippingCountry';
} else {
$countryField = $memberFields->fieldByName('Country');
$shippingFields = new FormAction_WithoutLabel('useDifferentShippingAddress', '');
$setCountryLinkID = $countryField->id() . '_SetCountryLink';
$setContryLink = ShoppingCart_Controller::set_country_link();
$memberFields->push(new HiddenField($setCountryLinkID, '', $setContryLink));
$leftFields = new CompositeField($memberFields, $shippingFields);
$rightFields = new CompositeField();
if(!$member->ID || $member->Password == '') {
$rightFields->push(new HeaderField('Sie sind bereits Kunde?', 3));
$rightFields->push(new LiteralField('MemberInfo', "<p>Wenn Sie bereits Kunde sind, loggen Sie sich bitte <a href=\"Security/login?BackURL=" . CheckoutPage::find_link(true) . "/\">hier</a> ein.</p>"));
$rightFields->push(new HeaderField('Sie sind Neukunde?', 3));
$rightFields->push(new LiteralField('AccountInfo', "<p>Wenn Sie Neukunde sind geben Sie bitte ein Passwort ein um Ihren Account zu erstellen. Damit können Sie später Ihren Bestellstatus verfolgen und Ihre Daten ändern. Zudem brauchen Sie Ihre Daten in Zukunft nicht erneut einzugeben.</p><br/>"));
$rightFields->push(new FieldGroup(new ConfirmedPasswordField('Password', 'Password')));
$requiredFields[] = 'Password[_Password]';
$requiredFields[] = 'Password[_ConfirmPassword]';
// 2) Payment fields
$currentOrder = ShoppingCart::current_order();
$total = '' . number_format($currentOrder->Total(), 2);
$paymentFields = Payment::combined_form_fields("$total " . $currentOrder->Currency(), $currentOrder->Total());
foreach($paymentFields as $field) $rightFields->push($field);
if($paymentRequiredFields = Payment::combined_form_requirements()) $requiredFields = array_merge($requiredFields, $paymentRequiredFields);
// 3) Put all the fields in one FieldSet
$fields = new FieldSet($leftFields, $rightFields);
// 4) Terms and conditions field
// If a terms and conditions page exists, we need to create a field to confirm the user has read it
if($controller->TermsPageID && $termsPage = DataObject::get_by_id('Page', $controller->TermsPageID)) {
$bottomFields = new CompositeField(new CheckboxField('ReadTermsAndConditions', "Ja, ich habe die <a href=\"$termsPage->URLSegment\">Allgemeinen Geschäftsbedingungen</a> gelesen und akzeptiere diese!<br><br>"));
$requiredFields[] = 'ReadTermsAndConditions';
$bottomFields->push(new LiteralField('MemberInfo', "<p class=\"hinweis\">Ihre Daten werden vertraulich behandelt und nicht an dritte weitergegeben!</p>"));
// 5) Actions and required fields creation
$actions = new FieldSet(new FormAction('processOrder', 'Artikel bestellen'));
$requiredFields = new CustomRequiredFields($requiredFields);
// 6) Form construction
parent::__construct($controller, $name, $fields, $actions, $requiredFields);
// 7) Member details loading
if($member->ID) $this->loadDataFrom($member);
// 8) Country field value update
$currentOrder = ShoppingCart::current_order();
$currentOrderCountry = $currentOrder->findShippingCountry(true);
* Disable the validator when the action clicked is to use a different shipping address
* or use the member shipping address.
function beforeProcessing() {
if(isset($_REQUEST['action_useDifferentShippingAddress']) || isset($_REQUEST['action_useMemberShippingAddress'])) return true;
else return parent::beforeProcessing();
* Save in the session that the current member wants to use a different shipping address.
function useDifferentShippingAddress($data, $form, $request) {
* Save in the session that the current member wants to use his address as a shipping address.
function useMemberShippingAddress($data, $form, $request) {
* Process the items in the shopping cart from session,
* creating a new {@link Order} record, and updating the
* customer's details {@link Member} record.
* {@link Payment} instance is created, linked to the order,
* and payment is processed {@link Payment::processPayment()}
* @param array $data Form request data submitted from OrderForm
* @param Form $form Form object for this action
* @param HTTPRequest $request Request object for this action
function processOrder($data, $form, $request) {
$paymentClass = (!empty($data['PaymentMethod'])) ? $data['PaymentMethod'] : null;
$payment = class_exists($paymentClass) ? new $paymentClass() : null;
if(!($payment && $payment instanceof Payment)) {
user_error(get_class($payment) . ' is not a valid Payment object!', E_USER_ERROR);
if(!ShoppingCart::has_items()) {
$form->sessionMessage('Please add some items to your cart', 'bad');
return false;
// Create new OR update logged in {@link Member} record
$member = EcommerceRole::createOrMerge($data);
if(!$member) {
'OrderForm.MEMBEREXISTS', 'Es existiert bereits ein Account mit dieser E-Mail-Adresse. Bitte loggen Sie sich ein um Ihre Bestellung abzuschließen.'
return false;
// Create new Order from shopping cart, discard cart contents in session
$order = ShoppingCart::save_current_order();
// Write new record {@link Order} to database
// Save payment data from form and process payment
$payment->OrderID = $order->ID;
$payment->Amount = $order->Total();
// Process payment, get the result back
$result = $payment->processPayment($data, $form);
// isProcessing(): Long payment process redirected to another website (PayPal, Worldpay)
if($result->isProcessing()) {
return $result->getValue();
if($result->isSuccess()) {
return true;
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment