Commit 3db144cb authored by Fernando Andrés Muñoz Bravo's avatar Fernando Andrés Muñoz Bravo Committed by Fernando Andrés Muñoz Bravo
Browse files

Issue #3260924 by waspper, KondratievaS, sorlov: Integration with Drupal Commerce

parent cbf577b2
Loading
Loading
Loading
Loading
+11 −0
Changes for modules/auctioneer_commerce/auctioneer_commerce.info.yml: 11 added lines, 0 removed lines.
Original line number Diff line number Diff line
name: Auctioneer - Commerce
type: module
description: 'Integration with Drupal Commerce.'
package: Auctioneer
core_version_requirement: ^8.8.8 || ^9
dependencies:
  - drupal:auctioneer
  - commerce:commerce_cart (>=2.28)
  - commerce:commerce_order (>=2.28)
  - commerce:commerce_price (>=2.28)
  - commerce:commerce_store (>=2.28)
+42 −0
Changes for modules/auctioneer_commerce/auctioneer_commerce.install: 42 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

/**
 * @file
 * Install, update and uninstall functions for the auctioneer_commerce module.
 */

use Drupal\Core\Field\BaseFieldDefinition;

/**
 * Implements hook_install().
 */
function auctioneer_commerce_install() {
  $order_item_type_storage = \Drupal::entityTypeManager()->getStorage('commerce_order_item_type');
  $order_item_type = $order_item_type_storage->load('auctioneer_commerce_auction');
  if (!$order_item_type) {
    // Step 1: Provide needed commerce order item type.
    $order_item_type = $order_item_type_storage->create([
      'id' => 'auctioneer_commerce_auction',
      'label' => t('Auction'),
      'orderType' => 'default',
    ]);
    $order_item_type->save();
    // Step 2: Provide needed fields to the order item type.
    $fields = [
      'auction_bid' => BaseFieldDefinition::create('entity_reference')
        ->setLabel(t('Bid'))
        ->setDescription(t('The auction bid.'))
        ->setCardinality(1)
        ->setRequired(TRUE)
        ->setSetting('target_type', 'bid')
        ->setSetting('handler', 'default')
        ->setTranslatable(TRUE)
        ->setDisplayOptions('form', [
          'type' => 'entity_reference_autocomplete',
        ])
        ->setDisplayConfigurable('view', TRUE)
        ->setDisplayConfigurable('form', TRUE),
    ];
    \Drupal::service('auctioneer.auction_field.manager')->provideEntityTypeFields($fields, 'commerce_order_item', $order_item_type->id());
  }
}
+7 −0
Changes for modules/auctioneer_commerce/auctioneer_commerce.libraries.yml: 7 added lines, 0 removed lines.
Original line number Diff line number Diff line
auction_type.form.ajax_behavior:
  version: VERSION
  js:
    js/auction-type--form-ajax-behavior.js: {}
  dependencies:
    - core/jquery
    - core/drupal
+309 −0
Changes for modules/auctioneer_commerce/auctioneer_commerce.module: 309 added lines, 0 removed lines.
Original line number Diff line number Diff line
<?php

/**
 * @file
 * Defines the "auctioneer_commerce" primary hooks.
 */

use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Url;

/**
 * Implements hook_entity_extra_field_info().
 */
function auctioneer_commerce_entity_extra_field_info() {
  $extra = [];
  $entity_extra_fields = [
    'bid' => [
      'bundles' => \Drupal::service('entity_type.bundle.info')->getBundleInfo('bid'),
      'fields' => [
        'basic_bid_add_to_cart' => [
          'label' => t('Add bid to cart (basic)'),
          'description' => t("Option to add this bid to the owner's cart."),
          'weight' => 100,
          'visible' => TRUE,
        ],
      ],
    ],
  ];
  // Let's iterate over all our supported entity types.
  foreach ($entity_extra_fields as $entity_type => $data) {
    foreach ($data['bundles'] as $bundle_name => $bundle_info) {
      foreach ($data['fields'] as $extra_field_name => $extra_field_definition) {
        $extra[$entity_type][$bundle_name]['display'][$extra_field_name] = $extra_field_definition;
      }
    }
  }

  return $extra;
}

/**
 * Implements hook_ENTITY_TYPE_view() for "bid" entity type.
 */
