arch-8.x-1.x-dev/modules/compare/arch_compare.module

modules/compare/arch_compare.module
<?php

/**
 * @file
 * Compare module.
 */

use Drupal\arch_product\Entity\ProductInterface;
use Drupal\arch_product\Entity\ProductType;
use Drupal\arch_product\Entity\ProductTypeInterface;
use Drupal\Component\Utility\Html;
use Drupal\Core\Entity\Display\EntityViewDisplayInterface;
use Drupal\Core\Entity\Entity\EntityViewDisplay;
use Drupal\Core\Entity\EntityInterface;
use Drupal\Core\Form\FormStateInterface;
use Drupal\field\Entity\FieldConfig;

/**
 * Implements hook_theme().
 */
function arch_compare_theme() {
  return [
    'compare_item' => [
      'variables' => [
        'product' => NULL,
      ],
    ],
    'compare_page' => [
      'variables' => [
        'products' => NULL,
        'limit' => NULL,
        'view_mode' => NULL,
      ],
    ],
    'compare_block' => [
      'variables' => [
        'title' => NULL,
        'list' => NULL,
        'url' => NULL,
        'link' => NULL,
        'limit' => NULL,
      ],
    ],
  ];
}

/**
 * Compare item theme function.
 *
 * @param array $variables
 *   Variables.
 *
 * @throws \Drupal\Core\Entity\EntityMalformedException
 */
function template_preprocess_compare_item(array &$variables) {
  if (empty($variables['product'])) {
    return;
  }

  /** @var \Drupal\arch_product\Entity\ProductInterface $product */
  $product = $variables['product'];
  $variables['element'] = [
    '#type' => 'container',
    '#attributes' => [
      'class' => [
        'compare-item',
      ],
    ],
    'checkbox' => [
      '#type' => 'checkbox',
      '#title' => t('Compare', [], ['context' => 'arch_compare']),
      '#return_value' => $product->id(),
      '#id' => 'compare-product-' . $product->id(),
      '#required' => FALSE,
      '#attributes' => [
        'data-pid' => $product->id(),
        'data-title' => $product->getTitle(),
        'data-url' => $product->toUrl()->toString(),
      ],
    ],
  ];
}

/**
 * Compare item theme function.
 *
 * @param array $variables
 *   Variables.
 */
function template_preprocess_compare_block(array &$variables) {
  $variables['title'] = [
    '#type' => 'html_tag',
    '#tag' => 'h3',
    '#value' => t('Compare products', [], ['context' => 'arch_compare']),
    '#attributes' => [
      'class' => 'title',
    ],
  ];
  $variables['list'] = [
    '#type' => 'html_tag',
    '#tag' => 'ul',
    '#attributes' => [
      'class' => 'product-list',
    ],
  ];
  $variables['link'] = [
    '#type' => 'link',
    '#title' => t('Compare', [], ['context' => 'arch_compare']),
    '#url' => !empty($variables['url']) ? $variables['url'] : NULL,
    '#attributes' => [
      'class' => 'compare-link',
    ],
  ];
}

/**
 * Compare item theme function.
 *
 * @param array $variables
 *   Variables.
 */
function template_preprocess_compare_page(array &$variables) {
  /** @var \Drupal\arch_product\Entity\ProductInterface[] $products */
  $products = $variables['products'];
  $settings = new stdClass();
  $settings->entity_type = 'product';
  $settings->view_mode = $variables['view_mode'];
  $settings->count = count($products);

  if (
    empty($settings->entity_type)
    || empty($settings->view_mode)
  ) {
    return;
  }

  $header = [NULL];
  $rows = [];

  foreach ($products as $key => $product) {
    _arch_compare_product_build_table_rows($header, $rows, $key, $settings, $product);
  }

  $empty_group = TRUE;
  $groupkey = NULL;
  // Add css classes for different, same or empty columns.
  foreach ($rows as $key => $row) {
    if (in_array('group-header-row', $row['class'])) {
      if ($empty_group && $key !== 0) {
        $rows[$groupkey]['class'][] = 'empty-group';
      }
      $groupkey = $key;
      $empty_group = TRUE;
    }

    if (!in_array('field-value-row', $row['class'])) {
      continue;
    }

    $values = array_values($row['data']);
    array_shift($values);
    $same_values = TRUE;
    $null_values = FALSE;
    $previous_value = current($values)['data'];
    foreach ($values as $column) {
      if ($column['data'] !== $previous_value) {
        $same_values = FALSE;
      }

      $previous_value = $column['data'];
    }

    if (empty($previous_value)) {
      $null_values = TRUE;
    }

    if ($same_values) {
      $rows[$key]['class'][] = ($null_values ? 'empty' : 'same') . '-values';
    }
    else {
      $rows[$key]['class'][] = 'different-values';
    }

    if (!$null_values) {
      $empty_group = FALSE;
    }
  }

  $variables['compare_table'] = [
    '#type' => 'container',
    '#attributes' => [
      'class' => [
        'compare-table',
      ],
    ],
    'table' => [
      '#type' => 'table',
      '#header' => $header,
      '#rows' => $rows,
      '#empty' => t('There are no products selected.', [], ['context' => 'arch_compare']),
    ],
  ];
}

/**
 * Prepare product values.
 */
