acquia_commercemanager-8.x-1.122/modules/acm_promotion/src/Plugin/Block/AcmPromotionContainerBlock.php
modules/acm_promotion/src/Plugin/Block/AcmPromotionContainerBlock.php
<?php
namespace Drupal\acm_promotion\Plugin\Block;
use Drupal\Core\Block\BlockBase;
use Drupal\Core\Utility\Token;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Form\FormStateInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Provides a block to display promotion information to users.
*
* @Block(
* id = "acm_promotion_container_block",
* admin_label = @Translation("Acquia Commerce Promotion Container Block"),
* category = @Translation("Acquia Commerce Promotion"),
* context = { *
* "node" = @ContextDefinition("entity:node", required = FALSE),
* }
* )
*/
class AcmPromotionContainerBlock extends BlockBase implements ContainerFactoryPluginInterface {
/**
* Token manager.
*
* @var \Drupal\Core\Utility\Token
*/
protected $tokenManager;
/**
* Constructs a new AcmPromotionContainerBlock.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin ID for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Utility\Token $token_manager
* Token manager.
*/
public function __construct(array $configuration,
$plugin_id,
$plugin_definition,
Token $token_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->tokenManager = $token_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('entity_type.manager'),
$container->get('entity_display.repository'),
$container->get('current_user')
);
}
/**
* {@inheritdoc}
*/
public function blockForm($form, FormStateInterface $form_state) {
$form = parent::blockForm($form, $form_state);
// Retrieve existing configuration for this block.
$config = $this->getConfiguration();
$display_mode_options = [];
$display_modes = acm_promotion_get_display_modes();
foreach ($display_modes as $display_mode => $label) {
if ($display_mode === 'full') {
continue;
}
$display_mode_options[$display_mode] = $label;
}
$form['display_mode'] = [
'#title' => t('Display Mode'),
'#description' => t(
'Select the promotion display mode you want this block to use to render promotion nodes.'
),
'#type' => 'select',
'#options' => $display_mode_options,
'#default_value' => (isset($config['display_mode']) && !empty($config['display_mode']) ? $config['display_mode'] : 'teaser'),
'#required' => TRUE,
];
$container_mode_options = acm_promotion_get_container_modes();
$form['container_mode'] = [
'#title' => t('Container Mode'),
'#description' => t(
'Select "Always On" if you want to target a all "always on" promotion nodes.<br />
Select "Sku" if you want to target a promotions that target a a specific sku.<br />
Select "Promotion" if you want to target a specific promotion node.<br />'
),
'#type' => 'select',
'#options' => $container_mode_options,
'#default_value' => (isset($config['container_mode']) && !empty($config['container_mode']) ? $config['container_mode'] : 'always_on'),
'#required' => TRUE,
];
// TODO In the future it would be nice to have different fields for when
// 'sku' or 'promotion' are selected. We could potentially add an
// auto complete field.
$form['argument'] = [
'#title' => t('Argument'),
'#description' => t(
'If the container mode is "Sku", this should be set to the sku you would like to target.<br />
If the container mode is "Promotion" this should be the title of the promotion node you would like to target.'
),
'#type' => 'textfield',
'#states' => [
'visible' => [
[
':input[name="settings[container_mode]"]' => ['value' => 'sku'],
],
[
':input[name="settings[container_mode]"]' => ['value' => 'promotion'],
],
],
],
'#default_value' => (isset($config['argument']) && !empty($config['argument']) ? $config['argument'] : ''),
];
return $form;
}
/**
* {@inheritdoc}
*/
public function blockValidate($form, FormStateInterface $form_state) {
// Make sure argument is present if needed.
if (
in_array($form_state->getValue('container_mode'), ['sku', 'promotion'])
&& empty($form_state->getValue('argument'))
) {
$form_state->setErrorByName('argument', t('You must provide an argument.'));
}
}
/**
* {@inheritdoc}
*/
public function blockSubmit($form, FormStateInterface $form_state) {
// Save our custom settings when the form is submitted.
$this->setConfigurationValue('display_mode', $form_state->getValue('display_mode'));
$this->setConfigurationValue('container_mode', $form_state->getValue('container_mode'));
$this->setConfigurationValue('argument', $form_state->getValue('argument'));
}
/**
* {@inheritdoc}
*/
public function build() {
// Grab display mode from configuration or default to teaser.
$config = $this->getConfiguration();
$display_mode = (isset($config['display_mode']) && !empty($config['display_mode']) ? $config['display_mode'] : 'teaser');
$container_mode = (isset($config['container_mode']) && !empty($config['container_mode']) ? $config['container_mode'] : 'always_on');
$argument = '';
if (isset($config['argument']) && !empty($config['argument'])) {
$argument = 'data-arg="' . $config['argument'] . '"';
}
// Allow token replacement (ie [node:field_skus]).
$contexts = array_filter($this->getContextValues(), function ($value) {
return !empty($value);
});
$argument = $this->tokenManager->replace($argument, $contexts);
// TODO May need to update this in the future to make this more flexible,
// perhaps with a theme function.
$html = sprintf(
'<div class="acm-promo-container" data-mode="%s" data-display="%s" %s></div>',
$container_mode,
$display_mode,
$argument
);
return ['#markup' => $html];
}
}