function auctioneer_commerce_bid_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
  if ($display->getComponent('basic_bid_add_to_cart')) {
    $user = \Drupal::currentUser();
    $auction = $entity->getAuction();
    if ($user->hasPermission('auctioneer_commerce add bid to cart') && ($auction instanceof EntityInterface)) {
      $hammer = \Drupal::service('auctioneer.auction_type.manager')->getAuctionHammerBidData($entity);
      $settings = $auction->getAuctionType()->getThirdPartySetting('auctioneer_commerce', 'settings');
      if (
        !in_array($auction->getAuctionState(), ['opened', 'paused']) &&
        !empty($hammer) &&
        !empty($settings) &&
        isset($settings['enable']) &&
        (bool) $settings['enable']
      ) {
        $output = [
          '#type' => 'container',
          '#attributes' => [
            'class' => [
              'bid-add-to-cart--basic',
              'bid-type--' . $entity->bundle(),
              'bid-type--' . $entity->bundle() . '--view-mode--' . $view_mode,
            ],
          ],
          'add_to_cart_link' => [
            '#type' => 'link',
            '#title' => t("Add to the owner's cart"),
            '#url' => Url::fromRoute('auctioneer_commerce.cart.add_bid_form', ['bid' => $entity->id()]),
            '#attributes' => [
              'class' => [
                'button',
              ],
            ],
          ],
        ];
        if (isset($settings['cart_ajax']) && (bool) $settings['cart_ajax']) {
          $output['add_to_cart_link']['#attributes']['class'][] = 'use-ajax';
          $output['add_to_cart_link']['#attributes']['data-dialog-type'] = 'modal';
          $dialog_classes = [
            'dialog-bid',
            'dialog-bid--cart-form',
            'dialog-bid--type--' . $entity->bundle(),
            'dialog-bid--type--' . $entity->bundle() . '--view-mode--' . $view_mode,
          ];
          $output['add_to_cart_link']['#attributes']['data-dialog-options'] = json_encode(['dialogClass' => implode(' ', $dialog_classes)]);
          $output['add_to_cart_link']['#attached']['library'][] = 'core/drupal.dialog.ajax';
        }
        $build['basic_bid_add_to_cart'] = $output;
      }
    }

    return [];
  }
}

/**
 * Implements hook_form_BASE_FORM_ID_alter() for "auction_type_form".
 */
function auctioneer_commerce_form_auction_type_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  $auction_type = $form_state->getFormObject()->getEntity();
  $settings = $auction_type->getThirdPartySetting('auctioneer_commerce', 'settings');
  $help = t('Enabling will attach needed fields to this auction type.');
  if (\Drupal::service('auctioneer_commerce.manager')->isCommerceEnabled($auction_type)) {
    $help = t(
      'Enabling will attach or display (if previously enabled) needed fields to this auction type.
      Disabling will prevent commerce-related behavior, but will keep previously stored data.
      If you need to remove integration for this auction type, use <a href="@remove_settings">this link</a>.',
      [
        '@remove_settings' => Url::fromRoute(
          'auctioneer_commerce.auction_type.commerce_settings.remove',
          [
            'auction_type' => $auction_type->id(),
          ],
          [
            'query' => [
              'destination' => $auction_type->toUrl()->toString(),
            ],
          ]
        )->toString(),
      ]
    );
  }
  $form['commerce'] = [
    '#type' => 'details',
    '#title' => t('Drupal commerce integration'),
    '#open' => TRUE,
    '#weight' => 10,
    '#tree' => TRUE,
    '#access' => \Drupal::currentUser()->hasPermission('auctioneer_commerce administer commerce settings'),
    '#prefix' => '<div id="commerce-integration">',
    '#suffix' => '</div>',
  ];
  $form['commerce']['enable'] = [
    '#type' => 'checkbox',
    '#title' => t('Enable for this auction type'),
    '#default_value' => $settings['enable'] ?? FALSE,
    '#description' => $help,
  ];
  $bid_allowed_fields = [];
  foreach (\Drupal::service('entity_field.manager')->getFieldDefinitions('bid', $auction_type->getBidTypeName()) as $field_name => $field_definition) {
    if (
      in_array($field_definition->getType(),
      [
        'auctioneer_number',
        'integer',
        'decimal',
        'float',
      ]) &&
      $field_name != 'id'
    ) {
      $bid_allowed_fields[$field_name] = t('Field name "@field_name" (@field_label)', ['@field_name' => $field_name, '@field_label' => $field_definition->getLabel()]);
    }
  }
  $form['commerce']['bid_amount_field_name'] = [
    '#type' => 'select',
    '#title' => t('Bid amount field'),
    '#description' => t('Pick field that should be used as source for the commerce price amount.'),
    '#options' => $bid_allowed_fields,
    '#default_value' => $settings['bid_amount_field_name'] ?? NULL,
    '#states' => [
      'visible' => [
        ':input[name="commerce[enable]"]' => ['checked' => TRUE],
      ],
    ],
    '#ajax' => [
      'callback' => '_auctioneer_commerce_auction_type_form_callback',
      'event' => 'auctioneer_commerce.auction_type.bid_selection',
      'wrapper'  => 'commerce-integration',
    ],
  ];
  $form['commerce']['cart_ajax'] = [
    '#type' => 'checkbox',
    '#title' => t('Use AJAX for cart operations.'),
    '#default_value' => $settings['cart_ajax'] ?? FALSE,
    '#states' => [
      'visible' => [
        ':input[name="commerce[enable]"]' => ['checked' => TRUE],
      ],
    ],
  ];
  $form['commerce']['different_customer'] = [
    '#type' => 'checkbox',
    '#title' => t('Allow to pick different customer.'),
    '#default_value' => $settings['different_customer'] ?? FALSE,
    '#description' => t('When there is no customer for placed bid (for example, it was placed as anonymous), it is common to ask for an existing user or a new one. This option is to allow adding bid to the cart to a different user account, no matter if bid was placed as a logged-in user.'),
    '#states' => [
      'visible' => [
        ':input[name="commerce[enable]"]' => ['checked' => TRUE],
      ],
    ],
  ];
  $form['#attached']['library'][] = 'auctioneer_commerce/auction_type.form.ajax_behavior';
  $form['actions']['submit']['#submit'][] = '_auctioneer_commerce_form_auction_type_form_submit';
}

