Más con Symfony

14.10. Creando un plugin

Como ya disponemos de un sistema para mejorar los formularios mediante una configuración sencilla basada en YAML, se va a publicar en forma de plugin para que la pueda disfrutar toda la comunidad. Si nunca has publicado un plugin, puede que pienses que es algo complicado, pero ahora vas a ver que no es tan difícil.

La estructura de archivos del plugin es la siguiente:

sfFormYamlEnhancementsPlugin/
  config/
    sfFormYamlEnhancementsPluginConfiguration.class.php
  lib/
    config/
      sfFormYamlEnhancementsConfigHandler.class.php
    form/
      sfFormYamlEnhancer.class.php
  test/
    unit/
      form/
        sfFormYamlEnhancerTest.php

Para facilitar la instalación del plugin se van a realizar algunos pequeños cambios. La creación y conexión del objeto que mejora los formularios se va a encapsular en la clase de configuración del plugin:

class sfFormYamlEnhancementsPluginConfiguration extends sfPluginConfiguration
{
  public function initialize()
  {
    if ($this->configuration instanceof sfApplicationConfiguration)
    {
      $enhancer = new sfFormYamlEnhancer($this->configuration->getConfigCache());
      $enhancer->connect($this->dispatcher);
    }
  }
}

El archivo de las pruebas debe ser actualizado para que apunte al script de inicialización del proyecto:

include dirname(__FILE__).'/../../../../../test/bootstrap/unit.php';

// ...

Por último, activa el plugin en ProjectConfiguration:

class ProjectConfiguration extends sfProjectConfiguration
{
  public function setup()
  {
    $this->enablePlugins('sfFormYamlEnhancementsPlugin');
  }
}

Si quieres ejecutar las pruebas desde el plugin, puedes conectarlas en ProjectConfiguration:

class ProjectConfiguration extends sfProjectConfiguration
{
  // ...

  public function setupPlugins()
  {
    $this->pluginConfigurations['sfFormYamlEnhancementsPlugin']->connectTests();
  }
}

Ahora las pruebas del plugin se ejecutan siempre que se ejecute una tarea de tipo test:*.

Pruebas del plugin

Figura 14.7 Pruebas del plugin

Todas las clases se encuentran ahora dentro del directorio del plugin, pero existe un problema: las pruebas unitarias dependen de archivos que todavía se encuentran en el proyecto. Esto significa que quien quiera ejecutar las pruebas no va a poder hacerlo a menos que disponga exactamente de los mismos archivos en su proyecto.

Para solucionar este problema debemos asilar el código que realiza llamadas a la cache de configuración de forma que se pueda redefinir dentro del archivo de pruebas y en su lugar utilice un archivo de datos forms.yml.

class sfFormYamlEnhancer
{
  // ...

  public function enhance(sfForm $form)
  {
    $this->loadWorker();
    $this->doEnhance($form->getFormFieldSchema(), $form);
  }

  public function loadWorker()
  {
    require_once $this->configCache->checkConfig('config/forms.yml');
  }

  // ...
}

Se puede redefinir el método ->loadWorker() en nuestro archivo de pruebas para que llame directamente al gestor propio de configuración. La clase CommentForm también se debe trasladar al archivo de pruebas y el archivo forms.yml se debe guardar dentro del directorio test/fixtures del plugin.

include dirname(__FILE__).'/../../../../../test/bootstrap/unit.php';

$t = new lime_test(6);

class sfFormYamlEnhancerTest extends sfFormYamlEnhancer
{
  public function loadWorker()
  {
    if (!class_exists('sfFormYamlEnhancementsWorker', false))
    {
      $configHandler = new sfFormYamlEnhancementsConfigHandler();
      $code = $configHandler->execute(array(dirname(__FILE__).'/../../fixtures/forms.yml'));

      $file = tempnam(sys_get_temp_dir(), 'sfFormYamlEnhancementsWorker');
      file_put_contents($file, $code);

      require $file;
    }
  }
}

class CommentForm extends BaseForm
{
  public function configure()
  {
    $this->setWidget('body', new sfWidgetFormTextarea());
    $this->setValidator('body', new sfValidatorString(array('min_length' => 12)));
  }
}

$configuration = $configuration->getApplicationConfiguration(
  'frontend', 'test', true, null, $configuration->getEventDispatcher());

$enhancer = new sfFormYamlEnhancerTest($configuration->getConfigCache());

// ...

Crear el paquete del plugin es muy sencillo si has instalado previamente el plugin sfTaskExtraPlugin. Simplemente ejecuta la tarea plugin:package y se creará el paquete utilizando la información proporcionada para cada pregunta del plugin.

$ php symfony plugin:package sfFormYamlEnhancementsPlugin

Nota El código de este artículo se ha publicado como plugin y está disponible para descargar desde el sitio de los plugins de Symfony:

http://symfony-project.org/plugins/sfFormYamlEnhancementsPlugin

Este plugin incluye todo lo que se ha mostrado en este capítulo y mucho más, ya que incluye soporte para los archivos widgets.yml y validators.yml, así como integración con la tarea i18n:extract para internacionalizar fácilmente tus formularios.