|
|
|
@@ -0,0 +1,213 @@
|
|
|
|
|
<?php
|
|
|
|
|
|
|
|
|
|
namespace Drupal\configurable_views_pane\Plugin\Block;
|
|
|
|
|
|
|
|
|
|
use Drupal\Core\Access\AccessResult;
|
|
|
|
|
use Drupal\Core\Block\BlockBase;
|
|
|
|
|
use Drupal\Core\Form\FormStateInterface;
|
|
|
|
|
use Drupal\Core\Session\AccountInterface;
|
|
|
|
|
use Drupal\views\Views;
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Configurable Views block for Page Manager / Panels variants.
|
|
|
|
|
*
|
|
|
|
|
* @Block(
|
|
|
|
|
* id = "booking_configurable_views_pane",
|
|
|
|
|
* admin_label = @Translation("Configurable Views Pane"),
|
|
|
|
|
* category = @Translation("Custom")
|
|
|
|
|
* )
|
|
|
|
|
*/
|
|
|
|
|
final class ConfigurableViewsPaneBlock extends BlockBase {
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* {@inheritdoc}
|
|
|
|
|
*/
|
|
|
|
|
public function defaultConfiguration(): array {
|
|
|
|
|
return [
|
|
|
|
|
'view_id' => '',
|
|
|
|
|
'display_id' => '',
|
|
|
|
|
'arguments' => '',
|
|
|
|
|
] + parent::defaultConfiguration();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* {@inheritdoc}
|
|
|
|
|
*/
|
|
|
|
|
protected function blockAccess(AccountInterface $account): AccessResult {
|
|
|
|
|
$view_id = $this->normalizedViewId((string) ($this->configuration['view_id'] ?? ''));
|
|
|
|
|
$display_id = trim((string) ($this->configuration['display_id'] ?? ''));
|
|
|
|
|
if ($view_id === '' || $display_id === '') {
|
|
|
|
|
return AccessResult::forbidden();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$view = Views::getView($view_id);
|
|
|
|
|
if (!$view || !$this->displayExists($view_id, $display_id)) {
|
|
|
|
|
return AccessResult::forbidden();
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$result = AccessResult::allowedIf($view->access($display_id, $account));
|
|
|
|
|
if ($view->storage) {
|
|
|
|
|
$result = $result->addCacheableDependency($view->storage);
|
|
|
|
|
}
|
|
|
|
|
return $result;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* {@inheritdoc}
|
|
|
|
|
*/
|
|
|
|
|
public function build(): array {
|
|
|
|
|
$view_id = $this->normalizedViewId((string) ($this->configuration['view_id'] ?? ''));
|
|
|
|
|
$display_id = trim((string) ($this->configuration['display_id'] ?? ''));
|
|
|
|
|
if ($view_id === '' || $display_id === '') {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$view = Views::getView($view_id);
|
|
|
|
|
if (!$view || !$this->displayExists($view_id, $display_id)) {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$args = $this->parseArguments((string) ($this->configuration['arguments'] ?? ''));
|
|
|
|
|
$build = $view->buildRenderable($display_id, $args, FALSE);
|
|
|
|
|
if (!is_array($build)) {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$build['#attributes']['class'][] = 'configurable-views-pane-block';
|
|
|
|
|
return $build;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* {@inheritdoc}
|
|
|
|
|
*/
|
|
|
|
|
public function blockForm($form, FormStateInterface $form_state): array {
|
|
|
|
|
$form = parent::blockForm($form, $form_state);
|
|
|
|
|
|
|
|
|
|
$form['view_id'] = [
|
|
|
|
|
'#type' => 'textfield',
|
|
|
|
|
'#title' => $this->t('View ID'),
|
|
|
|
|
'#default_value' => (string) ($this->configuration['view_id'] ?? ''),
|
|
|
|
|
'#required' => TRUE,
|
|
|
|
|
'#description' => $this->t('Machine name of the view. Example: audio_resource_embedded_player'),
|
|
|
|
|
];
|
|
|
|
|
$form['display_id'] = [
|
|
|
|
|
'#type' => 'textfield',
|
|
|
|
|
'#title' => $this->t('Display ID'),
|
|
|
|
|
'#default_value' => (string) ($this->configuration['display_id'] ?? ''),
|
|
|
|
|
'#required' => TRUE,
|
|
|
|
|
'#description' => $this->t('Display machine name. Example: block_1, page_1, block_nid_1770'),
|
|
|
|
|
];
|
|
|
|
|
$form['arguments'] = [
|
|
|
|
|
'#type' => 'textarea',
|
|
|
|
|
'#title' => $this->t('Contextual arguments'),
|
|
|
|
|
'#default_value' => (string) ($this->configuration['arguments'] ?? ''),
|
|
|
|
|
'#rows' => 2,
|
|
|
|
|
'#description' => $this->t('Optional contextual arguments. Separate multiple values with comma, pipe, or newline. Example: 1770'),
|
|
|
|
|
];
|
|
|
|
|
|
|
|
|
|
return $form;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* {@inheritdoc}
|
|
|
|
|
*/
|
|
|
|
|
public function blockValidate($form, FormStateInterface $form_state): void {
|
|
|
|
|
parent::blockValidate($form, $form_state);
|
|
|
|
|
|
|
|
|
|
$view_id = $this->normalizedViewId((string) $form_state->getValue('view_id'));
|
|
|
|
|
$display_id = trim((string) $form_state->getValue('display_id'));
|
|
|
|
|
|
|
|
|
|
if ($view_id === '') {
|
|
|
|
|
$form_state->setErrorByName('view_id', $this->t('View ID is required.'));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
if ($display_id === '') {
|
|
|
|
|
$form_state->setErrorByName('display_id', $this->t('Display ID is required.'));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$view = Views::getView($view_id);
|
|
|
|
|
if (!$view) {
|
|
|
|
|
$form_state->setErrorByName('view_id', $this->t('View %view was not found.', ['%view' => $view_id]));
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if (!$this->displayExists($view_id, $display_id)) {
|
|
|
|
|
$displays = implode(', ', $this->displayIds($view_id));
|
|
|
|
|
$form_state->setErrorByName(
|
|
|
|
|
'display_id',
|
|
|
|
|
$this->t('Display %display does not exist on view %view. Available displays: %available', [
|
|
|
|
|
'%display' => $display_id,
|
|
|
|
|
'%view' => $view_id,
|
|
|
|
|
'%available' => $displays !== '' ? $displays : '<none>',
|
|
|
|
|
])
|
|
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* {@inheritdoc}
|
|
|
|
|
*/
|
|
|
|
|
public function blockSubmit($form, FormStateInterface $form_state): void {
|
|
|
|
|
parent::blockSubmit($form, $form_state);
|
|
|
|
|
$this->configuration['view_id'] = $this->normalizedViewId((string) $form_state->getValue('view_id'));
|
|
|
|
|
$this->configuration['display_id'] = trim((string) $form_state->getValue('display_id'));
|
|
|
|
|
$this->configuration['arguments'] = trim((string) $form_state->getValue('arguments'));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Checks whether a display exists on a view.
|
|
|
|
|
*/
|
|
|
|
|
private function displayExists(string $view_id, string $display_id): bool {
|
|
|
|
|
return in_array($display_id, $this->displayIds($view_id), TRUE);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Returns known display IDs for a view.
|
|
|
|
|
*
|
|
|
|
|
* @return string[]
|
|
|
|
|
* Display IDs.
|
|
|
|
|
*/
|
|
|
|
|
private function displayIds(string $view_id): array {
|
|
|
|
|
$view = Views::getView($view_id);
|
|
|
|
|
if (!$view || !$view->storage) {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$definitions = (array) ($view->storage->get('display') ?? []);
|
|
|
|
|
return array_values(array_filter(array_map(static function ($id) {
|
|
|
|
|
return is_scalar($id) ? trim((string) $id) : '';
|
|
|
|
|
}, array_keys($definitions)), static function ($id) {
|
|
|
|
|
return $id !== '';
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Parses arguments from a config string.
|
|
|
|
|
*
|
|
|
|
|
* @return string[]
|
|
|
|
|
* Clean argument list.
|
|
|
|
|
*/
|
|
|
|
|
private function parseArguments(string $raw): array {
|
|
|
|
|
$raw = trim($raw);
|
|
|
|
|
if ($raw === '') {
|
|
|
|
|
return [];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
$parts = preg_split('/[\r\n,\|]+/', $raw) ?: [];
|
|
|
|
|
return array_values(array_filter(array_map(static function ($item) {
|
|
|
|
|
return trim((string) $item);
|
|
|
|
|
}, $parts), static function ($item) {
|
|
|
|
|
return $item !== '';
|
|
|
|
|
}));
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
* Normalizes view machine names.
|
|
|
|
|
*/
|
|
|
|
|
private function normalizedViewId(string $value): string {
|
|
|
|
|
$value = strtolower(trim($value));
|
|
|
|
|
return preg_replace('/[^a-z0-9_]+/', '_', $value) ?: '';
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
}
|