Будем писать простую форму добавления товара в корзину и выводить эту форму на странице товара чтобы юзверь мог нажать на кнопку и добавить товар в корзину.
Назовем модуль trade_add_to_cart
- создаем папку
modules/trade/modules/trade_add_to_cart
(например mkdir --parent ...modules/trade/modules/trade_add_to_cart)
- создаем в папке файл trade_add_to_cart.info.yml
name: Trade add to cart
description: Trade add to cart
type: module
package: Trade
# core: 8.x
dependencies:
- trade
# Information added by Drupal.org packaging script on 2017-09-08
version: '8.x-1.0'
core: '8.x'
project: 'trade'
datestamp: 1504875675
- создаем файл trade_add_to_cart.module где описывае поле с формой и выводим в него форму ...
<?php
use \Drupal\Core\Entity\EntityInterface;
use \Drupal\Core\Entity\Display\EntityViewDisplayInterface;
/**
* @file
* Module file for trade_product.
*/
/**
* Implements hook_entity_extra_field_info().
*/
function trade_add_to_cart_entity_extra_field_info() {
$extra['node']['trade_product']['display']['trade_add_to_cart'] = [
'label' => t('Add to cart'),
'description' => t('Trade add to cart'),
'weight' => 100,
'visible' => TRUE,
];
return $extra;
}
/**
* Implements hook_ENTITY_TYPE_view().
*/
function trade_add_to_cart_node_view(array &$build, EntityInterface $node, EntityViewDisplayInterface $display, $view_mode) {
if ($display->getComponent('trade_add_to_cart')) {
$form = \Drupal::formBuilder()
->getForm('Drupal\trade_add_to_cart\Form\TradeAddToCartForm', $node->id());
$build['trade_add_to_cart'] = $form;
}
}
- чуть не забыли саму форму :)
создаем файл trade_add_to_cart/src/Form/TradeAddToCartForm.php
ну это уже у каждого совя форма, на примере форма ajax овая чтобы страницу не пергружать ...
<?php
namespace Drupal\trade_add_to_cart\Form;
use Drupal\Core\Flood\FloodInterface;
use Drupal\Core\Form\FormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\RendererInterface;
use Drupal\user\UserAuthInterface;
use Drupal\user\UserStorageInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Drupal\node\Entity\Node;
use Drupal\taxonomy\Entity\Term;
use Drupal\Component\Utility\Html;
use Drupal\Core\Render\Element;
use Drupal\Core\Url;
use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Ajax\InvokeCommand;
/**
* Provides trade add to cart form.
*/
class TradeAddToCartForm extends FormBase {
/**
* The flood service.
*
* @var \Drupal\Core\Flood\FloodInterface
*/
protected $flood;
/**
* The user storage.
*
* @var \Drupal\user\UserStorageInterface
*/
protected $userStorage;
/**
* The user authentication object.
*
* @var \Drupal\user\UserAuthInterface
*/
protected $userAuth;
/**
* The renderer.
*
* @var \Drupal\Core\Render\RendererInterface
*/
protected $renderer;
/**
* Constructs a new TradeAddToCartForm.
*
* @param \Drupal\Core\Flood\FloodInterface $flood
* The flood service.
* @param \Drupal\user\UserStorageInterface $user_storage
* The user storage.
* @param \Drupal\user\UserAuthInterface $user_auth
* The user authentication object.
* @param \Drupal\Core\Render\RendererInterface $renderer
* The renderer.
*/
public function __construct(FloodInterface $flood, UserStorageInterface $user_storage, UserAuthInterface $user_auth, RendererInterface $renderer) {
$this->flood = $flood;
$this->userStorage = $user_storage;
$this->userAuth = $user_auth;
$this->renderer = $renderer;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static(
$container->get('flood'),
$container->get('entity.manager')->getStorage('user'),
$container->get('user.auth'),
$container->get('renderer')
);
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'trade_add_to_cart_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state, $node_id = 0) {
$config = $this->config('system.site');
$form = [];
$node = Node::load($node_id);
if ($node) {
if ($form_state->has('trade_ajax_form_id')) {
$form_id = $form_state->get('trade_ajax_form_id');
}
else {
$form_id = Html::getId("trade_add_to_cart_form_{$node_id}");
}
$form['#id'] = $form_id;
$form['#attributes']['class'][] = 'trade-add-to-cart-form';
$form['entity_id'] = [
'#type' => 'hidden',
'#value' => $node_id,
];
//product option entity reference fields
if (\Drupal::moduleHandler()->moduleExists('trade_option_term')) {
$fields = \Drupal::service('trade_option_term.manager')
->getFields($node);
if ($fields) {
$option_term_field = \Drupal::service('trade_option_term.trade_option_term_field')
->readUseDefault($node);
foreach ($fields as $field_name => $field) {
if (!empty($option_term_field[$field_name]->target_id)
&& ($term = Term::load($option_term_field[$field_name]->target_id))
) {
$default_value = $term->id();
}
else {
$default_value = '_none';
}
$element_type = $this->config('trade.adm')
->get('devel') ? 'textfield' : 'hidden';
$form[$field_name] = [
'#type' => $element_type,
'#title' => $field_name,
'#default_value' => $default_value,
'#attributes' => [
'data-trade-field' => $field_name,
'data-trade-form' => $form_id,
],
];
}
}
}
$form['quantity'] = [
'#type' => 'number',
'#default_value' => 1,
'#step' => 1,
'#size' => 16,
'#maxlength' => 16,
'#placeholder' => t('Quantity'),
];
if (!empty($node->field_trade_units)) {
$units_label = $node->field_trade_units->entity->label();
$form['quantity']['#description'] = $units_label;
$form['units_label'] = [
'#type' => 'hidden',
'#value' => $units_label,
];
}
$form['actions'] = [
'#type' => 'actions',
];
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this->t('Add to cart'),
'#ajax' => [
'callback' => '::ajaxSubmit',
],
];
$form['messages'] = [
'#type' => 'container',
'#attributes' => [
'class' => [
'trade-add-to-cart-messages',
],
],
];
$this->renderer->addCacheableDependency($form, $config);
}
return $form;
}
/**
* Implements set form default value.
*
* @param array $form
* Form render array.
*/
public
function setFormDefaultValue(&$form) {
foreach (Element::children($form) as $element_children_key) {
if (isset($form[$element_children_key]['#default_value'])
&& isset($form[$element_children_key]['#value'])) {
$form[$element_children_key]['#value'] = $form[$element_children_key]['#default_value'];
}
}
}
/**
* Implements ajax submit callback.
*
* @param array $form
* Form render array.
* @param \Drupal\Core\Form\FormStateInterface $form_state
* Current state of the form.
*
* @return array $form
*/
public
function ajaxSubmit(array &$form, FormStateInterface $form_state) {
$form['messages']['#attributes']['class'][] = 'trade-attach-modal-slide';
$form['messages']['status'] = [
'#type' => 'status_messages',
];
$form_selector = '#' . $form_state->get('trade_ajax_form_id');
$response = new AjaxResponse();
$response->addCommand(new ReplaceCommand($form_selector, $form));
$response->addCommand(new InvokeCommand($form_selector, 'trigger', ['replaceTradeAddToCartForm']));
return $response;
}
/**
* {@inheritdoc}
*/
public
function submitForm(array &$form, FormStateInterface $form_state) {
$node = Node::load($form_state->getValue('entity_id'));
if (\Drupal::moduleHandler()->moduleExists('trade_order')
&& !empty($node)
) {
$order_storage = \Drupal::service('entity.manager')
->getStorage('trade_order');
$cart = $order_storage->loadCart();
if (empty($cart)) {
$order_storage->createCart();
$cart = $order_storage->loadCart();
}
//add item
if (!empty($cart)) {
$values = $form_state->getValues();
//get product options
if (\Drupal::moduleHandler()->moduleExists('trade_option_term')) {
$options_fields = \Drupal::service('trade_option_term.manager')
->getFields($node);
$values['options'] = array_intersect_key($form_state->getValues(), $options_fields);
$options_texts = [];
foreach ($values['options'] as $field_name => $field_value) {
$field_value_entity = TERM::load($field_value);
if (!empty($field_value_entity)) {
$field_value_label = $field_value_entity->label();
if (empty($field_value_label)) {
$field_value_label = $field_value;
}
$options_texts[] = $node->getFieldDefinition($field_name)
->label() . ':' . $field_value_label;
$values['options_text'] = implode(';', $options_texts);
}
}
}
$cart->addItem($node, $values);
}
}
$cart_url = Url::fromRoute('trade_order.cart')->toString();
drupal_set_message($this->t('Product <strong>:nam</strong> added to <a href=":cart_url">cart</a>.', [
':nam' => $node->label(),
':cart_url' => $cart_url,
]));
$form_state->set('trade_ajax_form_id', $form['#id']);
$form_state->setRebuild(TRUE);
}
}