Actions

Plugins - advanced/es: Difference between revisions

From LimeSurvey Manual

(Created page with "<syntaxhighlight lang="xml"> <updaters> <updater> <stable> 1</stable> <type> descansar</type> <source> https://comfortupdate.limesurvey.org/index.php?r=limestorerest</source...")
(Created page with "(La etiqueta fuente anterior apunta a la API REST de LimeStore, que se utilizará para todas las extensiones disponibles en nuestro LimeStore).")
Line 251: Line 251:
</syntaxhighlight>
</syntaxhighlight>


(The source tag above points to the LimeStore REST API, which will be used for all extensions available in our LimeStore.)
(La etiqueta fuente anterior apunta a la API REST de LimeStore, que se utilizará para todas las extensiones disponibles en nuestro LimeStore).


{| class="wikitable"
{| class="wikitable"

Revision as of 07:59, 7 September 2023

Descripción general

A partir de LimeSurvey 2.05, LimeSurvey admitirá oficialmente complementos. Algunos complementos serán compatibles con el equipo de LimeSurvey y se incluirán en el núcleo. Algunos contarán con el apoyo de otros fuera del equipo de LimeSurvey. Para ayudarlo a encontrarlos, consulte los Complementos de terceros disponibles y agréguele su propio complemento.

Los complementos permiten a los usuarios personalizar la funcionalidad de su instalación y al mismo tiempo beneficiarse de las actualizaciones periódicas de software.

Esta documentación está destinada a desarrolladores que están ampliando LimeSurvey para su propio uso o para sus clientes; Esta documentación no ayudará a los usuarios finales.

Los complementos deben implementar la interfaz iPlugin. Recomendamos ampliar su clase de complemento desde la clase PluginBase.

Los complementos se desarrollan en torno a un mecanismo de event.

Configuración del complemento

Al ampliar, se beneficia de la funcionalidad común requerida por los complementos que ya hemos implementado para usted. Una de estas funciones es la implementación de la función getPluginSettings. Esta función debe devolver una matriz que describa las opciones de configuración para el usuario.

El complemento de ejemplo expone solo 1 configuración configurable, el mensaje que mostrará.

protegted $configuración = matriz(
 'logo' => matriz(
 'tipo' => 'logotipo',
 'ruta' => 'assets/logo.png'
 ) ,

'mensaje' => matriz(
 'tipo' => 'cadena',
 'etiqueta' => 'Mensaje'
 )
);

La matriz contiene un nombre para cada configuración como clave. Los valores son matrices que contienen los metadatos requeridos.

Los tipos admitidos son:

  • logo
  • int (número entero)
  • cadena (alfanumérica)
  • texto
  • html
  • relevancia
  • info
  • contraseña
  • fecha!
  • seleccionar

Además de escribir, hay otras claves disponibles:

  • etiqueta, define una etiqueta
  • predeterminado, define un valor para mostrar si no se especifica ningún valor (solo para la configuración global, no para la configuración de la encuesta)
  • actual, define el valor actual.
  • solo lectura: se muestra la configuración como ¡solo lectura
  • htmlOptions, las htmlOptions de la parte de entrada (consulte el manual de Yii [[1]])
  • pluginOptions, para algunas configuraciones (html o select): establece la opción del widget
  • labelOptions: htmlOptions de la etiqueta
  • controlOptions: htmlOptions del contenedor de etiqueta y entrada

Puede encontrar un ejemplo de complemento utilizando todas las configuraciones reales en exampleSettings

Leer y escribir configuraciones de complemento

Es posible leer y escribir la configuración del complemento directamente desde el código del complemento.

Ejemplo:

$miConfiguración = $this->get('miConfiguración');
$this->set('miConfiguración', $miConfiguración + 1);

Puede obtener un valor predeterminado si la configuración es nula:

$miConfiguración = $this->get('miConfiguración', nulo, nulo, 10); // ¡10 es el valor predeterminado

Eventos

Los complementos se suscriben a eventos y pueden interactuar con LimeSurvey cuando se activa el evento. Para obtener una lista de los eventos disponibles actualmente, consulte Eventos complementarios.

API

Los complementos sólo deberían extender LimeSurvey a través de su API "pública". Esto significa que usar directamente las clases que se encuentran en el código fuente es una mala práctica. Aunque no podemos obligarte a no hacerlo, corres el riesgo de tener un complemento roto con cada actualización menor que hacemos.

En la medida de lo posible, interactúe con LimeSurvey solo a través de los métodos descritos aquí. Lo mismo que para eventos.

El objeto API está disponible a través de $this->api cuando se extiende desde PluginBase; de lo contrario, puede obtenerlo desde la instancia de PluginManager que se pasa al constructor de sus complementos.

Se pueden agregar nuevas funciones al objeto API a pedido.

Extensión de formulario (New in 6 )

Introducción

El sistema de extensión de formularios es una forma más general de ampliar formularios en el núcleo de LimeSurvey sin agregar un nuevo evento para cada formulario.

Consta de los siguientes componentes:

  • ¡Un módulo global llamado FormExtensionService
  • ¡Una biblioteca de clases de entrada que los complementos pueden agregar a la inicialización del módulo anterior
  • Un widget, junto con renderizadores personalizados, que se utilizan en los archivos de vista de LimeSurvey

Cada formulario se identifica mediante una cadena de posición, como<form name><dot><tab name> . Ejemplo: globalsettings.general o globalsettings.security .

El objetivo detrás de un sistema basado en clases sin HTML es liberar a los autores del complemento del trabajo para actualizar el HTML cuando cambia el HTML principal. Aún así, el autor puede utilizar el tipo RawHtmlInput si es necesario.

Una cosa que no puede hacer en este sistema es agregar "nuevas pestañas de formulario".

Ejemplo

Para agregar una nueva entrada a un formulario desde un complemento, use el siguiente código de su función init():

TODO: Guardar en la configuración del complemento en lugar de global

// En la parte superior del archivo
use LimeSurvey\Libraries\FormExtension\Inputs\TextInput;
use LimeSurvey\Libraries\FormExtension\SaveFailedException;

// Dentro de init()
Yii::app()->formExtensionService->add(
 'globalsettings.general',
 new TextInput([
 'name' => 'myinput', 
 'label' => 'Etiqueta',
 'disabled' => true,
 'tooltip' => 'Moo moo moo',
 'help' => 'Algún texto de ayuda', 
 'save' => function($solicitud, $conexión) {
 $valor = $solicitud->getPost('myinput');
 if ($value === 'algún valor no válido') {
 throw new SaveFailedException("No se pudo guardar la entrada personalizada 'myinput'");
 } else {
 ConfiguraciónGlobal::setSetting('myinput', $value);
 }
 } ,
 'load' => function () {
 return getGlobalSetting('myinput');
 }
 ])
);

Validación

La validación de la entrada se realiza en la función save (ver ejemplo arriba). Si el valor publicado no es válido, lanza una SaveFailedException y se mostrará al usuario un mensaje flash de advertencia.

Formularios admitidos

Se pueden ampliar las siguientes formas:

  • configuración global.general (New in 6.0.0 )

Si desea agregar soporte para otro formulario principal, debe aplicar el siguiente cambio en una solicitud de extracción:

En el archivo de vista, agregue:

!¡NORTE! <?php
use LimeSurvey\Libraries\FormExtension\FormExtensionWidget;
use LimeSurvey\Libraries\FormExtension\Inputs\DefaultBaseRenderer;
?> 
... más HTML
<?= FormExtensionWidget::render(
    App()-> formExtensionService->getAll('globalsettings.security'),
 nuevo DefaultBaseRenderer()
); ?>

Es posible que tengas que crear una nueva clase de renderizador basada en DefaultBaseRenderer , si el formulario HTML es diferente a otros formularios. Es posible que también necesite ampliar la clase de renderizador predeterminada con tipos de entrada que aún no se han agregado.

El segundo cambio que debe hacer es agregar una llamada a la clase de servicio de extensión de formulario en la acción del controlador que guarda el formulario:

$request = App()->request;
Yii::app()->formExtensionService->applySave('globalsettings', $request);

¡Eso es todo!

Localización (New in 3 )

Es posible que los complementos agreguen sus propios archivos locales. El formato de archivo utilizado es .mo, igual que las traducciones principales. Los archivos deben almacenarse en

<plugin root folder>/lugar/<language> /<language> .mes

dónde "<language> " es una palabra de dos letras como "de" o "fr".

Para usar el archivo local específico, use la función del complemento gT:

$this->gT("Un texto de complemento que debe traducirse");

Si la cadena proporcionada no se puede encontrar en el archivo local específico del complemento, la función buscará en los archivos locales principales. Por tanto, es seguro utilizar cadenas como "Cancelar":

$this->gT("Cancelar"); // ¡Se traducirá incluso si "Cancelar" no está en el archivo local del complemento

Si está utilizando vistas junto con su complemento, debe usar

$plugin->gT("Traducirme");

para hacer una traducción específica del complemento en su vista.

Puede utilizar el archivo limesurvey.pot como ejemplo de cómo puede verse un archivo pot. Esto se importa a su herramienta de traducción.

Herramientas

Una herramienta de código abierto para editar archivos po y mo es [2].

Iniciando sesión (New in 3 )

Si desea registrar algo desde su complemento, simplemente escriba

$this->log("Tu mensaje");

El nivel de registro predeterminado es rastreo, pero puede proporcionar otro nivel de registro como segundo argumento opcional:

$this->log("¡Algo salió mal!", CLogger::LEVEL_ERROR);

El archivo de registro se puede encontrar en la carpeta

<limesurvey root folder>/tmp/runtime/plugin.log

El nombre de su complemento se utiliza automáticamente como categoría. Una buena manera de ver solo los errores de su complemento es usar grep (en Linux):

$ cola -f tmp/runtime/plugin.log | grep<your plugin name>

Más información sobre cómo configurar el registro en Yii 1: Optional_settings#Logging_settings.

Actualizaciones de extensiones (New in 4 )

Desde la versión 4.0.0 de LimeSurvey, existe un sistema para gestionar las actualizaciones de complementos y otras extensiones. Para utilizar este sistema, su archivo de extensión config.xml debe incluir la configuración del actualizador.

<updaters> <updater>
<stable> 1</stable> 
<type> descansar</type> 
<source> https://comfortupdate.limesurvey.org/index.php?r=limestorerest</source> 
<manualUpdateUrl> https://somedownloadlink.com/maybegithub</manualUpdateUrl> 
</updater> 
</updaters>

(La etiqueta fuente anterior apunta a la API REST de LimeStore, que se utilizará para todas las extensiones disponibles en nuestro LimeStore).

Updater tag descriptions
Tag Description
stable "1" if this source only gives you stable version numbers; "0" if the source will also provide unstable versions, like 0.3.3-beta.
type For now, only type rest is supported. It's easy to add new updater types (version checkers), like git, wget, etc.
source The URL to fetch new versions from.
manualUpdateUrl URL which the user can go to to update the latest version of the extension.
automaticUpdateUrl TODO

If you don't want to supply an updater, you should put the following text in your config XML file:

<updaters disabled="disabled">
</updaters>

This way, you tell the system that you purposefully disabled the update system, and didn't just forget to add it.

The new plugin UpdateCheck - installed and activated by default - checks for new updates for all installed extensions when a super admin logs in, asynchronously, max one time every 24 hours. If any new versions are found, a notification is pushed.

Available updates

If a new security update is found, the notification will open automatically and be styled in "danger" class.

Available security updates

You can manually check for updates by going to the plugin manager view and click on "Check updates". Note that this button is only visible if the UpdateCheck plugin is activated.

Manually check for updates

Under the hood

This section provides a brief overview over the extension updater implementation.

The extension updater is part of the ExtensionInstaller library. Below is a UML diagram for the classes related to the updater process.

Extension updater UML diagram

Program flow when Yii starts:

 Yii init
   VersionFetcherServiceLocator->init()
     Add REST version fetcher
   ExtensionUpdaterServiceLocator->init()
     Add PluginUpdater
     TODO: Add an updater for each extension type (theme, question template, ...)

Program flow when running the UpdaterCheck plugin:

 Get all updaters from ExtensionUpdaterServiceLocator
 Loop each updater
   For each updater, loop through version fetchers configured by <updater> XML
     For each version fetcher, contact remote source and get version information
 Compose all versions into a notification

The checkAll method in the UpdateCheck plugin provides an example of how to query all extensions for new versions.

Adding new version fetchers

To add a new custom version fetcher, run this during Yii initialization:

$service = \Yii::app()->versionFetcherServiceLocator
$service->addVersionFetcherType(
  'myNewVersionFetcherType',
  function (\SimpleXMLElement $updaterXml) {
    return new MyNewVersionFetcher($updaterXml);
  }
);

Of course, the class MyNewVersionFetcher has to subclass VersionFetcher.

To use your new version fetcher, configure the type tag in the updater XML to use myNewVersionFetcherType (instead of e.g. rest).

Adding new extension updaters

To add a new custom extension updater, run this during Yii initialization:

$service = \Yii::app()->extensionUpdaterServiceLocator;
$service->addUpdaterType(
  'myNewExtensionUpdater',
  function () {
    return MyNewExtensionUpdater::createUpdaters();
  }
);

Class MyNewExtensionUpdater has to subclass ExtensionUpdater.

The top type tag in config.xml ('plugin', 'theme', ...) will control which extension updater are used for this extension. The system is not fully customizable yet, since you also need to add a custom ExtensionInstaller, menu items, etc. But in theory, and maybe in the future, it should be possible to add a new type of extension this way.

Extension installer

The extension installer library consists of two abstract classes:

  • ExtensionInstaller
  • FileFetcher

The ExtensionInstaller is subclassed for each extension type, like PluginInstaller, QuestionThemeInstaller, etc.

The FileFetcher is subclassed for each different way to fetch files. Currently, only uploaded zip files are supported, but in the future, there could be a Github or LimeStore fetcher too.

Special plugins

Available plugins

Tutorial

This step-by-step tutorial shows how to create a plugin that sends a post request on every survey response submission. The tutorial shows you how to create and save global and per-survey settings, how to register events and more.