View source
<?php
namespace Drupal\uc_cart_links\Form;
use Drupal\Component\Datetime\TimeInterface;
use Drupal\Component\Utility\UrlHelper;
use Drupal\Core\Database\Connection;
use Drupal\Core\Extension\ModuleHandlerInterface;
use Drupal\Core\Form\ConfirmFormBase;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;
use Drupal\node\Entity\Node;
use Drupal\uc_cart\CartManagerInterface;
use Drupal\uc_cart_links\CartLinksValidatorInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\Session\SessionInterface;
class CartLinksForm extends ConfirmFormBase {
protected $actions;
protected $cartManager;
protected $cartLinksValidator;
protected $moduleHandler;
protected $session;
protected $dateTime;
protected $database;
public function __construct(CartManagerInterface $cart_manager, CartLinksValidatorInterface $cart_links_validator, ModuleHandlerInterface $module_handler, SessionInterface $session, TimeInterface $date_time, Connection $database) {
$this->cartManager = $cart_manager;
$this->cartLinksValidator = $cart_links_validator;
$this->moduleHandler = $module_handler;
$this->session = $session;
$this->dateTime = $date_time;
$this->database = $database;
}
public static function create(ContainerInterface $container) {
return new static($container
->get('uc_cart.manager'), $container
->get('uc_cart_links.validator'), $container
->get('module_handler'), $container
->get('session'), $container
->get('datetime.time'), $container
->get('database'));
}
public function getFormId() {
return 'uc_cart_links_form';
}
public function getQuestion() {
return $this
->t('The current contents of your shopping cart will be lost. Are you sure you want to continue?');
}
public function getCancelUrl() {
return [];
}
protected function getEditableConfigNames() {
return [
'uc_cart_links.settings',
];
}
public function buildForm(array $form, FormStateInterface $form_state, $actions = NULL) {
$cart_links_config = $this
->config('uc_cart_links.settings');
$this->actions = $actions;
$data = trim($cart_links_config
->get('restrictions'));
if (!empty($data)) {
$restrictions = explode("\n", $cart_links_config
->get('restrictions'));
$restrictions = array_map('trim', $restrictions);
if (!empty($restrictions) && !in_array($this->actions, $restrictions)) {
$this
->getRequest()->query
->remove('destination');
$path = $cart_links_config
->get('invalid_page');
if (empty($path)) {
return $this
->redirect('<front>');
}
return new RedirectResponse(Url::fromUri('internal:/' . $path, [
'absolute' => TRUE,
])
->toString());
}
}
$cart = $this->cartManager
->get();
$items = $cart
->getContents();
if ($cart_links_config
->get('empty') && !empty($items)) {
$actions = explode('-', urldecode($this->actions));
foreach ($actions as $action) {
$action = mb_substr($action, 0, 1);
if ($action == 'e' || $action == 'E') {
$form = parent::buildForm($form, $form_state);
$form['actions']['cancel']['#href'] = $cart_links_config
->get('invalid_page');
return $form;
}
}
}
return $this
->submitForm($form, $form_state);
}
public function validateForm(array &$form, FormStateInterface $form_state) {
}
public function submitForm(array &$form, FormStateInterface $form_state) {
$cart_links_config = $this
->config('uc_cart_links.settings');
$actions = explode('-', urldecode($this->actions));
$messages = [];
$id = $this
->t('(not specified)');
$cart = $this->cartManager
->get();
foreach ($actions as $action) {
switch (mb_substr($action, 0, 1)) {
case 'i':
case 'I':
$id = mb_substr($action, 1, 32);
break;
case 'p':
case 'P':
$p = [
'nid' => 0,
'qty' => 1,
'data' => [],
];
$msg = TRUE;
$parts = explode('_', $action);
foreach ($parts as $part) {
switch (mb_substr($part, 0, 1)) {
case 'p':
case 'P':
$p['nid'] = intval(mb_substr($part, 1));
break;
case 'q':
case 'Q':
$p['qty'] = intval(mb_substr($part, 1));
break;
case 'a':
case 'A':
$attribute = intval(mb_substr($part, 1, stripos($part, 'o') - 1));
$option = (string) mb_substr($part, stripos($part, 'o') + 1);
if (!isset($p['attributes'][$attribute])) {
$p['attributes'][$attribute] = $option;
}
else {
if (is_array($p['attributes'][$attribute])) {
$p['attributes'][$attribute][$option] = $option;
}
else {
$p['attributes'][$attribute] = [
$p['attributes'][$attribute] => $p['attributes'][$attribute],
$option => $option,
];
}
}
break;
case 's':
case 'S':
$msg = FALSE;
break;
}
}
if ($p['nid'] > 0 && $p['qty'] > 0) {
$node = Node::load($p['nid']);
if ($node->status) {
if (isset($node->products) && is_array($node->products)) {
foreach ($node->products as $nid => $product) {
$p['data']['products'][$nid] = [
'nid' => $nid,
'qty' => $product->qty,
];
}
}
$cart
->addItem($p['nid'], $p['qty'], $p['data'] + $this->moduleHandler
->invokeAll('uc_add_to_cart_data', [
$p,
]), $msg);
}
else {
$this
->logger('uc_cart_link')
->error('Cart Link on %url tried to add an unpublished product to the cart.', [
'%url' => $this
->getRequest()->server
->get('HTTP_REFERER'),
]);
}
}
break;
case 'e':
case 'E':
if ($cart_links_config
->get('empty')) {
$cart
->emptyCart();
}
break;
case 'm':
case 'M':
if (empty($messages)) {
$data = explode("\n", $cart_links_config
->get('messages'));
foreach ($data as $message) {
if (preg_match('/^\\s*$/', $message)) {
continue;
}
list($mkey, $mdata) = explode('|', $message, 2);
$messages[trim($mkey)] = trim($mdata);
}
}
$mkey = intval(mb_substr($action, 1));
if (!empty($messages[$mkey])) {
$this
->messenger()
->addMessage($messages[$mkey]);
}
break;
}
}
if ($cart_links_config
->get('track')) {
$this->database
->merge('uc_cart_link_clicks')
->key([
'cart_link_id' => (string) $id,
])
->fields([
'clicks' => 1,
'last_click' => $this->dateTime
->getRequestTime(),
])
->expression('clicks', 'clicks + :i', [
':i' => 1,
])
->execute();
}
$this->session
->set('uc_cart_last_url', $this
->getRequest()->server
->get('HTTP_REFERER'));
$query = $this
->getRequest()->query;
if ($query
->has('destination')) {
$options = UrlHelper::parse($query
->get('destination'));
$path = $options['path'];
}
else {
$path = 'cart';
$options = [];
}
$options += [
'absolute' => TRUE,
];
return new RedirectResponse(Url::fromUri('base:' . $path, $options)
->toString());
}
}