Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

JAKALA: Add Calendar display option to Views Block for Events #753

Merged
merged 18 commits into from
Oct 1, 2024
Merged
Show file tree
Hide file tree
Changes from 6 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
<?php

declare(strict_types=1);

namespace Drupal\ys_views_basic\Controller;

use Drupal\Core\Ajax\AjaxResponse;
use Drupal\Core\Ajax\ReplaceCommand;
use Drupal\Core\Controller\ControllerBase;
use Drupal\ys_views_basic\Service\EventsCalendarInterface;
use Symfony\Component\DependencyInjection\ContainerInterface;
use Symfony\Component\HttpFoundation\Request;

/**
* Returns an Ajax response containing calendar data for the given month.
*/
final class EventsCalendarController extends ControllerBase {

/**
* The controller constructor.
*/
public function __construct(
private EventsCalendarInterface $eventsCalendar,
) {}

/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container): self {
return new self(
$container->get('ys_views_basic.events_calendar'),
);
}

/**
* Builds the response.
*/
public function __invoke(Request $request): AjaxResponse {
$response = new AjaxResponse();

if (!$request->request->has('calendar_id') || !$request->request->has('month') || !$request->request->has('year')) {
return $response;
}

// Calendar wrapper that needs to be updated.
$calendar_id = $request->request->get('calendar_id');
$month = $request->request->get('month');
$year = $request->request->get('year');

$events_calendar = $this->eventsCalendar
->getCalendar($month, $year);

$calendar = [
'#theme' => 'views_basic_events_calendar',
'#month_data' => $events_calendar,
'#cache' => [
'tags' => ['node_list:event'],
],
];

$response->addCommand(new ReplaceCommand($calendar_id, $calendar));

return $response;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@
use Drupal\Core\Field\FieldItemListInterface;
use Drupal\Core\Field\FormatterBase;
use Drupal\Core\Plugin\ContainerFactoryPluginInterface;
use Drupal\Core\Render\Renderer;
use Drupal\ys_views_basic\Service\EventsCalendarInterface;
use Drupal\ys_views_basic\ViewsBasicManager;
use Symfony\Component\DependencyInjection\ContainerInterface;

Expand All @@ -28,14 +28,14 @@ class ViewsBasicDefaultFormatter extends FormatterBase implements ContainerFacto
*
* @var \Drupal\ys_views_basic\ViewsBasicManager
*/
protected $viewsBasicManager;
protected ViewsBasicManager $viewsBasicManager;

/**
* The renderer service.
* The Events Calendar service.
*
* @var \Drupal\Core\Render\Renderer
* @var \Drupal\ys_views_basic\Service\EventsCalendarInterface
*/
protected $rendererService;
protected EventsCalendarInterface $eventsCalendar;

/**
* Constructs an views basic default formatter object.
Expand All @@ -54,10 +54,10 @@ class ViewsBasicDefaultFormatter extends FormatterBase implements ContainerFacto
* The view mode.
* @param array $third_party_settings
* Any third party settings.
* @param \Drupal\ys_views_basic\Plugin\ViewsBasicManager $viewsBasicManager
* @param \Drupal\ys_views_basic\ViewsBasicManager $viewsBasicManager
* The views basic manager service.
* @param \Drupal\Core\Render\Renderer $renderer_service
* Drupal Core renderer service.
* @param \Drupal\ys_views_basic\Service\EventsCalendarInterface $eventsCalendar
* The Events Calendar service.
*/
public function __construct(
string $plugin_id,
Expand All @@ -68,7 +68,7 @@ public function __construct(
string $view_mode,
array $third_party_settings,
ViewsBasicManager $viewsBasicManager,
Renderer $renderer_service,
EventsCalendarInterface $eventsCalendar,
) {
parent::__construct(
$plugin_id,
Expand All @@ -78,20 +78,15 @@ public function __construct(
$label,
$view_mode,
$third_party_settings,
$this->rendererService = $renderer_service,
);
$this->viewsBasicManager = $viewsBasicManager;
$this->eventsCalendar = $eventsCalendar;
}

/**
* {@inheritdoc}
*/
public static function create(
ContainerInterface $container,
array $configuration,
$plugin_id,
$plugin_definition,
) {
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$plugin_id,
$plugin_definition,
Expand All @@ -101,33 +96,57 @@ public static function create(
$configuration['view_mode'],
$configuration['third_party_settings'],
$container->get('ys_views_basic.views_basic_manager'),
$container->get('renderer'),
$container->get('ys_views_basic.events_calendar')
);
}

/**
* Define how the field type is showed.
*/
public function viewElements(FieldItemListInterface $items, $langcode) {
public function viewElements(FieldItemListInterface $items, $langcode): array {

$elements = [];

foreach ($items as $delta => $item) {
// Get decoded parameters.
$paramsDecoded = json_decode($item->getValue()['params'], TRUE);

if ($paramsDecoded['filters']['types'][0] === 'event' && $paramsDecoded['view_mode'] === 'calendar') {
// Calculate the remaining time until the end of the current month.
$now = new \DateTime();
$end_of_month = new \DateTime('last day of this month 23:59:59');
$remaining_time_in_seconds = $end_of_month->getTimestamp() - $now->getTimestamp();

$view = $this->viewsBasicManager->getView('rendered', $item->getValue()['params']);
$events_calendar = $this->eventsCalendar
->getCalendar(date('m'), date('Y'));

$elements[$delta] = [
'#theme' => 'views_basic_formatter_default',
'#view' => $view,
// Extract exposed filters from the view and place them separately.
// This is necessary because we are conditionally displaying
// specific exposed filters based on field configuration.
// By placing the exposed filters outside of the view rendering
// context, we ensure that they do not get re-rendered
// when AJAX operations are performed on the view,
// allowing for better control over which filters are displayed
// and maintaining the expected user interface behavior.
'#exposed' => $view['#view']->exposed_widgets,
];
$elements[$delta] = [
'#theme' => 'views_basic_events_calendar',
'#month_data' => $events_calendar,
'#cache' => [
'tags' => ['node_list:event'],
// Set max-age to the remaining time until the end of the month.
'max-age' => $remaining_time_in_seconds,
'contexts' => ['timezone'],
],
];
}
else {
$view = $this->viewsBasicManager->getView('rendered', $item->getValue()['params']);
$elements[$delta] = [
'#theme' => 'views_basic_formatter_default',
'#view' => $view,
// Extract exposed filters from the view and place them separately.
// This is necessary because we are conditionally displaying
// specific exposed filters based on field configuration.
// By placing the exposed filters outside of the view rendering
// context, we ensure that they do not get re-rendered
// when AJAX operations are performed on the view,
// allowing for better control over which filters are displayed
// and maintaining the expected user interface behavior.
'#exposed' => $view['#view']->exposed_widgets,
];
}
}

return $elements;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -219,6 +219,11 @@ public function formElement(
'#suffix' => '</div>',
];

// Define the state for when the view mode is 'calendar' once.
$calendarViewInvisibleState = [
$formSelectors['view_mode_input_selector'] => ['value' => 'calendar'],
];

$fieldOptionValue = ($items[$delta]->params) ? $this->viewsBasicManager->getDefaultParamValue('field_options', $items[$delta]->params) : [];
$form['group_user_selection']['entity_and_view_mode']['field_options'] = [
'#type' => 'checkboxes',
Expand All @@ -230,6 +235,7 @@ public function formElement(
'#title' => $this->t('Field Display Options'),
'#tree' => TRUE,
'#default_value' => empty($fieldOptionValue) ? ['show_thumbnail'] : $fieldOptionValue,
'#states' => ['invisible' => $calendarViewInvisibleState],
'show_thumbnail' => [
'#states' => [
'visible' => [
Expand All @@ -252,14 +258,9 @@ public function formElement(
'#title' => $this->t('Exposed Filter Options'),
'#tree' => TRUE,
'#default_value' => ($items[$delta]->params) ? $this->viewsBasicManager->getDefaultParamValue('exposed_filter_options', $items[$delta]->params) : [],
'#states' => ['invisible' => $calendarViewInvisibleState],
'show_year_filter' => [
'#states' => [
'visible' => [
$formSelectors['entity_types_ajax'] => [
'value' => 'post',
],
],
],
'#states' => ['visible' => [$formSelectors['entity_types_ajax'] => ['value' => 'post']]],
],
];

Expand All @@ -269,9 +270,8 @@ public function formElement(
'#description' => $this->t("Enter a custom label for the <strong>Category Filter</strong>. This label will be displayed to users as the filter's name. If left blank, the default label <strong>Category</strong> will be used."),
'#default_value' => ($items[$delta]->params) ? $this->viewsBasicManager->getDefaultParamValue('category_filter_label', $items[$delta]->params) : NULL,
'#states' => [
'visible' => [
$formSelectors['show_category_filter_selector'] => ['checked' => TRUE],
],
'visible' => [$formSelectors['show_category_filter_selector'] => ['checked' => TRUE]],
'invisible' => $calendarViewInvisibleState,
],
];

Expand All @@ -287,9 +287,8 @@ public function formElement(
'#prefix' => '<div id="edit-category-included-terms">',
'#suffix' => '</div>',
'#states' => [
'visible' => [
$formSelectors['show_category_filter_selector'] => ['checked' => TRUE],
],
'visible' => [$formSelectors['show_category_filter_selector'] => ['checked' => TRUE]],
'invisible' => $calendarViewInvisibleState,
],
];

Expand All @@ -302,6 +301,7 @@ public function formElement(
'#tags' => TRUE,
'#target_type' => 'taxonomy_term',
'#default_value' => ($items[$delta]->params) ? $this->viewsBasicManager->getDefaultParamValue('terms_include', $items[$delta]->params) : [],
'#states' => ['invisible' => $calendarViewInvisibleState],
];

$form['group_user_selection']['filter_and_sort']['terms_exclude'] = [
Expand All @@ -313,6 +313,7 @@ public function formElement(
'#tags' => TRUE,
'#target_type' => 'taxonomy_term',
'#default_value' => ($items[$delta]->params) ? $this->viewsBasicManager->getDefaultParamValue('terms_exclude', $items[$delta]->params) : [],
'#states' => ['invisible' => $calendarViewInvisibleState],
];

$form['group_user_selection']['filter_and_sort']['term_operator'] = [
Expand All @@ -329,7 +330,7 @@ public function formElement(
'term-operator-item',
],
],

'#states' => ['invisible' => $calendarViewInvisibleState],
];

// Gets the view mode options based on Ajax callbacks or initial load.
Expand All @@ -345,6 +346,7 @@ public function formElement(
'#validated' => 'true',
'#prefix' => '<div id="edit-sort-by">',
'#suffix' => '</div>',
'#states' => ['invisible' => $calendarViewInvisibleState],
];

$form['group_user_selection']['entity_specific']['event_time_period'] = [
Expand All @@ -357,11 +359,8 @@ public function formElement(
],
'#default_value' => ($items[$delta]->params) ? $this->viewsBasicManager->getDefaultParamValue('event_time_period', $items[$delta]->params) : 'future',
'#states' => [
'visible' => [
$formSelectors['entity_types_ajax'] => [
'value' => 'event',
],
],
'visible' => [$formSelectors['entity_types_ajax'] => ['value' => 'event']],
'invisible' => $calendarViewInvisibleState,
],
];

Expand All @@ -377,6 +376,7 @@ public function formElement(
'limit' => $this->t('Limit to'),
'pager' => $this->t('Pagination after'),
],
'#states' => ['invisible' => $calendarViewInvisibleState],
];

$limitTitle = $this->t('Items');
Expand All @@ -397,6 +397,7 @@ public function formElement(
'#required' => TRUE,
'#prefix' => '<div id="edit-limit">',
'#suffix' => '</div>',
'#states' => ['invisible' => $calendarViewInvisibleState],
];

$form['group_user_selection']['options']['offset'] = [
Expand All @@ -408,6 +409,7 @@ public function formElement(
'#attributes' => [
'placeholder' => 0,
],
'#states' => ['invisible' => $calendarViewInvisibleState],
];

$element['group_params']['params'] = [
Expand All @@ -420,6 +422,7 @@ public function formElement(
'views-basic--params',
],
],
'#states' => ['invisible' => $calendarViewInvisibleState],
];

$form['#attached']['library'][] = 'ys_views_basic/ys_views_basic';
Expand Down
Loading