x

Capítulos principais

  1. LimeSurvey Cloud vs LimeSurvey CE
  2. Guia de início rápido - LimeSurvey 3.0+
  3. Instalação - LimeSurvey CE
  4. Como criar um bom inquérito (guia)
  5. Iniciando
  6. Administrando o LimeSurvey
  7. Questionários - introdução
  8. Configurações do questionário
  9. Menu da pesquisa
  10. Estrutura da pesquisa
  11. Perguntas - introdução
  12. Grupos de perguntas - introdução
  13. Questionários - gerenciamento
  14. Opções da barra de ferramentas do questionário
  15. Questionário multilíngue
  16. ExpressionScript Engine - Guia de início rápido
  17. Recursos avançados e não categorizados
  18. FAQ geral
  19. Solução de problemas
  20. Soluções alternativas
  21. Licença
  22. Registro de mudanças da versão
  23. Plugins
 Actions

Plugins

From LimeSurvey Manual

Esta página pode ter sido traduzida automaticamente e conter erros. Ver o original em inglês · Melhorar esta tradução
This page is a translated version of the page Plugins and the translation is 100% complete.

Visão geral

O LimeSurvey pode ter novas funcionalidades adicionadas por meio de plugins. Ele já inclui vários plugins principais. Confira também nossa lista de plugins de terceiros e, quem sabe, adicione o seu próprio plugin a ela no futuro!

Os plugins permitem que os usuários personalizem as funcionalidades de sua instalação e, ao mesmo tempo, continuem se beneficiando das atualizações regulares do software.

Esta documentação destina-se a desenvolvedores que estendem o LimeSurvey para uso próprio ou para seus clientes; os usuários finais não encontrarão ajuda nesta documentação.

Os plugins devem implementar a interface iPlugin. Recomendamos que a classe do seu plugin estenda a classe PluginBase.

Os plugins são desenvolvidos em torno de um mecanismo de eventos.

Configurações do plugin

Ao estender a classe, você se beneficia das funcionalidades comuns exigidas pelos plugins, que já implementamos para você. Uma dessas funções é a implementação da função getPluginSettings. Essa função deve retornar um array que descreve as opções de configuração para o usuário.

O plugin de exemplo expõe apenas 1 configuração, a mensagem que será exibida.

protected $settings = array(
    'logo' => array(
          'type' => 'logo',
          'path' => 'assets/logo.png'
     ),

     'message' => array(
          'type' => 'string',
          'label' => 'Message'
     )
);

O array contém um nome para cada configuração como chave. Os valores são arrays que contêm os metadados necessários.

Os tipos suportados são:

  • logo
  • int (número inteiro)
  • string (alfanumérico)
  • text
  • html
  • relevance
  • info
  • password
  • date
  • select

Além de type, várias outras chaves estão disponíveis:

  • label, define um rótulo
  • default, define um valor a ser exibido se nenhum valor for especificado (somente para configurações globais, não para configurações do inquérito)
  • current, define o valor atual.
  • readOnly : exibe as configurações como somente leitura
  • htmlOptions, as htmlOptions da parte de entrada (veja o manual do Yii [[1]])
  • pluginOptions, para algumas configurações (html ou select) : define a opção do widget
  • labelOptions : htmlOptions do rótulo
  • controlOptions : htmlOptions do contêiner do rótulo e da entrada
  • localized : se verdadeiro, o valor é armazenado por idioma. A entrada é enviada como name[language] e current deve ser um array indexado pelo código de idioma.
  • language : usado junto com localized. Pode ser um único código de idioma ou (New in X.Y.Z ) um array de códigos de idioma para exibir uma entrada por idioma (veja Configurações de plugin localizadas)

Você pode encontrar um exemplo de plugin que usa todas as configurações atuais em exampleSettings

Ler e gravar as configurações do plugin

É possível ler e gravar as configurações do plugin diretamente a partir do código do seu plugin.

Exemplo:

$mySetting = $this->get('mySetting');
$this->set('mySetting', $mySetting + 1);

Você pode obter um valor padrão caso a configuração seja nula:

$mySetting = $this->get('mySetting', null, null, 10);  // 10 is default

Configurações de plugin específicas do inquérito

Dois eventos são usados para criar configurações de plugin específicas do inquérito:

  • newSurveySettings
  • beforeSurveySettings