/**
 * Helper ajax callback to update coomerce options on bid type selection.
 */
function _auctioneer_commerce_auction_type_form_callback(array &$form, FormStateInterface $form_state) {
  return $form['commerce'];
}

/**
 * Custom submit function to set commerce settings.
 */
function _auctioneer_commerce_form_auction_type_form_submit(array $form, FormStateInterface $form_state) {
  $commerce = $form_state->getValue('commerce');
  $auction_type = $form_state->getFormObject()->getEntity();
  // Saving our configurations.
  $settings = [
    'enable' => (bool) $commerce['enable'],
    'bid_amount_field_name' => $commerce['bid_amount_field_name'],
    'cart_ajax' => (bool) $commerce['cart_ajax'],
    'different_customer' => (bool) $commerce['different_customer'],
  ];
  $auction_type->setThirdPartySetting('auctioneer_commerce', 'settings', $settings);
  $auction_type->save();
}

/**
 * Implements hook_ENTITY_TYPE_insert() for entity type "auction_type".
 */
function auctioneer_commerce_auction_type_insert(EntityInterface $entity) {
  auctioneer_commerce_auction_type_post_save($entity);
}

/**
 * Implements hook_ENTITY_TYPE_update() for entity type "auction_type".
 */
function auctioneer_commerce_auction_type_update(EntityInterface $entity) {
  auctioneer_commerce_auction_type_post_save($entity);
}

/**
 * Helper function to provide auction type commerce settings.
 */
function auctioneer_commerce_auction_type_post_save(EntityInterface $entity) {
  $settings = $entity->getThirdPartySetting('auctioneer_commerce', 'settings');
  if (!empty($settings) && isset($settings['enable']) && (bool) $settings['enable']) {
    \Drupal::service('auctioneer_commerce.manager')->initializeAuctionTypeCommerceConfigurations($entity);
  }
}

/**
 * Implements hook_form_BASE_FORM_ID_alter() for 'auction_form'.
 */
function auctioneer_commerce_form_auction_form_alter(&$form, FormStateInterface $form_state) {
  $auction = $form_state->getFormObject()->getEntity();
  $settings = $auction->getAuctionType()->getThirdPartySetting('auctioneer_commerce', 'settings');
  $form['auctioneer_commerce'] = [
    '#title' => t('Commerce integration'),
    '#type' => 'details',
    '#collapsible' => TRUE,
    '#weight' => 100,
    '#open' => TRUE,
    '#tree' => FALSE,
    '#group' => 'advanced',
    '#access' => isset($settings['enable']) && (bool) $settings['enable'],
  ];
  foreach (['auction_commerce_store', 'auction_commerce_currency'] as $field_name) {
    if (isset($form[$field_name])) {
      $form[$field_name]['#group'] = 'auctioneer_commerce';
    }
  }
}

/**
 * Implements hook_entity_operation().
 */
function auctioneer_commerce_entity_operation(EntityInterface $entity) {
  $operations = [];
  if ($entity->getEntityTypeId() == 'auction_type' && \Drupal::service('auctioneer_commerce.manager')->isCommerceEnabled($entity)) {
    $operations['auctioneer_commerce_remove'] = [
      'title' => t('Remove commerce integration'),
      'url' => Url::fromRoute(
        'auctioneer_commerce.auction_type.commerce_settings.remove',
        [
          'auction_type' => $entity->id(),
        ],
        [
          'query' => [
            'destination' => Url::fromRoute('entity.auction_type.collection')->toString(),
          ],
        ]
      ),
      'weight' => 100,
    ];
  }

  return $operations;
}

/**
 * Implements hook_theme().
 */
function auctioneer_commerce_theme($existing, $type, $theme, $path) {
  return [
    'auctioneer_commerce_delay_redirect' => [
      'variables' => [
        'path' => NULL,
        'delay' => NULL,
      ],
    ],
  ];
}
+8 −0
Changes for modules/auctioneer_commerce/auctioneer_commerce.permissions.yml: 8 added lines, 0 removed lines.
Original line number Diff line number Diff line
auctioneer_commerce administer commerce settings:
  title: "Administer Commerce integration"
  description: "Allow to manage integration with Drupal Commerce."
  restrict access: true

auctioneer_commerce add bid to cart:
  title: "Add bid to the owner's cart"
  description: "Allow adding bids to the owner's cart."
Loading