Este articulo surge a raíz de un requerimiento sobre un proyecto en el cual trabajo. El requerimiento consite en poder seleccionar desde una vista con formato de Tabla uno o varios nodos (que estan en el resultado de la vista) para generar un informe a cada uno de ellos a través de una operacion en bulk.
Para poder resolverlo utilice el modulo contrib Views Bulk Operations (VBO) que nos acerca bastante a la solución. Este modulo se integra a Views y extiende ya de por si las operaciones que se pueden realizar en bulk utilizando un campo Global propio de este módulo similar al que nos brinda el core de drupal para operaciones masivas y además nos provee de una API para poder extenderlo que nos permite, entre otras cosas, agregar acciones u operaciones custom.
Lo primero que tenemos que hacer es instalar el modulo y activarlo
composer require drupal/views_bulk_operations
drush en views_bulk_operations
Ahora pasamos a crear nuestra action custom
Para empezar, creamos un nuevo modulo (por ahora nos alcanzará con el info.yml file del módulo) o podemos utlizar un modulo custom que se esté usando.
Nuestra action debemos crearla dentro de la ruta src/Plugin/Action
. Será una clase que va a contener dos partes, anotaciones y la definición de la clase en si.
#1 Annotation
/**
* Este Action Plugin nos permite generar informes de manera masiva sobre
* las entidades que son resultado de la vista
*
* @Action(
* id = "generar_informe",
* label = @Translation("Generar informe"),
* type = "",
* confirm = FALSE,
* requirements = {
* "_permission" = "acceso a generar informe",
* "_custom_access" = FALSE
* },
* )
Con esta annotation se establece que lo que estamos definiendo es un plugin de tipo Action. Dentro de esta definicion vamos a especificar valores de opciones del Plugin:
id
: identificador del pluginlabel
: Texto que será el utilizado para mostrar al usuariotype
: especifica si esta action será utilizada por un content type o podemos dejarlo vacío y estará disponible para todos los contents typesconfirm
: si se setea en TRUE, el parámetroconfirm_form_route_name
va a reemplazar la ruta del formulario de confirmación de action que utiliza Views Bulk Operations como predeterminado, y le proporciona a la acción un paso de confirmación. Sin embargo, si no se establece el parámetroconfirm_form_route_name
, la configuración de confirmación no tendrá efecto, ya que en su lugar se utilizará el parámetroconfirm_form_route
establecido.requirements
: array de requerimientos que deben ser cumplidos para que se ejecute la action. Las opciones posibles son:_permission
: si el usuario tiene este permiso la action va a ser mostrada en la lista de seleccion de acciones masivas._custom_access
: si se setea a TRUE, el metodocustomAccess
de esta action será llamado para determinar si el usuario puede correr esa action en una entidad especifica (ver su implementacion por default enViewsBulkOperationsActionBase
). Si es FALSE o no está definido, el métodocustomAccess
no se llamará.
Si requirements
no está definido entonces la action será visible y podrá ser ejecutada por todos los usuario que tengan acceso a la vista.
#2 Action class
Para ya contar con un conjunto de métodos predefinidos lo mejor es extender de la clase ViewsBulkOperationsActionBase. Hay dos métodos que debemos implementar: access y execute o executeMultiple (executeMutiple es requerido por ActionInterface pero tiene una implementacion por defecto en ViewsBulkOperationsActionBase que llama a $this->execute() en un loop para todas las entidades seleccionadas)
class GenerarInforme extends ViewsBulkOperationsActionBase {
use StringTranslationTrait;
/**
* {@inheritdoc}
*/
public function execute($entity = NULL) {
// Do some processing..
// Don't return anything for a default completion message, otherwise return translatable markup.
return $this->t('Some result');
}
/**
* {@inheritdoc}
*/
public function access($object, AccountInterface $account = NULL, $return_as_object = FALSE) {
if ($object->getEntityType() === 'node') {
$access = $object->access('update', $account, TRUE)
->andIf($object->status->access('edit', $account, TRUE));
return $return_as_object ? $access : $access->isAllowed();
}
// Other entity types may have different
// access methods and properties.
return TRUE;
}
}
Como decia anteriormente, el método execute
será el encargado realizar el procesamiento que sea necesario y el método access
se encarga, a través del la validación que necesitemos permitir el acceso a ver la operación en el listado de operaciones disponibles o no. Recoredemos que el metodo access
se llamara solo si en las annotations dentro del array de requirements
se define en TRUE
la opción "_custom_access"
.
Recordar que en la vista que queremos utilizar esta action debemos agrear un campo Global "Views bulk operations"
En la configuración del campo vamos a encontrar nuestra custom action para poder agregarla a la lista de opciones de operaciones en masa