function _arch_compare_product_build_table_rows(&$header, &$rows, $col, $settings, ProductInterface $product) {
  if (empty($product)) {
    return;
  }
  $header[$col] = $product->getTitle();
  $bundle = $product->bundle();
  /** @var \Drupal\Core\Entity\Display\EntityViewDisplayInterface $display */
  $display = EntityViewDisplay::load($settings->entity_type . '.' . $bundle . '.' . $settings->view_mode);
  if (empty($display)) {
    return;
  }

  $params = _arch_compare_get_product_group_structure($display);
  $row = 0;
  // Build table.
  foreach ($params->groups as $group) {
    // @codingStandardsIgnoreStart
    $rows[$row]['data'][0] = [
      'data' => t($group->label, [], ['context' => 'arch_compare_group']),
      'colspan' => $settings->count + 1,
    ];
    // @codingStandardsIgnoreEnd
    $rows[$row]['class'][0] = 'group-header-row';
    $row++;
    foreach ($group->children as $field_name) {
      $field_config = FieldConfig::loadByName($display->getTargetEntityTypeId(), $bundle, $field_name);
      if (empty($field_config)) {
        continue;
      }

      $value = NULL;
      if (
        $product->hasField($field_name)
        && ($items = $product->get($field_name))
        && !$items->isEmpty()
      ) {
        $render_array = $product->get($field_name)->first()->view($settings->view_mode);
        $value = $render_array;
      }

      $rows[$row]['data'][0]['data'] = $field_config->getLabel();
      $rows[$row]['data'][0]['class'] = 'field-label field--name-' . Html::cleanCssIdentifier($field_name);
      $rows[$row]['class'][0] = 'field-value-row';
      $rows[$row]['data'][$col]['data'] = $value;
      $rows[$row]['data'][$col]['class'] = 'field-value';

      $row++;
    }
  }
}

/**
 * Get product group structure.
 *
 * @param Drupal\Core\Entity\Display\EntityViewDisplayInterface $display
 *   Display.
 *
 * @return object
 *   Group structure.
 */
function _arch_compare_get_product_group_structure(EntityViewDisplayInterface $display) {
  $params = new stdClass();
  $params->entity_type = $display->getTargetEntityTypeId();
  $params->bundle = $display->getTargetBundle();
  $params->mode = $display->getMode();
  $params->context = 'view';

  $params->groups = [];
  $params->groups = field_group_info_groups($params->entity_type, $params->bundle, $params->context, $params->mode);

  $params->parents = [];
  foreach ($params->groups as $name => $group) {
    foreach ($group->children as $child) {
      if ($child !== $group->parent_name) {
        $params->parents[$child] = $name;
      }
    }
  }
  return $params;
}

/**
 * Implements hook_form_FORM_ID_alter().
 */
function arch_compare_form_product_type_edit_form_alter(&$form, FormStateInterface $form_state, $form_id) {
  /** @var \Drupal\arch_product\Form\ProductTypeForm $form_object */
  $form_object = $form_state->getFormObject();
  /** @var \Drupal\arch_product\Entity\ProductType $product_type */
  $product_type = $form_object->getEntity();

  $form['compare'] = [
    '#type' => 'details',
    '#title' => t('Compare settings', [], ['context' => 'arch_compare']),
    '#group' => 'product_type_features',
    '#weight' => 200,
  ];

  $form['compare']['comparable'] = [
    '#type' => 'checkbox',
    '#title' => t('Comparable', [], ['context' => 'arch_compare']),
    '#default_value' => $product_type->getThirdPartySetting('arch_compare', 'comparable'),
  ];

  $form['#entity_builders'][] = 'arch_compare_form_product_type_form_builder';
}

/**
 * Entity builder for the product type form with compare options.
 *
 * @see arch_compare_form_product_type_edit_form_alter()
 */
function arch_compare_form_product_type_form_builder($entity_type, ProductTypeInterface $type, &$form, FormStateInterface $form_state) {
  if ($form_state->getValue('comparable')) {
    $type->setThirdPartySetting('arch_compare', 'comparable', TRUE);
  }
  else {
    $type->unsetThirdPartySetting('arch_compare', 'comparable');
  }
}

/**
 * Implements hook_entity_extra_field_info().
 */
function arch_compare_entity_extra_field_info() {
  $extra = [];

  /** @var \Drupal\arch_product\Entity\ProductTypeInterface $bundle */
  foreach (ProductType::loadMultiple() as $bundle) {
    if (!$bundle->getThirdPartySetting('arch_compare', 'comparable')) {
      continue;
    }
    $extra['product'][$bundle->id()]['display']['compare_item'] = [
      'label' => t('Compare action', [], ['context' => 'arch_compare']),
      'visible' => FALSE,
    ];
  }

  return $extra;
}

/**
 * Implements hook_entity_view().
 */
function arch_compare_entity_view(array &$build, EntityInterface $entity, EntityViewDisplayInterface $display, $view_mode) {
  if ($entity->getEntityTypeId() !== 'product') {
    return;
  }

  if ($display->getComponent('compare_item')) {
    $build['compare_item'] = [
      '#theme' => 'compare_item',
      '#product' => $entity,
      '#attached' => [
        'library' => [
          'arch_compare/compare_item',
        ],
      ],
    ];
  }
}

Главная | Обратная связь

drupal hosting | друпал хостинг | it patrol .inc