From 59d0c1f6609b2d8dedba1ec74fa2858cc29863d2 Mon Sep 17 00:00:00 2001
From: catch <catch@35733.no-reply.drupal.org>
Date: Thu, 29 Nov 2012 10:42:00 +0000
Subject: [PATCH] Issue #680546 by swentel, jramby, Cottser, jonathan1055:
 Added a custom 'number of values' for 'multiple / multi-value' field. (e.g.
 nodereference, imagefield).

---
 .../Drupal/text/Tests/TextTranslationTest.php |  2 +-
 core/modules/field_ui/field_ui.admin.inc      | 46 +++++++++++++++++--
 .../field_ui/Tests/ManageFieldsTest.php       | 44 ++++++++++++++++++
 3 files changed, 87 insertions(+), 5 deletions(-)

diff --git a/core/modules/field/modules/text/lib/Drupal/text/Tests/TextTranslationTest.php b/core/modules/field/modules/text/lib/Drupal/text/Tests/TextTranslationTest.php
index 0ac151fe2626..1e2a13dd7049 100644
--- a/core/modules/field/modules/text/lib/Drupal/text/Tests/TextTranslationTest.php
+++ b/core/modules/field/modules/text/lib/Drupal/text/Tests/TextTranslationTest.php
@@ -90,7 +90,7 @@ function testTextField() {
    */
   function testTextFieldFormatted() {
     // Make node body multiple.
-    $edit = array('field[cardinality]' => -1);
+    $edit = array('field[container][cardinality]' => -1);
     $this->drupalPost('admin/structure/types/manage/article/fields/body', $edit, t('Save settings'));
     $this->drupalGet('node/add/article');
     $this->assertFieldByXPath("//input[@name='body_add_more']", t('Add another item'), 'Body field cardinality set to multiple.');
diff --git a/core/modules/field_ui/field_ui.admin.inc b/core/modules/field_ui/field_ui.admin.inc
index 22069f7163fe..d919eed438a6 100644
--- a/core/modules/field_ui/field_ui.admin.inc
+++ b/core/modules/field_ui/field_ui.admin.inc
@@ -921,13 +921,35 @@ function field_ui_field_edit_form($form, &$form_state, $instance) {
   if (field_behaviors_widget('multiple_values', $instance) == FIELD_BEHAVIOR_DEFAULT) {
     $description .= '<br/>' . t("'Unlimited' will provide an 'Add more' button so the users can add as many values as they like.");
   }
-  $form['field']['cardinality'] = array(
-    '#type' => 'select',
+
+  $cardinality = $field['cardinality'];
+  $form['field']['container'] = array(
+    // We can't use the container element because it doesn't support the title
+    // or description properties.
+    '#type' => 'item',
+    '#field_prefix' => '<div class="container-inline">',
+    '#field_suffix' => '</div>',
     '#title' => t('Number of values'),
-    '#options' => array(FIELD_CARDINALITY_UNLIMITED => t('Unlimited')) + drupal_map_assoc(range(1, 10)),
-    '#default_value' => $field['cardinality'],
     '#description' => $description,
   );
+  $form['field']['container']['cardinality'] = array(
+    '#type' => 'select',
+    '#options' => array(FIELD_CARDINALITY_UNLIMITED => t('Unlimited')) + drupal_map_assoc(range(1, 5)) + array('other' => t('More')),
+    '#default_value' => ($cardinality < 6) ? $cardinality : 'other',
+  );
+  // @todo Convert when http://drupal.org/node/1207060 gets in.
+  $form['field']['container']['cardinality_other'] = array(
+    '#type' => 'number',
+    '#default_value' => $cardinality > 5 ? $cardinality : 6,
+    '#min' => 1,
+    '#title' => t('Custom value'),
+    '#title_display' => 'invisible',
+    '#states' => array(
+      'visible' => array(
+       ':input[name="field[container][cardinality]"]' => array('value' => 'other'),
+      ),
+    ),
+  );
 
   // Add additional field type settings. The field type module is
   // responsible for not returning settings that cannot be changed if
@@ -1037,6 +1059,13 @@ function field_ui_field_edit_form_validate($form, &$form_state) {
   $field_name = $instance['field_name'];
   $entity = $form['#entity'];
 
+  // Validate field cardinality.
+  $cardinality = $form_state['values']['field']['container']['cardinality'];
+  $cardinality_other = $form_state['values']['field']['container']['cardinality_other'];
+  if ($cardinality == 'other' && empty($cardinality_other)) {
+    form_error($form['field']['container']['cardinality_other'], t('Number of values is required.'));
+  }
+
   if (isset($form['instance']['default_value_widget'])) {
     $element = $form['instance']['default_value_widget'];
 
@@ -1077,6 +1106,15 @@ function field_ui_field_edit_form_submit($form, &$form_state) {
   $field = $form['#field'];
   $entity = $form['#entity'];
 
+  // Save field cardinality.
+  $cardinality = $form_state['values']['field']['container']['cardinality'];
+  $cardinality_other = $form_state['values']['field']['container']['cardinality_other'];
+  if ($cardinality == 'other') {
+    $cardinality = $cardinality_other;
+  }
+  $form_state['values']['field']['cardinality'] = $cardinality;
+  unset($form_state['values']['field']['container']);
+
   // Merge incoming values into the field.
   $field = array_merge($field, $form_state['values']['field']);
   try {
diff --git a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
index 6aaec65bcb47..e9c4be29ac04 100644
--- a/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
+++ b/core/modules/field_ui/lib/Drupal/field_ui/Tests/ManageFieldsTest.php
@@ -65,6 +65,7 @@ function testCRUDFields() {
     $this->createField();
     $this->updateField();
     $this->addExistingField();
+    $this->cardinalitySettings();
   }
 
   /**
@@ -162,6 +163,49 @@ function addExistingField() {
     $this->fieldUIAddExistingField("admin/structure/types/manage/page", $edit);
   }
 
+  /**
+   * Tests the cardinality settings of a field.
+   *
+   * We do not test if the number can be submitted with anything else than a
+   * numeric value. That is tested already in FormTest::testNumber().
+   */
+  function cardinalitySettings() {
+    $field_edit_path = 'admin/structure/types/manage/article/fields/body';
+
+    // Assert the cardinality other field cannot be empty when cardinality is
+    // set to other.
+    $edit = array(
+      'field[container][cardinality]' => 'other',
+      'field[container][cardinality_other]' => '',
+    );
+    $this->drupalPost($field_edit_path, $edit, t('Save settings'));
+    $this->assertText('Number of values is required.');
+
+    // Assert the cardinality field is set to 'Other' when the value is greater
+    // than 5.
+    $edit = array(
+      'field[container][cardinality]' => 'other',
+      'field[container][cardinality_other]' => 16,
+    );
+    $this->drupalPost($field_edit_path, $edit, t('Save settings'));
+    $this->assertText('Saved Body configuration.');
+    $this->drupalGet($field_edit_path);
+    $this->assertFieldByXPath("//select[@name='field[container][cardinality]']", 'other');
+    $this->assertFieldByXPath("//input[@name='field[container][cardinality_other]']", 16);
+
+    // Assert the cardinality other field is set back to 6 after changing the
+    // cardinality to less than 6.
+    $edit = array(
+      'field[container][cardinality]' => 3,
+      'field[container][cardinality_other]' => 16,
+    );
+    $this->drupalPost($field_edit_path, $edit, t('Save settings'));
+    $this->assertText('Saved Body configuration.');
+    $this->drupalGet($field_edit_path);
+    $this->assertFieldByXPath("//select[@name='field[container][cardinality]']", 3);
+    $this->assertFieldByXPath("//input[@name='field[container][cardinality_other]']", 6);
+  }
+
   /**
    * Asserts field settings are as expected.
    *
-- 
GitLab