Exemplo para desativar um plugin em um inquérito específico:

    public function init()
    {
        $this->subscribe('beforeSurveySettings');
        $this->subscribe('newSurveySettings');
        // Other events...
    }

    public function beforeSurveySettings()
    {
	    $event = $this->event;
	    $surveyId = intval($event->get('survey'));

        $event->set(
            "surveysettings.{$this->id}",
            [
                'name' => get_class($this),
                'settings' => [
                    'isActive' => [
                        'type' => 'boolean',
                        'label' => 'isActive',
                        'current' => $this->getIsActive($surveyId),
                        'help' => 'Activate plugin for this survey'
                    ],
                ]
            ]
        );
    }

    public function newSurveySettings()
    {
        $event = $this->event;
        foreach ($event->get('settings') as $name => $value)
        {
            $this->set($name, $value, 'Survey', $event->get('survey'), false);
        }
    }

    private function getIsActive(int $sid): bool
    {
        return (bool) $this->get('isActive', 'Survey', $sid, false);
    }

<span id="Localized_plugin_settings_ (New in 7.4 )">

Configurações de plugin localizadas (New in 7.4 )

Para mostrar um campo por idioma do inquérito para a mesma configuração, defina localized como true e passe a lista de idiomas em language. O nome do idioma é adicionado ao rótulo de cada campo.

    public function beforeSurveySettings()
    {
        $event = $this->event;
        $surveyId = intval($event->get('survey'));
        $survey = Survey::model()->findByPk($surveyId);

        $event->set(
            "surveysettings.{$this->id}",
            [
                'name' => get_class($this),
                'settings' => [
                    'errorText' => [
                        'type' => 'text',
                        'label' => $this->gT('Error text'),
                        'localized' => true,
                        'language' => $survey->getAllLanguages(),
                        // Array indexed by language code, e.g. ['en' => '...', 'de' => '...']
                        'current' => $this->get('errorText', 'Survey', $surveyId, []),
                    ],
                ]
            ]
        );
    }

O valor enviado é um array indexado pelo código de língua, portanto a função newSurveySettings do exemplo anterior o guarda sem qualquer alteração. Para ler o texto do idioma atual:

$errorTexts = $this->get('errorText', 'Survey', $surveyId, []);
$errorText = $errorTexts[App()->getLanguage()] ?? '';

Eventos

Os plugins subscrevem eventos e podem interagir com o LimeSurvey quando o evento é disparado. Para ver a lista de eventos atualmente disponíveis, consulte Eventos de plugins.

API

Os plugins só devem expandir o LimeSurvey através da sua API "pública". Isso significa que usar diretamente classes encontradas no código-fonte é uma má prática. Embora não possamos impedi-lo, você corre o risco de ter um plugin quebrado a cada atualização menor que fizermos.

Sempre que possível, interaja com o LimeSurvey apenas através dos métodos descritos aqui. O mesmo vale para os eventos.

O objeto da API está disponível através de $this->api quando se estende a partir de PluginBase; caso contrário, você pode obtê-lo a partir da instância do PluginManager que é passada ao construtor dos seus plugins.

Novas funções podem ser adicionadas ao objeto da API mediante solicitação.

<span id="Form_extension (New in 6 )">

Extensão de formulários (New in 6 )

Introdução

O sistema de extensão de formulários é uma forma mais genérica de expandir os formulários do LimeSurvey principal sem adicionar um novo evento para cada formulário.

É composto pelos seguintes componentes:

  • Um módulo global chamado FormExtensionService
  • Uma biblioteca de classes de entrada que os plugins podem adicionar à inicialização do módulo acima
  • Um widget, juntamente com renderizadores personalizados, que é usado nos arquivos de visualização do LimeSurvey

Cada formulário é identificado por uma string de posição, como <form name><dot><tab name>. Exemplo: globalsettings.general ou globalsettings.security.

O objetivo de um sistema baseado em classes, sem HTML, é livrar os autores de plugins do trabalho de atualizar o HTML quando o HTML principal muda. Ainda assim, o autor pode usar o tipo RawHtmlInput se necessário.

Uma coisa que você não pode fazer neste sistema é adicionar novas abas de formulário.

Exemplo

Para adicionar um novo campo a um formulário a partir de um plugin, use o seguinte código na sua função init():

TODO: Save in plugin settings instead of global

// At top of file
use LimeSurvey\Libraries\FormExtension\Inputs\TextInput;
use LimeSurvey\Libraries\FormExtension\SaveFailedException;

