View source
<?php
namespace Drupal\commerce_wishlist\Form;
use Drupal\commerce\AjaxFormTrait;
use Drupal\commerce\Context;
use Drupal\commerce\PurchasableEntityInterface;
use Drupal\commerce_cart\CartManagerInterface;
use Drupal\commerce_cart\CartProviderInterface;
use Drupal\commerce_order\Resolver\OrderTypeResolverInterface;
use Drupal\commerce_price\Resolver\ChainPriceResolverInterface;
use Drupal\commerce_store\CurrentStoreInterface;
use Drupal\commerce_wishlist\Entity\WishlistInterface;
use Drupal\commerce_wishlist\Entity\WishlistItemInterface;
use Drupal\commerce_wishlist\WishlistManagerInterface;
use Drupal\commerce_wishlist\WishlistSessionInterface;
use Drupal\Core\Config\ConfigFactoryInterface;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Routing\RouteMatchInterface;
use Drupal\Core\Session\AccountInterface;
use Drupal\Component\Serialization\Json;
use Drupal\Component\Utility\Html;
use Symfony\Component\DependencyInjection\ContainerInterface;
class WishlistUserForm extends EntityForm {
use AjaxFormTrait;
protected $cartManager;
protected $cartProvider;
protected $currentStore;
protected $currentUser;
protected $orderTypeResolver;
protected $routeMatch;
protected $settings;
protected $chainPriceResolver;
protected $wishlistManager;
protected $wishlistSession;
public function __construct(EntityTypeManagerInterface $entity_type_manager, ConfigFactoryInterface $config_factory, CartManagerInterface $cart_manager, CartProviderInterface $cart_provider, CurrentStoreInterface $current_store, AccountInterface $current_user, OrderTypeResolverInterface $order_type_resolver, RouteMatchInterface $route_match, ChainPriceResolverInterface $chain_price_resolver, WishlistManagerInterface $wishlist_manager, WishlistSessionInterface $wishlist_session) {
$this->entityTypeManager = $entity_type_manager;
$this->cartManager = $cart_manager;
$this->cartProvider = $cart_provider;
$this->currentStore = $current_store;
$this->currentUser = $current_user;
$this->orderTypeResolver = $order_type_resolver;
$this->routeMatch = $route_match;
$this->settings = $config_factory
->get('commerce_wishlist.settings');
$this->chainPriceResolver = $chain_price_resolver;
$this->wishlistManager = $wishlist_manager;
$this->wishlistSession = $wishlist_session;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('entity_type.manager'), $container
->get('config.factory'), $container
->get('commerce_cart.cart_manager'), $container
->get('commerce_cart.cart_provider'), $container
->get('commerce_store.current_store'), $container
->get('current_user'), $container
->get('commerce_order.chain_order_type_resolver'), $container
->get('current_route_match'), $container
->get('commerce_price.chain_price_resolver'), $container
->get('commerce_wishlist.wishlist_manager'), $container
->get('commerce_wishlist.wishlist_session'));
}
public function form(array $form, FormStateInterface $form_state) {
$wishlist = $this->entity;
$owner_access = $this
->ownerAccess($wishlist);
$wishlist_has_items = $wishlist
->hasItems();
$form['#tree'] = TRUE;
$form['#process'][] = '::processForm';
$form['#theme'] = 'commerce_wishlist_user_form';
$form['#attached']['library'][] = 'commerce_wishlist/user';
$form['#id'] = Html::getId($form_state
->getBuildInfo()['form_id']);
$form['header'] = [
'#type' => 'container',
];
$form['header']['empty_text'] = [
'#markup' => $this
->t('Your wishlist is empty.'),
'#access' => !$wishlist_has_items,
];
$form['header']['add_all_to_cart'] = [
'#type' => 'submit',
'#value' => t('Add the entire list to cart'),
'#ajax' => [
'callback' => [
get_called_class(),
'ajaxRefreshForm',
],
],
'#access' => $wishlist_has_items,
];
$form['header']['share'] = [
'#type' => 'link',
'#title' => $this
->t('Share the list by email'),
'#url' => $wishlist
->toUrl('share-form'),
'#attributes' => [
'class' => [
'use-ajax',
'button',
'btn',
'btn-default',
'wishlist-button',
],
'data-dialog-type' => 'modal',
'data-dialog-options' => Json::encode([
'width' => 700,
'title' => $this
->t('Share the list by email'),
]),
'role' => 'button',
],
'#access' => $owner_access && $wishlist_has_items,
];
$form['items'] = [];
foreach ($wishlist
->getItems() as $item) {
$purchasable_entity = $item
->getPurchasableEntity();
if (!$purchasable_entity) {
continue;
}
$item_form =& $form['items'][$item
->id()];
$item_form = [
'#type' => 'container',
];
$item_form['entity'] = $this
->renderPurchasableEntity($purchasable_entity);
$item_form['details'] = [
'#theme' => 'commerce_wishlist_item_details',
'#wishlist_item_entity' => $item,
];
$item_form['details_edit'] = [
'#type' => 'link',
'#title' => $this
->t('Edit details'),
'#url' => $item
->toUrl('details-form'),
'#attributes' => [
'class' => [
'use-ajax',
'wishlist-item__details-edit-link',
],
'data-dialog-type' => 'modal',
'data-dialog-options' => Json::encode([
'width' => 700,
'title' => $this
->t('Edit details'),
]),
],
'#access' => $owner_access,
];
$item_form['actions'] = [
'#type' => 'container',
];
$item_form['actions']['add_to_cart'] = [
'#type' => 'submit',
'#value' => t('Add to cart'),
'#ajax' => [
'callback' => [
get_called_class(),
'ajaxRefreshForm',
],
],
'#submit' => [
'::addToCartSubmit',
],
'#name' => 'add-to-cart-' . $item
->id(),
'#item_id' => $item
->id(),
];
$item_form['actions']['remove'] = [
'#type' => 'submit',
'#value' => t('Remove'),
'#ajax' => [
'callback' => [
get_called_class(),
'ajaxRefreshForm',
],
],
'#submit' => [
'::removeItem',
],
'#name' => 'remove-' . $item
->id(),
'#access' => $owner_access,
'#item_id' => $item
->id(),
];
}
return $form;
}
protected function actionsElement(array $form, FormStateInterface $form_state) {
return [];
}
public function addToCartSubmit(array $form, FormStateInterface $form_state) {
$triggering_element = $form_state
->getTriggeringElement();
$wishlist_item_storage = $this->entityTypeManager
->getStorage('commerce_wishlist_item');
$wishlist_item = $wishlist_item_storage
->load($triggering_element['#item_id']);
$this
->addItemToCart($wishlist_item);
}
public function removeItem(array $form, FormStateInterface $form_state) {
$wishlist = $this->entity;
$triggering_element = $form_state
->getTriggeringElement();
$wishlist_item_storage = $this->entityTypeManager
->getStorage('commerce_wishlist_item');
$wishlist_item = $wishlist_item_storage
->load($triggering_element['#item_id']);
$this->wishlistManager
->removeWishlistItem($wishlist, $wishlist_item);
$this
->messenger()
->addStatus($this
->t('@entity has been removed from your wishlist.', [
'@entity' => $wishlist_item
->label(),
]));
$form_state
->setRebuild(TRUE);
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$wishlist = $this->entity;
foreach ($wishlist
->getItems() as $wishlist_item) {
$this
->addItemToCart($wishlist_item);
}
}
protected function renderPurchasableEntity(PurchasableEntityInterface $purchasable_entity) {
$entity_type_id = $purchasable_entity
->getEntityTypeId();
$view_builder = $this->entityTypeManager
->getViewBuilder($entity_type_id);
$view_mode = $this->settings
->get('view_modes.' . $entity_type_id);
$view_mode = $view_mode ?: 'cart';
$build = $view_builder
->view($purchasable_entity, $view_mode);
return $build;
}
protected function ownerAccess(WishlistInterface $wishlist) {
if ($this->currentUser
->isAnonymous()) {
return $this->wishlistSession
->hasWishlistId($wishlist
->id());
}
if ($wishlist
->getOwnerId() != $this->currentUser
->id()) {
return FALSE;
}
if ($this->routeMatch
->getRouteName() != 'entity.commerce_wishlist.user_form') {
return FALSE;
}
return TRUE;
}
protected function addItemToCart(WishlistItemInterface $wishlist_item) {
$purchasable_entity = $wishlist_item
->getPurchasableEntity();
$order_item_storage = $this->entityTypeManager
->getStorage('commerce_order_item');
$values = [
'quantity' => $wishlist_item
->getQuantity(),
];
$order_item = $order_item_storage
->createFromPurchasableEntity($purchasable_entity, $values);
$order_type_id = $this->orderTypeResolver
->resolve($order_item);
$store = $this
->selectStore($purchasable_entity);
$cart = $this->cartProvider
->getCart($order_type_id, $store);
if (!$order_item
->isUnitPriceOverridden()) {
$context = new Context($this->currentUser, $store);
$resolved_price = $this->chainPriceResolver
->resolve($purchasable_entity, $order_item
->getQuantity(), $context);
$order_item
->setUnitPrice($resolved_price);
}
if (!$cart) {
$cart = $this->cartProvider
->createCart($order_type_id, $store);
}
$this->cartManager
->addOrderItem($cart, $order_item, TRUE);
}
protected function selectStore(PurchasableEntityInterface $entity) {
$stores = $entity
->getStores();
if (count($stores) === 1) {
$store = reset($stores);
}
elseif (count($stores) === 0) {
throw new \Exception('The given entity is not assigned to any store.');
}
else {
$store = $this->currentStore
->getStore();
if (!in_array($store, $stores)) {
throw new \Exception("The given entity can't be purchased from the current store.");
}
}
return $store;
}
}