summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAlex Pott2014-03-11 09:18:37 (GMT)
committerAlex Pott2014-03-11 09:18:37 (GMT)
commitc53879f09a2984bd392670726bbf3188db3908f1 (patch)
tree664f347faf7a47d7f4420818c920a1c76c6ecbbe
parent29b519c560230312e6d5b8c29c9f05f0dc930465 (diff)
Issue #1978924 by tim.plunkett, ParisLiakos, disasm, Luxian, vijaycs85, YesCT, vaibhavjain, Pancho: Convert locale_translate_export_form to a Controller.
-rw-r--r--core/lib/Drupal/Core/Form/FormBuilder.php12
-rw-r--r--core/lib/Drupal/Core/Form/FormBuilderInterface.php6
-rw-r--r--core/modules/locale/lib/Drupal/locale/Form/ExportForm.php178
-rw-r--r--core/modules/locale/lib/Drupal/locale/Form/LocaleForm.php10
-rw-r--r--core/modules/locale/locale.bulk.inc132
-rw-r--r--core/modules/locale/locale.routing.yml2
-rw-r--r--core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php94
-rw-r--r--core/tests/Drupal/Tests/Core/Form/FormTestBase.php8
8 files changed, 293 insertions, 149 deletions
diff --git a/core/lib/Drupal/Core/Form/FormBuilder.php b/core/lib/Drupal/Core/Form/FormBuilder.php
index 26a1c3d..69431a5 100644
--- a/core/lib/Drupal/Core/Form/FormBuilder.php
+++ b/core/lib/Drupal/Core/Form/FormBuilder.php
@@ -603,10 +603,14 @@ class FormBuilder implements FormBuilderInterface {
// Set a flag to indicate the the form has been processed and executed.
$form_state['executed'] = TRUE;
- // Redirect the form based on values in $form_state.
- $redirect = $this->redirectForm($form_state);
- if (is_object($redirect)) {
- return $redirect;
+ // If no response has been set, process the form redirect.
+ if (!isset($form_state['response']) && $redirect = $this->redirectForm($form_state)) {
+ $form_state['response'] = $redirect;
+ }
+
+ // If there is a response was set, return it instead of continuing.
+ if (isset($form_state['response']) && $form_state['response'] instanceof Response) {
+ return $form_state['response'];
}
}
diff --git a/core/lib/Drupal/Core/Form/FormBuilderInterface.php b/core/lib/Drupal/Core/Form/FormBuilderInterface.php
index 9166f98..0e318bb 100644
--- a/core/lib/Drupal/Core/Form/FormBuilderInterface.php
+++ b/core/lib/Drupal/Core/Form/FormBuilderInterface.php
@@ -104,6 +104,12 @@ interface FormBuilderInterface extends FormErrorInterface {
* already set $form_state['rebuild'] to cause the form processing to
* bypass submit handlers and rebuild the form instead, even if there are
* no validation errors.
+ * - response: Used when a form needs to return some kind of a
+ * \Symfony\Component\HttpFoundation\Response object, e.g., a
+ * \Symfony\Component\HttpFoundation\BinaryFileResponse when triggering a
+ * file download. If you use the $form_state['redirect'] key, it will be
+ * used to build a \Symfony\Component\HttpFoundation\RedirectResponse and
+ * will populate this key.
* - redirect: Used to redirect the form on submission. It may either be a
* string containing the destination URL, or an array of arguments
* compatible with url(). See url() for complete information.
diff --git a/core/modules/locale/lib/Drupal/locale/Form/ExportForm.php b/core/modules/locale/lib/Drupal/locale/Form/ExportForm.php
new file mode 100644
index 0000000..433c8c9
--- /dev/null
+++ b/core/modules/locale/lib/Drupal/locale/Form/ExportForm.php
@@ -0,0 +1,178 @@
+<?php
+
+/**
+ * @file
+ * Contains \Drupal\locale\Form\ExportForm.
+ */
+
+namespace Drupal\locale\Form;
+
+use Drupal\Component\Gettext\PoStreamWriter;
+use Drupal\Core\Form\FormBase;
+use Drupal\Core\Language\Language;
+use Drupal\Core\Language\LanguageManagerInterface;
+use Drupal\locale\PoDatabaseReader;
+use Symfony\Component\DependencyInjection\ContainerInterface;
+use Symfony\Component\HttpFoundation\BinaryFileResponse;
+
+/**
+ * Form for the Gettext translation files export form.
+ */
+class ExportForm extends FormBase {
+
+ /**
+ * The language manager.
+ *
+ * @var \Drupal\Core\Language\LanguageManagerInterface
+ */
+ protected $languageManager;
+
+ /**
+ * Constructs a new ExportForm.
+ *
+ * @param \Drupal\Core\Language\LanguageManagerInterface $language_manager
+ * The language manager.
+ */
+ public function __construct(LanguageManagerInterface $language_manager) {
+ $this->languageManager = $language_manager;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public static function create(ContainerInterface $container) {
+ return new static(
+ $container->get('language_manager')
+ );
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function getFormID() {
+ return 'locale_translate_export_form';
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function buildForm(array $form, array &$form_state) {
+ $languages = $this->languageManager->getLanguages();
+ $language_options = array();
+ foreach ($languages as $langcode => $language) {
+ if ($langcode != 'en' || locale_translate_english()) {
+ $language_options[$langcode] = $language->name;
+ }
+ }
+ $language_default = $this->languageManager->getDefaultLanguage();
+
+ if (empty($language_options)) {
+ $form['langcode'] = array(
+ '#type' => 'value',
+ '#value' => Language::LANGCODE_SYSTEM,
+ );
+ $form['langcode_text'] = array(
+ '#type' => 'item',
+ '#title' => $this->t('Language'),
+ '#markup' => $this->t('No language available. The export will only contain source strings.'),
+ );
+ }
+ else {
+ $form['langcode'] = array(
+ '#type' => 'select',
+ '#title' => $this->t('Language'),
+ '#options' => $language_options,
+ '#default_value' => $language_default->id,
+ '#empty_option' => $this->t('Source text only, no translations'),
+ '#empty_value' => Language::LANGCODE_SYSTEM,
+ );
+ $form['content_options'] = array(
+ '#type' => 'details',
+ '#title' => $this->t('Export options'),
+ '#collapsed' => TRUE,
+ '#tree' => TRUE,
+ '#states' => array(
+ 'invisible' => array(
+ ':input[name="langcode"]' => array('value' => Language::LANGCODE_SYSTEM),
+ ),
+ ),
+ );
+ $form['content_options']['not_customized'] = array(
+ '#type' => 'checkbox',
+ '#title' => $this->t('Include non-customized translations'),
+ '#default_value' => TRUE,
+ );
+ $form['content_options']['customized'] = array(
+ '#type' => 'checkbox',
+ '#title' => $this->t('Include customized translations'),
+ '#default_value' => TRUE,
+ );
+ $form['content_options']['not_translated'] = array(
+ '#type' => 'checkbox',
+ '#title' => $this->t('Include untranslated text'),
+ '#default_value' => TRUE,
+ );
+ }
+
+ $form['actions'] = array(
+ '#type' => 'actions'
+ );
+ $form['actions']['submit'] = array(
+ '#type' => 'submit',
+ '#value' => $this->t('Export')
+ );
+ return $form;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ public function submitForm(array &$form, array &$form_state) {
+ // If template is required, language code is not given.
+ if ($form_state['values']['langcode'] != Language::LANGCODE_SYSTEM) {
+ $language = $this->languageManager->getLanguage($form_state['values']['langcode']);
+ }
+ else {
+ $language = NULL;
+ }
+ $content_options = isset($form_state['values']['content_options']) ? $form_state['values']['content_options'] : array();
+ $reader = new PoDatabaseReader();
+ $languageName = '';
+ if ($language != NULL) {
+ $reader->setLangcode($language->id);
+ $reader->setOptions($content_options);
+ $languages = $this->languageManager->getLanguages();
+ $languageName = isset($languages[$language->id]) ? $languages[$language->id]->name : '';
+ $filename = $language->id .'.po';
+ }
+ else {
+ // Template required.
+ $filename = 'drupal.pot';
+ }
+
+ $item = $reader->readItem();
+ if (!empty($item)) {
+ $uri = tempnam('temporary://', 'po_');
+ $header = $reader->getHeader();
+ $header->setProjectName($this->config('system.site')->get('name'));
+ $header->setLanguageName($languageName);
+
+ $writer = new PoStreamWriter;
+ $writer->setUri($uri);
+ $writer->setHeader($header);
+
+ $writer->open();
+ $writer->writeItem($item);
+ $writer->writeItems($reader);
+ $writer->close();
+
+ $response = new BinaryFileResponse($uri);
+ $response->setContentDisposition('attachment', $filename);
+ $form_state['response'] = $response;
+ }
+ else {
+ drupal_set_message($this->t('Nothing to export.'));
+ }
+ }
+
+}
diff --git a/core/modules/locale/lib/Drupal/locale/Form/LocaleForm.php b/core/modules/locale/lib/Drupal/locale/Form/LocaleForm.php
index c06a4aa..aaa0bfa 100644
--- a/core/modules/locale/lib/Drupal/locale/Form/LocaleForm.php
+++ b/core/modules/locale/lib/Drupal/locale/Form/LocaleForm.php
@@ -22,16 +22,6 @@ class LocaleForm {
}
/**
- * Wraps locale_translate_export_form().
- *
- * @todo Remove locale_translate_export_form().
- */
- public function export() {
- module_load_include('bulk.inc', 'locale');
- return drupal_get_form('locale_translate_export_form');
- }
-
- /**
* Wraps locale_translation_status_form().
*
* @todo Remove locale_translation_status_form().
diff --git a/core/modules/locale/locale.bulk.inc b/core/modules/locale/locale.bulk.inc
index 96cf924..5f72ad8 100644
--- a/core/modules/locale/locale.bulk.inc
+++ b/core/modules/locale/locale.bulk.inc
@@ -5,11 +5,8 @@
* Mass import-export and batch import functionality for Gettext .po files.
*/
-use Drupal\Component\Gettext\PoStreamWriter;
use Drupal\locale\Gettext;
-use Drupal\locale\PoDatabaseReader;
use Drupal\Core\Language\Language;
-use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Drupal\file\FileInterface;
/**
@@ -149,135 +146,6 @@ function locale_translate_import_form_submit($form, &$form_state) {
}
/**
- * Form constructor for the Gettext translation files export form.
- *
- * @see locale_translate_export_form_submit()
- * @ingroup forms
- *
- * @deprecated in Drupal 8.x-dev, will be removed before Drupal 8.0.
- * Use \Drupal\locale\Form\LocaleForm::export().
- */
-function locale_translate_export_form($form, &$form_state) {
- $languages = language_list();
- $language_options = array();
- foreach ($languages as $langcode => $language) {
- if ($langcode != 'en' || locale_translate_english()) {
- $language_options[$langcode] = $language->name;
- }
- }
- $language_default = language_default();
-
- if (empty($language_options)) {
- $form['langcode'] = array(
- '#type' => 'value',
- '#value' => Language::LANGCODE_SYSTEM,
- );
- $form['langcode_text'] = array(
- '#type' => 'item',
- '#title' => t('Language'),
- '#markup' => t('No language available. The export will only contain source strings.'),
- );
- }
- else {
- $form['langcode'] = array(
- '#type' => 'select',
- '#title' => t('Language'),
- '#options' => $language_options,
- '#default_value' => $language_default->id,
- '#empty_option' => t('Source text only, no translations'),
- '#empty_value' => Language::LANGCODE_SYSTEM,
- );
- $form['content_options'] = array(
- '#type' => 'details',
- '#title' => t('Export options'),
- '#tree' => TRUE,
- '#states' => array(
- 'invisible' => array(
- ':input[name="langcode"]' => array('value' => Language::LANGCODE_SYSTEM),
- ),
- ),
- );
- $form['content_options']['not_customized'] = array(
- '#type' => 'checkbox',
- '#title' => t('Include non-customized translations'),
- '#default_value' => TRUE,
- );
- $form['content_options']['customized'] = array(
- '#type' => 'checkbox',
- '#title' => t('Include customized translations'),
- '#default_value' => TRUE,
- );
- $form['content_options']['not_translated'] = array(
- '#type' => 'checkbox',
- '#title' => t('Include untranslated text'),
- '#default_value' => TRUE,
- );
- }
-
- $form['actions'] = array(
- '#type' => 'actions'
- );
- $form['actions']['submit'] = array(
- '#type' => 'submit',
- '#value' => t('Export')
- );
- return $form;
-}
-
-/**
- * Form submission handler for locale_translate_export_form().
- */
-function locale_translate_export_form_submit($form, &$form_state) {
- // If template is required, language code is not given.
- if ($form_state['values']['langcode'] != Language::LANGCODE_SYSTEM) {
- $language = language_load($form_state['values']['langcode']);
- }
- else {
- $language = NULL;
- }
- $content_options = isset($form_state['values']['content_options']) ? $form_state['values']['content_options'] : array();
- $reader = new PoDatabaseReader();
- $languageName = '';
- if ($language != NULL) {
- $reader->setLangcode($language->id);
- $reader->setOptions($content_options);
- $languages = language_list();
- $languageName = isset($languages[$language->id]) ? $languages[$language->id]->name : '';
- $filename = $language->id .'.po';
- }
- else {
- // Template required.
- $filename = 'drupal.pot';
- }
-
- $item = $reader->readItem();
- if (!empty($item)) {
- $uri = tempnam('temporary://', 'po_');
- $header = $reader->getHeader();
- $header->setProjectName(\Drupal::config('system.site')->get('name'));
- $header->setLanguageName($languageName);
-
- $writer = new PoStreamWriter;
- $writer->setUri($uri);
- $writer->setHeader($header);
-
- $writer->open();
- $writer->writeItem($item);
- $writer->writeItems($reader);
- $writer->close();
-
- $response = new BinaryFileResponse($uri);
- $response->setContentDisposition('attachment', $filename);
- // @todo remove lines below once converted to new routing system.
- $response->prepare(\Drupal::request())
- ->send();
- }
- else {
- drupal_set_message('Nothing to export.');
- }
-}
-
-/**
* Prepare a batch to import all translations.
*
* @param array $options
diff --git a/core/modules/locale/locale.routing.yml b/core/modules/locale/locale.routing.yml
index 190ddf7..6658dad 100644
--- a/core/modules/locale/locale.routing.yml
+++ b/core/modules/locale/locale.routing.yml
@@ -32,7 +32,7 @@ locale.translate_import:
locale.translate_export:
path: '/admin/config/regional/translate/export'
defaults:
- _content: '\Drupal\locale\Form\LocaleForm::export'
+ _form: '\Drupal\locale\Form\ExportForm'
_title: 'Export'
requirements:
_permission: 'translate interface'
diff --git a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
index 487f4c8..a1d2ff9 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormBuilderTest.php
@@ -125,6 +125,100 @@ class FormBuilderTest extends FormTestBase {
}
/**
+ * Tests the handling of $form_state['response'].
+ *
+ * @dataProvider formStateResponseProvider
+ */
+ public function testHandleFormStateResponse($class, $form_state_key) {
+ $form_id = 'test_form_id';
+ $expected_form = $form_id();
+
+ $response = $this->getMockBuilder($class)
+ ->disableOriginalConstructor()
+ ->getMock();
+ $response->expects($this->any())
+ ->method('prepare')
+ ->will($this->returnValue($response));
+
+ $form_arg = $this->getMockForm($form_id, $expected_form);
+ $form_arg->expects($this->any())
+ ->method('submitForm')
+ ->will($this->returnCallback(function ($form, &$form_state) use ($response, $form_state_key) {
+ $form_state[$form_state_key] = $response;
+ }));
+
+ $form_state = array();
+ $this->formBuilder->getFormId($form_arg, $form_state);
+
+ try {
+ $form_state['values'] = array();
+ $form_state['input']['form_id'] = $form_id;
+ $this->simulateFormSubmission($form_id, $form_arg, $form_state, FALSE);
+ $this->fail('TestFormBuilder::sendResponse() was not triggered.');
+ }
+ catch (\Exception $e) {
+ $this->assertSame('exit', $e->getMessage());
+ }
+ $this->assertInstanceOf('Symfony\Component\HttpFoundation\Response', $form_state['response']);
+ }
+
+ /**
+ * Provides test data for testHandleFormStateResponse().
+ */
+ public function formStateResponseProvider() {
+ return array(
+ array('Symfony\Component\HttpFoundation\Response', 'response'),
+ array('Symfony\Component\HttpFoundation\RedirectResponse', 'redirect'),
+ );
+ }
+
+ /**
+ * Tests the handling of a redirect when $form_state['response'] exists.
+ */
+ public function testHandleRedirectWithResponse() {
+ $form_id = 'test_form_id';
+ $expected_form = $form_id();
+
+ // Set up a response that will be used.
+ $response = $this->getMockBuilder('Symfony\Component\HttpFoundation\Response')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $response->expects($this->once())
+ ->method('prepare')
+ ->will($this->returnValue($response));
+
+ // Set up a redirect that will not be called.
+ $redirect = $this->getMockBuilder('Symfony\Component\HttpFoundation\RedirectResponse')
+ ->disableOriginalConstructor()
+ ->getMock();
+ $redirect->expects($this->never())
+ ->method('prepare');
+
+ $form_arg = $this->getMockForm($form_id, $expected_form);
+ $form_arg->expects($this->any())
+ ->method('submitForm')
+ ->will($this->returnCallback(function ($form, &$form_state) use ($response, $redirect) {
+ // Set both the response and the redirect.
+ $form_state['response'] = $response;
+ $form_state['redirect'] = $redirect;
+ }));
+
+ $form_state = array();
+ $this->formBuilder->getFormId($form_arg, $form_state);
+
+ try {
+ $form_state['values'] = array();
+ $form_state['input']['form_id'] = $form_id;
+ $this->simulateFormSubmission($form_id, $form_arg, $form_state, FALSE);
+ $this->fail('TestFormBuilder::sendResponse() was not triggered.');
+ }
+ catch (\Exception $e) {
+ $this->assertSame('exit', $e->getMessage());
+ }
+ $this->assertSame($response, $form_state['response']);
+ }
+
+ /**
* Tests the redirectForm() method when a redirect is expected.
*
* @param array $form_state
diff --git a/core/tests/Drupal/Tests/Core/Form/FormTestBase.php b/core/tests/Drupal/Tests/Core/Form/FormTestBase.php
index 3b7a97f..44059c4 100644
--- a/core/tests/Drupal/Tests/Core/Form/FormTestBase.php
+++ b/core/tests/Drupal/Tests/Core/Form/FormTestBase.php
@@ -189,15 +189,19 @@ abstract class FormTestBase extends UnitTestCase {
* The form object.
* @param array $form_state
* An associative array containing the current state of the form.
+ * @param bool $programmed
+ * Whether $form_state['programmed'] should be set to TRUE or not. If it is
+ * not set to TRUE, you must provide additional data in $form_state for the
+ * submission to take place.
*
* @return array
* The built form.
*/
- protected function simulateFormSubmission($form_id, FormInterface $form_arg, array &$form_state) {
+ protected function simulateFormSubmission($form_id, FormInterface $form_arg, array &$form_state, $programmed = TRUE) {
$form_state['build_info']['callback_object'] = $form_arg;
$form_state['build_info']['args'] = array();
$form_state['input']['op'] = 'Submit';
- $form_state['programmed'] = TRUE;
+ $form_state['programmed'] = $programmed;
$form_state['submitted'] = TRUE;
return $this->formBuilder->buildForm($form_id, $form_state);
}