// Inside init()
Yii::app()->formExtensionService->add(
    'globalsettings.general',
    new TextInput([
        'name' => 'myinput',
        'label' => 'Label',
        'disabled' => true,
        'tooltip' => 'Moo moo moo',
        'help' => 'Some help text',
        'save' => function($request, $connection) {
            $value = $request->getPost('myinput');
            if ($value === 'some invalid value') {
                throw new SaveFailedException("Could not save custom input 'myinput'");
            } else {
                SettingGlobal::setSetting('myinput', $value);
            }
        },
        'load' => function () {
            return getGlobalSetting('myinput');
        }
    ])
);

Validação

A validação da entrada é feita na função save (veja o exemplo acima). Se o valor enviado for inválido, lance uma SaveFailedException e uma mensagem de aviso será exibida ao usuário.

Formulários compatíveis

Os seguintes formulários podem ser expandidos:

  • globalsettings.general (New in 6.0.0 )

Se quiser adicionar suporte a outro formulário principal, você precisa aplicar a seguinte alteração em um pull request:

No arquivo de visualização, adicione:

<?php
use LimeSurvey\Libraries\FormExtension\FormExtensionWidget;
use LimeSurvey\Libraries\FormExtension\Inputs\DefaultBaseRenderer;
?>
... more HTML
<?= FormExtensionWidget::render(
    App()->formExtensionService->getAll('globalsettings.security'),
    new DefaultBaseRenderer()
); ?>

Talvez seja necessário criar uma nova classe de renderização baseada em DefaultBaseRenderer, caso o HTML do formulário seja diferente dos outros formulários. Também pode ser necessário expandir a classe de renderização padrão com tipos de entrada ainda não adicionados.

A segunda alteração necessária é adicionar uma chamada à classe de serviço de extensão de formulário na ação do controlador que salva o formulário:

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

É só isso!

<span id="Localization_ (New in 3 )">

Localização (New in 3 )

Os plugins podem adicionar seus próprios arquivos de idioma. O formato de arquivo utilizado é .mo, o mesmo das traduções principais. Os arquivos devem ser armazenados em

<plugin root folder>/locale/<language>/<language>.mo

onde "<language>" é uma palavra de duas letras, como "de" ou "fr".

Para usar o arquivo de idioma específico, utilize a função gT do plugin:

$this->gT("A plugin text that needs to be translated");

Se o texto informado não for encontrado no arquivo de idioma específico do plugin, a função procurará nos arquivos de idioma principais. Portanto, é seguro usar textos como "Cancelar":

$this->gT("Cancel");  // Will be translated even if "Cancel" is not in the plugin locale file

Se você estiver usando views junto com o seu plugin, deve usar

$plugin->gT("Translate me");

para fazer a tradução específica do plugin na sua view.

Você pode usar o arquivo limesurvey.pot como exemplo de como um arquivo pot pode ser. Ele é importado para a sua ferramenta de tradução.

Ferramentas

Uma ferramenta de código aberto para editar arquivos po e mo é o Poedit.

<span id="Logging_ (New in 3 )">

Registro de log (New in 3 )

Se quiser registrar algo no log a partir do seu plugin, basta escrever

$this->log("Your message");

O nível de log padrão é trace, mas você pode informar outro nível de log como segundo argumento opcional:

$this->log("Something went wrong!", CLogger::LEVEL_ERROR);

O arquivo de log pode ser encontrado na pasta

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

O nome do seu plugin é usado automaticamente como categoria. Uma boa maneira de ver apenas os erros do seu plugin é usar o grep (no Linux):

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

<span id="Logging_plugin_deactivation_due_to_error_ (New in 6.13.3 )">

Registro de log da desativação de plugin devido a erro (New in 6.13.3 )

Desde a versão 5 do LimeSurvey, um plugin pode ser desativado automaticamente em caso de erro de PHP.

Um e-mail é enviado automaticamente ao administrador do LimeSurvey. Você pode usar o sistema de log para gerar um alerta para os demais administradores do servidor.

Por exemplo: para enviar uma mensagem de alerta

                // Plugin error happen, plugin was disable : send email using CLogRoute
                'pluginError' => array(
                    'class' => 'CEmailLogRoute', // https://www.yiiframework.com/doc/api/1.1/CEmailLogRoute
                    'categories' => 'application.model.plugin.setLoadError', // A plugin was disable
                    'subject' => '[ERROR] Plugin deactivated',
                    'emails' => ['webmaster@example.org'],
                    'sentFrom' => 'noreply@example.org',
                    'enabled' => 1, // enabled here
                )

