Skip to content
Snippets Groups Projects
Commit b631e183 authored by Bojan Živanović's avatar Bojan Živanović
Browse files

Add initial (very basic) add to cart form.

parent 521dff46
No related branches found
Tags 8.x-2.0-alpha1
No related merge requests found
......@@ -15,6 +15,7 @@ config_devel:
- commerce_product.commerce_product_variation_type.default
- commerce_order.commerce_line_item_type.product_variation
- core.entity_form_display.commerce_product.default.default
- core.entity_view_display.commerce_product.default.default
- core.entity_form_display.commerce_product_variation.default.default
- core.entity_form_display.commerce_line_item.product_variation.default
- core.entity_view_display.commerce_line_item.product_variation.default
......
langcode: en
status: true
dependencies:
config:
- commerce_product.commerce_product_type.default
- field.field.commerce_product.default.body
- field.field.commerce_product.default.stores
- field.field.commerce_product.default.variations
module:
- commerce_product
- text
- user
id: commerce_product.default.default
targetEntityType: commerce_product
bundle: default
mode: default
content:
body:
type: text_default
weight: 0
label: hidden
settings: { }
third_party_settings: { }
variations:
type: add_to_cart
weight: 1
label: hidden
settings:
default_quantity: '1'
combine: true
show_quantity: false
third_party_settings: { }
hidden:
stores: true
......@@ -43,6 +43,19 @@ field.field.*.*.*.third_party.commerce_product:
type: label
label: 'The title of the attribute for the Add to Cart form'
field.formatter.settings.add_to_cart:
type: mapping
mapping:
show_quantity:
type: boolean
label: 'Whether to display a quantity input field on the add to cart form.'
default_quantity:
type: string
label: 'Default quantity'
combine:
type: boolean
label: 'Whether to attempt to combine line items containing the same product variation'
action.configuration.publish_product_action:
type: action_configuration_default
label: 'Configuration for the Publish product action'
......
<?php
/**
* @file
* Contains \Drupal\commerce_product\Form\AddToCartForm.
*/
namespace Drupal\commerce_product\Form;
use Drupal\commerce_cart\CartManagerInterface;
use Drupal\commerce_cart\CartProviderInterface;
use Drupal\commerce_store\StoreContextInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Link;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides the add to cart form for product variations.
*/
class AddToCartForm extends FormBase {
/**
* The cart manager.
*
* @var \Drupal\commerce_cart\CartManagerInterface
*/
protected $cartManager;
/**
* The cart provider.
*
* @var \Drupal\commerce_cart\CartProviderInterface
*/
protected $cartProvider;
/**
* The variation storage.
*
* @var \Drupal\Core\Entity\EntityStorageInterface
*/
protected $variationStorage;
/**
* The store context.
*
* @var \Drupal\commerce_store\StoreContextInterface
*/
protected $storeContext;
/**
* Constructs a new AddToCartForm object.
*
* @param \Drupal\commerce_cart\CartManagerInterface $cart_manager
* The cart manager.
* @param \Drupal\commerce_cart\CartProviderInterface $cart_provider
* The cart provider.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
49 The entity type manager.
* @param \Drupal\commerce_store\StoreContextInterface $store_context
* The store context.
*/
public function __construct(CartManagerInterface $cart_manager, CartProviderInterface $cart_provider, EntityTypeManagerInterface $entity_type_manager, StoreContextInterface $store_context) {
$this->cartManager = $cart_manager;
$this->cartProvider = $cart_provider;
$this->variationStorage = $entity_type_manager->getStorage('commerce_product_variation');
$this->storeContext = $store_context;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('commerce_cart.cart_manager'),
$container->get('commerce_cart.cart_provider'),
$container->get('entity_type.manager'),
$container->get('commerce_store.store_context')
);
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'commerce_product_add_to_cart_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, $product = NULL, array $settings = NULL) {
$variations = [];
foreach ($product->variations->referencedEntities() as $variation) {
$variations[$variation->id()] = $variation->label();
}
$form['#settings'] = $settings;
$form['variation'] = [
'#type' => 'select',
'#title' => $this->t('Select variation:'),
'#options' => $variations,
];
if (!empty($settings['show_quantity'])) {
$form['quantity'] = [
'#type' => 'number',
'#title' => $this->t('Quantity'),
'#min' => 1,
'#max' => 9999,
'#step' => 1,
];
}
else {
$form['quantity'] = [
'#type' => 'value',
'#value' => $settings['default_quantity'],
];
}
$form['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Add to cart'),
];
return $form;
}
/**
* {@inheritdoc}
*/
function submitForm(array &$form, FormStateInterface $form_state) {
$variation = $this->variationStorage->load($form_state->getValue('variation'));
$available_stores = $variation->getProduct()->getStores();
if (count($available_stores) === 1) {
$store = reset($available_stores);
}
else {
$store = $this->storeContext->getStore();
if (!in_array($store, $available_stores)) {
// Throw an exception.
}
}
// @todo The order type should not be hardcoded.
$cart = $this->cartProvider->getCart('default', $store);
if (!$cart) {
$cart = $this->cartProvider->createCart('default', $store);
}
$quantity = $form_state->getValue('quantity');
$combine = $form['#settings']['combine'];
$this->cartManager->addEntity($cart, $variation, $quantity, $combine);
drupal_set_message(t('@variation added to @cart-link.', [
'@variation' => $variation->label(),
'@cart-link' => Link::createFromRoute('your cart', 'commerce_cart.page')->toString(),
]));
}
}
<?php
/**
* @file
* Contains \Drupal\commerce_product\Plugin\Field\FieldFormatter\AddToCartFormatter.
*/
namespace Drupal\commerce_product\Plugin\Field\FieldFormatter;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Field\FieldDefinitionInterface;
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Form\FormBuilderInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\Element;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Plugin implementation of the 'add_to_cart' formatter.
*
* @FieldFormatter(
* id = "add_to_cart",
* label = @Translation("Add to cart form"),
* field_types = {
* "entity_reference",
* },
* )
*/
class AddToCartFormatter extends FormatterBase implements ContainerFactoryPluginInterface {
/**
* The form builder.
*
* @var \Drupal\Core\Form\FormBuilderInterface
*/
protected $formBuilder;
/**
* Constructs an AddToCartFormatter object.
*
* @param string $plugin_id
* The plugin_id for the formatter.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Field\FieldDefinitionInterface $field_definition
* The definition of the field to which the formatter is associated.
* @param array $settings
* The formatter settings.
* @param string $label
* The formatter label display setting.
* @param string $view_mode
* The view mode.
* @param array $third_party_settings
* Any third party settings.
* @param \Drupal\Core\Form\FormBuilderInterface $form_builder
* The form builder.
*/
public function __construct($plugin_id, $plugin_definition, FieldDefinitionInterface $field_definition, array $settings, $label, $view_mode, array $third_party_settings, FormBuilderInterface $form_builder) {
parent::__construct($plugin_id, $plugin_definition, $field_definition, $settings, $label, $view_mode, $third_party_settings);
$this->formBuilder = $form_builder;
}
/**
* {@inheritdoc}
*/
public static function defaultSettings() {
return array(
'show_quantity' => FALSE,
'default_quantity' => 1,
'combine' => TRUE,
) + parent::defaultSettings();
}
/**
* {@inheritdoc}
*/
public function settingsForm(array $form, FormStateInterface $form_state) {
$form = parent::settingsForm($form, $form_state);
$form['show_quantity'] = [
'#type' => 'checkbox',
'#title' => t('Display a quantity input field on the add to cart form.'),
'#default_value' => $this->getSetting('show_quantity'),
];
$form['default_quantity'] = [
'#type' => 'number',
'#title' => t('Default quantity'),
'#default_value' => $this->getSetting('default_quantity'),
'#min' => 1,
'#max' => 9999,
];
$form['combine'] = [
'#type' => 'checkbox',
'#title' => t('Attempt to combine line items containing the same product variation.'),
'#description' => t('The line item type, referenced product variation, and data from fields exposed on the Add to Cart form must all match to combine.'),
'#default_value' => $this->getSetting('combine'),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function settingsSummary() {
// @todo.
return [];
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
// @see \Drupal\Core\Field\FormatterPluginManager::createInstance().
return new static(
$plugin_id,
$plugin_definition,
$configuration['field_definition'],
$configuration['settings'],
$configuration['label'],
$configuration['view_mode'],
$configuration['third_party_settings'],
$container->get('form_builder')
);
}
/**
* {@inheritdoc}
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
// @todo Use a lazy_builder.
$product = $items->getEntity();
$settings = $this->getSettings();
return $this->formBuilder->getForm('\Drupal\commerce_product\Form\AddToCartForm', $product, $settings);
}
/**
* {@inheritdoc}
*/
public static function isApplicable(FieldDefinitionInterface $field_definition) {
return \Drupal::moduleHandler()->moduleExists('commerce_cart');
}
}
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment