Commit b761f76a authored by catch's avatar catch

Issue #2056627 by dawehner, tim.plunkett: Fixed Regression, Form API...

Issue #2056627 by dawehner, tim.plunkett: Fixed Regression, Form API autocomplete is broken for routes.
parent 350c73f1
......@@ -4078,16 +4078,42 @@ function theme_vertical_tabs($variables) {
* @code
* '#autocomplete_path' => 'mymodule_autocomplete/' . $some_key . '/' . $some_id,
* @endcode
* Or if your route is called 'mymodule_autocomplete' with the path of
* '/mymodule-autocomplete/{a}/{b}':
* @code
* '#autocomplete_route_name' => 'mymodule_autocomplete',
* '#autocomplete_route_parameters' => array('a' => $some_key, 'b' => $some_id),
* @endcode
* The user types in "keywords" so the full path called is:
* 'mymodule_autocomplete/$some_key/$some_id?q=keywords'
*
* @param $element
* @param array $element
* The form element to process. Properties used:
* - #autocomplete_path: A system path to be used as callback URL by the
* autocomplete JavaScript library.
* - #autocomplete_route_name: A route to be used as callback URL by the
* autocomplete JavaScript library.
* - #autocomplete_route_parameters: The parameters to be used in conjunction
* with the route name.
* @param array $form_state
* An associative array containing the current state of the form.
*
* @return array
* The form element.
*/
function form_process_autocomplete($element, &$form_state) {
if (!empty($element['#autocomplete_path']) && drupal_valid_path($element['#autocomplete_path'])) {
$access = FALSE;
if (!empty($element['#autocomplete_route_name'])) {
$parameters = isset($element['#autocomplete_route_parameters']) ? $element['#autocomplete_route_parameters'] : array();
$path = Drupal::urlGenerator()->generate($element['#autocomplete_route_name'], $parameters);
$access = Drupal::service('access_manager')->checkNamedRoute($element['#autocomplete_route_name'], $parameters);
}
elseif (!empty($element['#autocomplete_path'])) {
$path = url($element['#autocomplete_path'], array('absolute' => TRUE));
$access = drupal_valid_path($element['#autocomplete_path']);
}
if ($access) {
$element['#attributes']['class'][] = 'form-autocomplete';
$element['#attached']['library'][] = array('system', 'drupal.autocomplete');
// Provide a hidden element for the JavaScript behavior to bind to. Since
......@@ -4097,7 +4123,7 @@ function form_process_autocomplete($element, &$form_state) {
$element['autocomplete'] = array(
'#type' => 'hidden',
'#input' => FALSE,
'#value' => url($element['#autocomplete_path'], array('absolute' => TRUE)),
'#value' => $path,
'#disabled' => TRUE,
'#attributes' => array(
'class' => array('autocomplete'),
......
......@@ -87,7 +87,7 @@ public function form(array $form, array &$form_state) {
if ($is_admin) {
$form['author']['name']['#title'] = t('Authored by');
$form['author']['name']['#description'] = t('Leave blank for %anonymous.', array('%anonymous' => \Drupal::config('user.settings')->get('anonymous')));
$form['author']['name']['#autocomplete_path'] = 'user/autocomplete';
$form['author']['name']['#autocomplete_route_name'] = 'user_autocomplete';
}
elseif ($user->isAuthenticated()) {
$form['author']['name']['#type'] = 'item';
......
......@@ -274,7 +274,7 @@ public function entityFormAlter(array &$form, array &$form_state, EntityInterfac
'#type' => 'textfield',
'#title' => t('Authored by'),
'#maxlength' => 60,
'#autocomplete_path' => 'user/autocomplete',
'#autocomplete_route_name' => 'user_autocomplete',
'#default_value' => $name,
'#description' => t('Leave blank for %anonymous.', array('%anonymous' => variable_get('anonymous', t('Anonymous')))),
);
......
......@@ -190,7 +190,7 @@ public function form(array $form, array &$form_state) {
'#type' => 'textfield',
'#title' => t('Authored by'),
'#maxlength' => 60,
'#autocomplete_path' => 'user/autocomplete',
'#autocomplete_route_name' => 'user_autocomplete',
'#default_value' => !empty($node->name) ? $node->name : '',
'#weight' => -1,
'#description' => t('Leave blank for %anonymous.', array('%anonymous' => $user_config->get('anonymous'))),
......
......@@ -107,7 +107,7 @@ public function buildConfigurationForm(array $form, array &$form_state) {
'#type' => 'textfield',
'#title' => t('Username'),
'#default_value' => $owner_name,
'#autocomplete_path' => 'user/autocomplete',
'#autocomplete_route_name' => 'user_autocomplete',
'#size' => '6',
'#maxlength' => '60',
'#description' => $description,
......
......@@ -123,4 +123,26 @@ function testUnpublishedNodeCreation() {
$this->assertRaw(t('!post %title has been created.', array('!post' => 'Basic page', '%title' => $edit["title"])));
}
/**
* Tests the author autocompletion textfield.
*/
public function testAuthorAutocomplete() {
$admin_user = $this->drupalCreateUser(array('administer nodes', 'create page content'));
$this->drupalLogin($admin_user);
$this->drupalGet('node/add/page');
$result = $this->xpath('//input[@id = "edit-name-autocomplete"]');
$this->assertEqual(count($result), 0, 'No autocompletion without access user profiles.');
$admin_user = $this->drupalCreateUser(array('administer nodes', 'create page content', 'access user profiles'));
$this->drupalLogin($admin_user);
$this->drupalGet('node/add/page');
$result = $this->xpath('//input[@id = "edit-name-autocomplete"]');
$this->assertEqual((string) $result[0]['value'], url('user/autocomplete'));
$this->assertEqual(count($result), 1, 'Ensure that the user does have access to the autocompletion');
}
}
......@@ -126,4 +126,28 @@ function testGroupElements() {
$elements = $this->xpath('//div[@class="vertical-tabs-panes"]//details[@id="edit-meta-2"]//label');
$this->assertTrue(count($elements) == 1);
}
/**
* Tests a form with a autocomplete setting..
*/
public function testFormAutocomplete() {
$this->drupalGet('form-test/autocomplete');
$result = $this->xpath('//input[@id = "edit-autocomplete-1-autocomplete"]');
$this->assertEqual(count($result), 0, 'Ensure that the user does not have access to the autocompletion');
$result = $this->xpath('//input[@id = "edit-autocomplete-2-autocomplete"]');
$this->assertEqual(count($result), 0, 'Ensure that the user did not had access to the autocompletion');
$user = $this->drupalCreateUser(array('access autocomplete test'));
$this->drupalLogin($user);
$this->drupalGet('form-test/autocomplete');
$result = $this->xpath('//input[@id = "edit-autocomplete-1-autocomplete"]');
$this->assertEqual((string) $result[0]['value'], url('form-test/autocomplete-1'));
$this->assertEqual(count($result), 1, 'Ensure that the user does have access to the autocompletion');
$result = $this->xpath('//input[@id = "edit-autocomplete-2-autocomplete"]');
$this->assertEqual((string) $result[0]['value'], url('form-test/autocomplete-2/value'));
$this->assertEqual(count($result), 1, 'Ensure that the user does have access to the autocompletion');
}
}
......@@ -376,6 +376,9 @@ function form_test_permission() {
'access vertical_tab_test tabs' => array(
'title' => t('Access vertical_tab_test tabs'),
),
'access autocomplete test' => array(
'title' => t('Access autocomplete test'),
),
);
return $perms;
}
......
......@@ -46,3 +46,24 @@ form_test.route7:
_form: '\Drupal\form_test\ConfirmFormArrayPathTestForm'
requirements:
_access: 'TRUE'
form_test.route8:
pattern: '/form-test/autocomplete'
defaults:
_form: '\Drupal\form_test\FormTestAutocompleteForm'
requirements:
_access: 'TRUE'
form_test.autocomplete_1:
pattern: '/form-test/autocomplete-1'
defaults:
controller: '\Drupal\form_test\AutocompleteController::autocomplete1'
requirements:
_permission: 'access autocomplete test'
form_test.autocomplete_2:
pattern: '/form-test/autocomplete-2/{param}'
defaults:
controller: '\Drupal\form_test\AutocompleteController::autocomplete1'
requirements:
_permission: 'access autocomplete test'
<?php
/**
* @file
* Contains \Drupal\form_test\AutocompleteController.
*/
namespace Drupal\form_test;
use Symfony\Component\HttpFoundation\JsonResponse;
/**
* Defines a controller class with methods for autocompletion.
*/
class AutocompleteController {
/**
* Returns some autocompletion content.
*
* @return \Symfony\Component\HttpFoundation\JsonResponse
* A JSON response.
*/
public function autocomplete1() {
return new JsonResponse(array('key' => 'value'));
}
}
<?php
/**
* @file
* Contains \Drupal\form_test\FormTestAutocompleteForm.
*/
namespace Drupal\form_test;
use Drupal\Core\Form\FormInterface;
/**
* Defines a test form using autocomplete textfields.
*/
class FormTestAutocompleteForm implements FormInterface {
/**
* {@inheritdoc}
*/
public function getFormID() {
return 'form_test_autocomplete';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, array &$form_state) {
$form['autocomplete_1'] = array(
'#type' => 'textfield',
'#title' => 'Autocomplete 1',
'#autocomplete_route_name' => 'form_test.autocomplete_1',
);
$form['autocomplete_2'] = array(
'#type' => 'textfield',
'#title' => 'Autocomplete 2',
'#autocomplete_route_name' => 'form_test.autocomplete_2',
'#autocomplete_route_parameters' => array('param' => 'value'),
);
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, array &$form_state) {
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, array &$form_state) {
}
}
......@@ -42,7 +42,7 @@ protected function valueForm(&$form, &$form_state) {
'#title' => t('Usernames'),
'#description' => t('Enter a comma separated list of user names.'),
'#default_value' => $default_value,
'#autocomplete_path' => 'user/autocomplete/anonymous',
'#autocomplete_route_name' => 'user_autocomplete_anonymous',
);
if (!empty($form_state['exposed']) && !isset($form_state['input'][$this->options['expose']['identifier']])) {
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment