Crear vistas en Drupal ofrece una amplia gama de opciones para personalizar la presentación de contenido. A veces, es posible que necesites añadir filtros contextuales personalizados para lograr una funcionalidad específica. Aquí te mostraremos cómo puedes hacerlo.
Supongamos que queremos filtrar una vista de forma directa por un campo del usuario, por ejemplo el departamento. Lo primero que debemos hacer es crear una clase que extienda ArgumentPluginBase. La ubicación debe ser, dentro de tu módulo, en la ruta "/src/Plugin/views/argument". En este caso, este sería un ejemplo de la clase que podríamos tener:
<?php
namespace Drupal\my_module\Plugin\views\argument;
use Drupal\Core\Session\AccountProxy;
use Drupal\Core\Database\Connection;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Logger\LoggerChannelFactoryInterface;
use Drupal\views\Plugin\views\argument\ArgumentPluginBase;
use Symfony\Component\DependencyInjection\ContainerInterface;
/**
* Argument handler for Filtering the node by User Department.
*
* @ingroup views_argument_handlers
*
* @ViewsArgument("contextual_filter_department")
*/
class NodeFilterDepartment extends ArgumentPluginBase {
/**
* The current user data object.
*
* @var \Drupal\Core\Session\AccountProxy
*/
protected $currentUser;
/**
* The current database connection.
*
* @var \Drupal\Core\Database\Connection
*/
protected $database;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The logger factory.
*
* @var \Drupal\Core\Logger\LoggerChannelFactoryInterface
*/
protected $loggerFactory;
public function __construct(
array $configuration,
$plugin_id,
$plugin_definition,
AccountProxy $current_user,
Connection $database,
EntityTypeManagerInterface $entity_type_manager,
LoggerChannelFactoryInterface $logger_factory
) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->currentUser = $current_user;
$this->database = $database;
$this->entityTypeManager = $entity_type_manager;
$this->loggerFactory = $logger_factory;
}
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static(
$configuration,
$plugin_id,
$plugin_definition,
$container->get('current_user'),
$container->get('database'),
$container->get('entity_type.manager'),
$container->get('logger.factory')
);
}
public function query($group_by = FALSE) {
$current_user_id = $this->currentUser->id();
$tids_department_user = $this->getDepartmentIdForUser($current_user_id);
// Query to filter results.
$nid_filter_query = $this->database->select('node', 'node');
$nid_filter_query->leftJoin('node__department', 'node__department', 'node.nid = node__department.entity_id');
$nid_filter_query->fields('node', ['nid']);
$nid_filter_query->condition('node__department.department_target_id', $tids_department_user, 'IN');
$result = $nid_filter_query->execute()->fetchAllAssoc('nid');
$nid_filter_ids = array_keys($result);
if (!empty($nid_filter_ids)) {
$this->query->addWhere(0, 'node_field_data.nid', $nid_filter_ids, 'IN');
}
}
/**
* Example method to retrieve the department IDs for a user.
*
* This method assumes that the department is stored as a field on the user
* entity (e.g., field_department). The method takes the user ID and returns
* an array of department IDs related to that user.
*
* @param int $user_id
* The user ID for whom the department IDs should be retrieved.
*
* @return array
* An array of department IDs related to the given user.
*/
private function getDepartmentIdsForUser($user_id) {
$department_ids = [];
$user = $this->entityTypeManager->getStorage('user')->load($user_id);
if ($user) {
$departments = $user->get('field_department')->getValue();
foreach ($departments as $department) {
$department_ids[] = $department['target_id'];
}
}
return $department_ids;
}
}
Después en el archivo .module de nuestro módulo, registraremos este filtro con el uso del siguiente código:
/**
* Implements hook_views_data_alter().
*/
function my_module_views_data_alter(&$data) {
$data['node']['contextual_filter_department'] = [
'argument' => [
'title' => t('Filter the results by User Department.'),
'id' => 'contextual_filter_department',
],
];
}
Hola a todos, soy desarrollador de Drupal, especializado en Backend, aunque a veces hago mis pinitos con Frontend, ¡Hasta sé centrar un div! Cuando no estoy sumergido en el código, probablemente me encontraréis explorando nuevos mundos en mis videojuegos favoritos o disfrutando de tiempo de calidad con los míos. Me apasiona combinar la tecnología con la creatividad, y siempre estoy buscando nuevas formas de aprender y crecer en mi campo. ¿Unimos fuerzas y creamos algo?
Si te gusta mi trabajo y quieres echar una mano:
Buy me a coffe!