Mais informações sobre como configurar o registro de log no Yii 1: Configurações de log.

<span id="Extension_updates_ (New in 4 )">

Atualizações de extensões (New in 4 )

Desde a versão 4.0.0 do LimeSurvey, existe um sistema para lidar com atualizações de plugins e de outras extensões. Para usar esse sistema, o arquivo config.xml da sua extensão precisa incluir a configuração do atualizador.

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

(A tag source acima aponta para a API REST da LimeStore, que será usada para todas as extensões disponíveis na nossa LimeStore.)

Descrições das tags do atualizador
Tag Descrição
stable "1" se esta fonte fornece apenas números de versões estáveis; "0" se a fonte também fornecer versões instáveis, como 0.3.3-beta.
type Por enquanto, apenas o tipo rest é suportado. É fácil adicionar novos tipos de atualizador (verificadores de versão), como git, wget etc.
source A URL de onde buscar novas versões.
manualUpdateUrl URL que o usuário pode acessar para atualizar para a última versão da extensão.
automaticUpdateUrl TODO

Se você não quiser fornecer um atualizador, deve colocar o seguinte texto no arquivo XML de configuração:

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

Dessa forma, você informa ao sistema que desabilitou o sistema de atualização de propósito e não apenas esqueceu de adicioná-lo.

O novo plugin UpdateCheck - instalado e ativado por padrão - verifica se há novas atualizações para todas as extensões instaladas quando um superadministrador faz login, de forma assíncrona, no máximo uma vez a cada 24 horas. Se novas versões forem encontradas, uma notificação é enviada.

Atualizações disponíveis

Se uma nova atualização de segurança for encontrada, a notificação será aberta automaticamente e exibida com o estilo da classe "danger".

Atualizações de segurança disponíveis

Você pode verificar manualmente se há atualizações acessando a visualização do gerenciador de plugins e clicando em "Check updates". Observe que esse botão só fica visível se o plugin UpdateCheck estiver ativado.

Verificar atualizações manualmente

Por baixo dos panos

Esta seção apresenta uma breve visão geral da implementação do atualizador de extensões.

O atualizador de extensões faz parte da biblioteca ExtensionInstaller. Abaixo está um diagrama UML das classes relacionadas ao processo de atualização.

Diagrama UML do atualizador de extensões

Fluxo do programa quando o Yii inicia:

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

Fluxo do programa ao executar o plugin UpdaterCheck:

 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

O método checkAll no plugin UpdateCheck fornece um exemplo de como consultar todas as extensões em busca de novas versões.

Adicionar novos buscadores de versão

Para adicionar um novo buscador de versão personalizado, execute o seguinte durante a inicialização do Yii:

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

Naturalmente, a classe MyNewVersionFetcher deve ser uma subclasse de VersionFetcher.

Para usar o seu novo buscador de versão, configure a tag type no XML do atualizador para usar myNewVersionFetcherType (em vez de, por exemplo, rest).

Adicionar novos atualizadores de extensão

Para adicionar um novo atualizador de extensão personalizado, execute o seguinte durante a inicialização do Yii:

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

A classe MyNewExtensionUpdater deve ser uma subclasse de ExtensionUpdater.

A tag type de nível superior no config.xml ('plugin', 'theme', ...) controla quais atualizadores de extensão são usados para esta extensão. O sistema ainda não é totalmente personalizável, pois também é necessário adicionar um ExtensionInstaller personalizado, itens de menu etc. Mas, em teoria, e talvez no futuro, será possível adicionar um novo tipo de extensão dessa forma.

Instalador de extensões

A biblioteca do instalador de extensões consiste em duas classes abstratas:

  • ExtensionInstaller
  • FileFetcher

O ExtensionInstaller é estendido por uma subclasse para cada tipo de extensão, como PluginInstaller, QuestionThemeInstaller etc.

O FileFetcher é estendido por uma subclasse para cada forma diferente de obter arquivos. Atualmente, somente arquivos zip enviados por upload são suportados, mas no futuro também poderá haver um buscador para Github ou LimeStore.

Tutorial

Este tutorial passo a passo mostra como criar um plugin que envia uma requisição POST a cada envio de resposta do questionário. O tutorial mostra como criar e salvar configurações globais e por questionário, como registrar eventos e muito mais.