Commit 3bb5f796 authored by webchick's avatar webchick

Issue #1998638 by damiankloip, dawehner, kim.pepper, cosmicdreams, alexpott,...

Issue #1998638 by damiankloip, dawehner, kim.pepper, cosmicdreams, alexpott, larowlan, Damien Tournoud: Replace almost all remaining superglobals (, , etc.) with Symfony Request object.
parent 67e93b23
......@@ -241,7 +241,7 @@ function ajax_render($commands = array()) {
// since the base page ought to have at least one JS file and one CSS file
// loaded. It probably indicates an error, and rather than making the page
// reload all of the files, instead we return no new files.
if (empty($_POST['ajax_page_state'][$type])) {
if (!\Drupal::request()->request->get("ajax_page_state[$type]", NULL, TRUE)) {
$items[$type] = array();
}
else {
......
......@@ -457,25 +457,28 @@ function config_get_config_directory($type = CONFIG_ACTIVE_DIRECTORY) {
* 'REMOTE_ADDR' key.
*
* @param $variables
* (optional) An associative array of variables within $_SERVER that should
* be replaced. If the special element 'url' is provided in this array, it
* will be used to populate some of the server defaults; it should be set to
* the URL of the current page request, excluding any $_GET request but
* including the script name (e.g., http://www.example.com/mysite/index.php).
* (optional) An associative array of variables within
* \Drupal::request()->server that should be replaced. If the special element
* 'url' is provided in this array, it will be used to populate some of the
* server defaults; it should be set to the URL of the current page request,
* excluding any GET request but including the script name
* (e.g., http://www.example.com/mysite/index.php).
*
* @see conf_path()
* @see request_uri()
* @see \Symfony\Component\HttpFoundation\Request::getClientIP()
*/
function drupal_override_server_variables($variables = array()) {
$request = \Drupal::request();
$server_vars = $request->server->all();
// Allow the provided URL to override any existing values in $_SERVER.
if (isset($variables['url'])) {
$url = parse_url($variables['url']);
if (isset($url['host'])) {
$_SERVER['HTTP_HOST'] = $url['host'];
$server_vars['HTTP_HOST'] = $url['host'];
}
if (isset($url['path'])) {
$_SERVER['SCRIPT_NAME'] = $url['path'];
$server_vars['SCRIPT_NAME'] = $url['path'];
}
unset($variables['url']);
}
......@@ -492,7 +495,10 @@ function drupal_override_server_variables($variables = array()) {
'HTTP_USER_AGENT' => NULL,
);
// Replace elements of the $_SERVER array, as appropriate.
$_SERVER = $variables + $_SERVER + $defaults;
$request->server->replace($variables + $server_vars + $defaults);
// @todo remove once conf_path() no longer uses $_SERVER.
$_SERVER = $request->server->all();
}
/**
......
......@@ -411,7 +411,8 @@ function drupal_get_feeds($delimiter = "\n") {
* Processes a URL query parameter array to remove unwanted elements.
*
* @param $query
* (optional) An array to be processed. Defaults to $_GET.
* (optional) An array to be processed. Defaults to \Drupal::request()->query
* parameters.
* @param $exclude
* (optional) A list of $query array keys to remove. Use "parent[child]" to
* exclude nested items.
......@@ -490,7 +491,7 @@ function drupal_get_destination() {
* The returned array contains a 'path' that may be passed separately to url().
* For example:
* @code
* $options = drupal_parse_url($_GET['destination']);
* $options = drupal_parse_url(\Drupal::request()->query->get('destination'));
* $my_url = url($options['path'], $options);
* $my_link = l('Example link', $options['path'], $options);
* @endcode
......@@ -501,7 +502,7 @@ function drupal_get_destination() {
* $options['query'] and the fragment into $options['fragment'].
*
* @param $url
* The URL string to parse, f.e. $_GET['destination'].
* The URL string to parse.
*
* @return
* An associative array containing the keys:
......@@ -1886,6 +1887,7 @@ function drupal_html_id($id) {
// take into account IDs that are already in use on the base page.
$seen_ids_init = &drupal_static(__FUNCTION__ . ':init');
if (!isset($seen_ids_init)) {
$ajax_html_ids = \Drupal::request()->request->get('ajax_html_ids');
// Ideally, Drupal would provide an API to persist state information about
// prior page requests in the database, and we'd be able to add this
// function's $seen_ids static variable to that state information in order
......@@ -1895,7 +1897,7 @@ function drupal_html_id($id) {
// normally not recommended as it could open up security risks, but because
// the raw POST data is cast to a number before being returned by this
// function, this usage is safe.
if (empty($_POST['ajax_html_ids'])) {
if (empty($ajax_html_ids)) {
$seen_ids_init = array();
}
else {
......@@ -1904,7 +1906,7 @@ function drupal_html_id($id) {
// requested id. $_POST['ajax_html_ids'] contains the ids as they were
// returned by this function, potentially with the appended counter, so
// we parse that to reconstruct the $seen_ids array.
$ajax_html_ids = explode(' ', $_POST['ajax_html_ids']);
$ajax_html_ids = explode(' ', $ajax_html_ids);
foreach ($ajax_html_ids as $seen_id) {
// We rely on '--' being used solely for separating a base id from the
// counter, which this function ensures when returning an id.
......
......@@ -495,7 +495,8 @@ function form_type_checkboxes_value($element, $input = FALSE) {
// NULL elements from the array before constructing the return value, to
// simulate the behavior of web browsers (which do not send unchecked
// checkboxes to the server at all). This will not affect non-programmatic
// form submissions, since all values in $_POST are strings.
// form submissions, since all values in \Drupal::request()->request are
// strings.
foreach ($input as $key => $value) {
if (!isset($value)) {
unset($input[$key]);
......
......@@ -253,9 +253,19 @@ function install_state_defaults() {
* modified with information gleaned from the beginning of the page request.
*/
function install_begin_request(&$install_state) {
// A request object from the HTTPFoundation to tell us about the request.
$request = Request::createFromGlobals();
// Create a minimal container so that t() and $request will work. This
// container will be overriden but it's needed for the very early installation
// process when database tasks run.
$container = new ContainerBuilder();
$container->set('request', $request);
\Drupal::setContainer($container);
// Add any installation parameters passed in via the URL.
if ($install_state['interactive']) {
$install_state['parameters'] += $_GET;
$install_state['parameters'] += $request->query->all();
}
// Validate certain core settings that are used throughout the installation.
......@@ -288,13 +298,10 @@ function install_begin_request(&$install_state) {
// _drupal_load_test_overrides() sets the simpletest_conf_path in-memory
// setting in this case.
if ($install_state['interactive'] && drupal_valid_test_ua() && !settings()->get('simpletest_conf_path')) {
header($_SERVER['SERVER_PROTOCOL'] . ' 403 Forbidden');
header($request->server->get('SERVER_PROTOCOL') . ' 403 Forbidden');
exit;
}
// A request object from the HTTPFoundation to tell us about the request.
$request = Request::createFromGlobals();
// If we have a language selected and it is not yet saved in the system
// (eg. pre-database data screens we are unable to persistently store
// the default language), we should set language_default so the proper
......@@ -324,10 +331,6 @@ function install_begin_request(&$install_state) {
// Determine whether the configuration system is ready to operate.
$install_state['config_verified'] = install_verify_config_directory(CONFIG_ACTIVE_DIRECTORY) && install_verify_config_directory(CONFIG_STAGING_DIRECTORY);
// Create a minimal container for t() to work.
// This container will be overriden but it needed for the very early
// installation process when database tasks run.
$container = new ContainerBuilder();
// Register the translation services.
install_register_translation_service($container);
\Drupal::setContainer($container);
......@@ -1355,7 +1358,7 @@ function install_select_profile(&$install_state) {
*
* A profile will be selected if:
* - Only one profile is available,
* - A profile was submitted through $_POST,
* - A profile was submitted through \Drupal::request()->request,
* - Exactly one of the profiles is marked as "exclusive".
* If multiple profiles are marked as "exclusive" then no profile will be
* selected.
......@@ -1369,12 +1372,13 @@ function install_select_profile(&$install_state) {
*/
function _install_select_profile($profiles) {
// Don't need to choose profile if only one available.
$request_params = \Drupal::request()->request;
if (count($profiles) == 1) {
$profile = array_pop($profiles);
return $profile->name;
}
elseif (!empty($_POST['profile']) && isset($profiles[$_POST['profile']])) {
return $profiles[$_POST['profile']]->name;
elseif ($request_params->has('profile') && ($profile = $request_params->get('profile')) && isset($profiles[$profile])) {
return $profiles[$profile]->name;
}
// Check for a profile marked as "exclusive" and ensure that only one
// profile is marked as such.
......@@ -1555,6 +1559,7 @@ function install_select_language(&$install_state) {
// Find all available translation files.
$files = install_find_translations();
$install_state['translations'] += $files;
$request_params = \Drupal::request()->request;
// If a valid language code is set, continue with the next installation step.
// When translations from the localization server are used, any language code
......@@ -1562,9 +1567,9 @@ function install_select_language(&$install_state) {
// langauges available at http://localize.drupal.org.
// When files from the translation directory are used, we only accept
// languages for which a file is available.
if (!empty($_POST['langcode'])) {
if ($request_params->has('langcode')) {
$standard_languages = LanguageManager::getStandardLanguageList();
$langcode = $_POST['langcode'];
$langcode = $request_params->get('langcode');
if ($langcode == 'en' || isset($files[$langcode]) || isset($standard_languages[$langcode])) {
$install_state['parameters']['langcode'] = $langcode;
return;
......@@ -2106,7 +2111,8 @@ function install_configure_form($form, &$form_state, &$install_state) {
// especially out of place on the last page of the installer, where it would
// distract from the message that the Drupal installation has completed
// successfully.)
if (empty($_POST) && (!drupal_verify_install_file(DRUPAL_ROOT . '/' . $settings_file, FILE_EXIST|FILE_READABLE|FILE_NOT_WRITABLE) || !drupal_verify_install_file(DRUPAL_ROOT . '/' . $settings_dir, FILE_NOT_WRITABLE, 'dir'))) {
$post_params = \Drupal::request()->request->all();
if (empty($post_params) && (!drupal_verify_install_file(DRUPAL_ROOT . '/' . $settings_file, FILE_EXIST|FILE_READABLE|FILE_NOT_WRITABLE) || !drupal_verify_install_file(DRUPAL_ROOT . '/' . $settings_dir, FILE_NOT_WRITABLE, 'dir'))) {
drupal_set_message(t('All necessary changes to %dir and %file have been made, so you should remove write permissions to them now in order to avoid security risks. If you are unsure how to do so, consult the <a href="@handbook_url">online handbook</a>.', array('%dir' => $settings_dir, '%file' => $settings_file, '@handbook_url' => 'http://drupal.org/server-permissions')), 'warning');
}
......
......@@ -100,7 +100,8 @@
* $langcode = language_from_url($languages);
*
* // If we are on an administrative path, override with the default language.
* if (isset($_GET['q']) && strtok($_GET['q'], '/') == 'admin') {
* $query = \Drupal::request()->query;
* if ($query->has('q') && strtok($query->get('q'), '/') == 'admin') {
* return language_default()->id;
* }
* return $langcode;
......
......@@ -5,13 +5,6 @@
* API functions for processing and sending e-mail.
*/
/**
* Auto-detect appropriate line endings for e-mails.
*
* $settings['mail_line_endings'] will override this setting.
*/
define('MAIL_LINE_ENDINGS', isset($_SERVER['WINDIR']) || strpos($_SERVER['SERVER_SOFTWARE'], 'Win32') !== FALSE ? "\r\n" : "\n");
/**
* Composes and optionally sends an e-mail message.
*
......@@ -431,7 +424,7 @@ function drupal_html_to_text($string, $allowed_tags = NULL) {
if (isset($casing)) {
$chunk = $casing($chunk);
}
$line_endings = settings()->get('mail_line_endings', MAIL_LINE_ENDINGS);
$line_endings = settings()->get('mail_line_endings', PHP_EOL);
// Format it and apply the current indentation.
$output .= drupal_wrap_mail($chunk, implode('', $indent)) . $line_endings;
// Remove non-quotation markers from indentation.
......
......@@ -16,13 +16,13 @@
*
* @return
* The number of the current requested page, within the pager represented by
* $element. This is determined from the URL query parameter $_GET['page'], or
* 0 by default. Note that this number may differ from the actual page being
* displayed. For example, if a search for "example text" brings up three
* pages of results, but a users visits search/node/example+text?page=10, this
* function will return 10, even though the default pager implementation
* adjusts for this and still displays the third page of search results at
* that URL.
* $element. This is determined from the URL query parameter
* \Drupal::request()->query->get('page'), or 0 by default. Note that this
* number may differ from the actual page being displayed. For example, if a
* search for "example text" brings up three pages of results, but a users
* visits search/node/example+text?page=10, this function will return 10, even
* though the default pager implementation adjusts for this and still displays
* the third page of search results at that URL.
*
* @see pager_default_initialize()
*/
......@@ -109,10 +109,11 @@ function pager_find_page($element = 0) {
*
* @return
* The number of the current page, within the pager represented by $element.
* This is determined from the URL query parameter $_GET['page'], or 0 by
* default. However, if a page that does not correspond to the actual range
* of the result set was requested, this function will return the closest
* page actually within the result set.
* This is determined from the URL query parameter
* \Drupal::request()->query->get('page), or 0 by default. However, if a page
* that does not correspond to the actual range of the result set was
* requested, this function will return the closest page actually within the
* result set.
*/
function pager_default_initialize($total, $limit, $element = 0) {
global $pager_page_array, $pager_total, $pager_total_items, $pager_limits;
......
......@@ -83,7 +83,8 @@ function _drupal_session_read($sid) {
// Handle the case of first time visitors and clients that don't store
// cookies (eg. web crawlers).
$insecure_session_name = substr(session_name(), 1);
if (!isset($_COOKIE[session_name()]) && !isset($_COOKIE[$insecure_session_name])) {
$cookies = \Drupal::request()->cookies;
if (!$cookies->has(session_name()) && !$cookies->has($insecure_session_name)) {
$user = new UserSession();
return '';
}
......@@ -95,9 +96,9 @@ function _drupal_session_read($sid) {
if (\Drupal::request()->isSecure()) {
$values = db_query("SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.ssid = :ssid", array(':ssid' => $sid))->fetchAssoc();
if (!$values) {
if (isset($_COOKIE[$insecure_session_name])) {
if ($cookies->has($insecure_session_name)) {
$values = db_query("SELECT u.*, s.* FROM {users} u INNER JOIN {sessions} s ON u.uid = s.uid WHERE s.sid = :sid AND s.uid = 0", array(
':sid' => $_COOKIE[$insecure_session_name]))
':sid' => $cookies->get($insecure_session_name)))
->fetchAssoc();
}
}
......@@ -188,13 +189,14 @@ function _drupal_session_write($sid, $value) {
// On HTTPS connections, use the session ID as both 'sid' and 'ssid'.
if (\Drupal::request()->isSecure()) {
$key['ssid'] = $sid;
$cookies = \Drupal::request()->cookies;
// The "secure pages" setting allows a site to simultaneously use both
// secure and insecure session cookies. If enabled and both cookies are
// presented then use both keys.
if (settings()->get('mixed_mode_sessions', FALSE)) {
$insecure_session_name = substr(session_name(), 1);
if (isset($_COOKIE[$insecure_session_name])) {
$key['sid'] = $_COOKIE[$insecure_session_name];
if ($cookies->has($insecure_session_name)) {
$key['sid'] = $cookies->get($insecure_session_name);
}
}
}
......@@ -241,9 +243,8 @@ function drupal_session_initialize() {
session_set_save_handler('_drupal_session_open', '_drupal_session_close', '_drupal_session_read', '_drupal_session_write', '_drupal_session_destroy', '_drupal_session_garbage_collection');
$is_https = \Drupal::request()->isSecure();
// We use !empty() in the following check to ensure that blank session IDs
// are not valid.
if (!empty($_COOKIE[session_name()]) || ($is_https && settings()->get('mixed_mode_sessions', FALSE) && !empty($_COOKIE[substr(session_name(), 1)]))) {
$cookies = \Drupal::request()->cookies;
if (($cookies->has(session_name()) && ($session_name = $cookies->get(session_name()))) || ($is_https && settings()->get('mixed_mode_sessions', FALSE) && ($cookies->has(substr(session_name(), 1))) && ($session_name = $cookies->get(substr(session_name(), 1))))) {
// If a session cookie exists, initialize the session. Otherwise the
// session is only started on demand in drupal_session_commit(), making
// anonymous users not use a session cookie unless something is stored in
......@@ -267,7 +268,7 @@ function drupal_session_initialize() {
if ($is_https && settings()->get('mixed_mode_sessions', FALSE)) {
$insecure_session_name = substr(session_name(), 1);
$session_id = Crypt::hashBase64(uniqid(mt_rand(), TRUE));
$_COOKIE[$insecure_session_name] = $session_id;
$cookies->set($insecure_session_name, $session_id);
}
}
date_default_timezone_set(drupal_get_user_timezone());
......@@ -323,7 +324,8 @@ function drupal_session_commit() {
$insecure_session_name = substr(session_name(), 1);
$params = session_get_cookie_params();
$expire = $params['lifetime'] ? REQUEST_TIME + $params['lifetime'] : 0;
setcookie($insecure_session_name, $_COOKIE[$insecure_session_name], $expire, $params['path'], $params['domain'], FALSE, $params['httponly']);
$cookie_params = \Drupal::request()->cookies;
setcookie($insecure_session_name, $cookie_params->get($insecure_session_name), $expire, $params['path'], $params['domain'], FALSE, $params['httponly']);
}
}
// Write the session data.
......@@ -356,11 +358,12 @@ function drupal_session_regenerate() {
}
$is_https = \Drupal::request()->isSecure();
$cookies = \Drupal::request()->cookies;
if ($is_https && settings()->get('mixed_mode_sessions', FALSE)) {
$insecure_session_name = substr(session_name(), 1);
if (!isset($GLOBALS['lazy_session']) && isset($_COOKIE[$insecure_session_name])) {
$old_insecure_session_id = $_COOKIE[$insecure_session_name];
if (!isset($GLOBALS['lazy_session']) && $cookies->has($insecure_session_name)) {
$old_insecure_session_id = $cookies->get($insecure_session_name);
}
$params = session_get_cookie_params();
$session_id = Crypt::hashBase64(uniqid(mt_rand(), TRUE) . Crypt::randomBytes(55));
......@@ -369,7 +372,7 @@ function drupal_session_regenerate() {
// it will expire when the browser is closed.
$expire = $params['lifetime'] ? REQUEST_TIME + $params['lifetime'] : 0;
setcookie($insecure_session_name, $session_id, $expire, $params['path'], $params['domain'], FALSE, $params['httponly']);
$_COOKIE[$insecure_session_name] = $session_id;
$cookies->set($insecure_session_name, $session_id);
}
if (drupal_session_started()) {
......@@ -461,13 +464,14 @@ function _drupal_session_destroy($sid) {
* Force the secure value of the cookie.
*/
function _drupal_session_delete_cookie($name, $secure = NULL) {
if (isset($_COOKIE[$name]) || (!\Drupal::request()->isSecure() && $secure === TRUE)) {
$cookies = \Drupal::request()->cookies;
if ($cookies->has($name) || (!\Drupal::request()->isSecure() && $secure === TRUE)) {
$params = session_get_cookie_params();
if ($secure !== NULL) {
$params['secure'] = $secure;
}
setcookie($name, '', REQUEST_TIME - 3600, $params['path'], $params['domain'], $params['secure'], $params['httponly']);
unset($_COOKIE[$name]);
$cookies->remove($name);
}
}
......
......@@ -34,7 +34,8 @@ class Url {
* http_build_query() directly.
*
* @param array $query
* The query parameter array to be processed, e.g. $_GET.
* The query parameter array to be processed,
* e.g. \Drupal::request()->query->all().
* @param string $parent
* Internal use only. Used to build the $query array key for nested items.
*
......@@ -118,13 +119,14 @@ public static function filterQueryParameters(array $query, array $exclude = arra
* The returned array contains a 'path' that may be passed separately to url().
* For example:
* @code
* $options = Url::parse($_GET['destination']);
* $options = Url::parse(\Drupal::request()->query->get('destination'));
* $my_url = url($options['path'], $options);
* $my_link = l('Example link', $options['path'], $options);
* @endcode
*
* @param string $url
* The URL string to parse, f.e. $_GET['destination'].
* The URL string to parse, i.e.
* \Drupal::request()->query->get('destination').
*
* @return
* An associative array containing the keys:
......
......@@ -95,10 +95,11 @@ protected function ajaxRender(Request $request) {
// diffing logic using array_diff_key().
$ajax_page_state = $request->request->get('ajax_page_state');
foreach (array('css', 'js') as $type) {
// It is highly suspicious if $_POST['ajax_page_state'][$type] is empty,
// since the base page ought to have at least one JS file and one CSS file
// loaded. It probably indicates an error, and rather than making the page
// reload all of the files, instead we return no new files.
// It is highly suspicious if
// $request->request->get("ajax_page_state[$type]") is empty, since the
// base page ought to have at least one JS file and one CSS file loaded.
// It probably indicates an error, and rather than making the page reload
// all of the files, instead we return no new files.
if (empty($ajax_page_state[$type])) {
$items[$type] = array();
}
......
......@@ -48,9 +48,10 @@ public function checkRedirectUrl(FilterResponseEvent $event) {
$options = array();
$destination = $event->getRequest()->query->get('destination');
// A destination in $_GET always overrides the current RedirectResponse.
// We do not allow absolute URLs to be passed via $_GET, as this can be an
// attack vector, with the following exception:
// A destination from \Drupal::request()->query always overrides the
// current RedirectResponse. We do not allow absolute URLs to be passed
// via \Drupal::request()->query, as this can be an attack vector, with
// the following exception:
// - Absolute URLs that point to this site (i.e. same base URL and
// base path) are allowed.
if ($destination && (!url_is_external($destination) || _external_url_is_local($destination))) {
......
......@@ -569,7 +569,7 @@ public function retrieveForm($form_id, &$form_state) {
public function processForm($form_id, &$form, &$form_state) {
$form_state['values'] = array();
// With $_GET, these forms are always submitted if requested.
// With GET, these forms are always submitted if requested.
if ($form_state['method'] == 'get' && !empty($form_state['always_process'])) {
if (!isset($form_state['input']['form_build_id'])) {
$form_state['input']['form_build_id'] = $form['#build_id'];
......@@ -1490,9 +1490,10 @@ protected function handleInputElement($form_id, &$element, &$form_state) {
$name = array_shift($element['#parents']);
$element['#name'] = $name;
if ($element['#type'] == 'file') {
// To make it easier to handle $_FILES in file.inc, we place all
// To make it easier to handle files in file.inc, we place all
// file fields in the 'files' array. Also, we do not support
// nested file names.
// @todo Remove this files prefix now?
$element['#name'] = 'files[' . $element['#name'] . ']';
}
elseif (count($element['#parents'])) {
......@@ -1608,7 +1609,8 @@ protected function handleInputElement($form_id, &$element, &$form_state) {
if (!empty($element['#is_button'])) {
// All buttons in the form need to be tracked for
// form_state_values_clean() and for the self::doBuildForm() code that
// handles a form submission containing no button information in $_POST.
// handles a form submission containing no button information in
// \Drupal::request()->request.
$form_state['buttons'][] = $element;
if ($this->buttonWasClicked($element, $form_state)) {
$form_state['triggering_element'] = $element;
......@@ -1668,15 +1670,15 @@ protected function buttonWasClicked($element, &$form_state) {
// buttons on a form share the same name (usually 'op'), and the specific
// return value is used to determine which was clicked. This ONLY works as
// long as $form['#name'] puts the value at the top level of the tree of
// $_POST data.
// \Drupal::request()->request data.
if (isset($form_state['input'][$element['#name']]) && $form_state['input'][$element['#name']] == $element['#value']) {
return TRUE;
}
// When image buttons are clicked, browsers do NOT pass the form element
// value in $_POST. Instead they pass an integer representing the
// coordinates of the click on the button image. This means that image
// buttons MUST have unique $form['#name'] values, but the details of their
// $_POST data should be ignored.
// value in \Drupal::request()->Request. Instead they pass an integer
// representing the coordinates of the click on the button image. This means
// that image buttons MUST have unique $form['#name'] values, but the
// details of their \Drupal::request()->request data should be ignored.
elseif (!empty($element['#has_garbage_value']) && isset($element['#value']) && $element['#value'] !== '') {
return TRUE;
}
......
......@@ -154,8 +154,9 @@ public function getForm($form_arg);
* understanding of security implications. In almost all cases, code
* should use the data in the 'values' array exclusively. The most common
* use of this key is for multi-step forms that need to clear some of the
* user input when setting 'rebuild'. The values correspond to $_POST or
* $_GET, depending on the 'method' chosen.
* user input when setting 'rebuild'. The values correspond to
* \Drupal::request()->request or \Drupal::request()->query, depending on
* the 'method' chosen.
* - always_process: If TRUE and the method is GET, a form_id is not
* necessary. This should only be used on RESTful GET forms that do NOT
* write data, as this could lead to security issues. It is useful so that
......@@ -169,8 +170,8 @@ public function getForm($form_arg);
* invoked via self::submitForm(). Defaults to FALSE.
* - process_input: Boolean flag. TRUE signifies correct form submission.
* This is always TRUE for programmed forms coming from self::submitForm()
* (see 'programmed' key), or if the form_id coming from the $_POST data
* is set and matches the current form_id.
* (see 'programmed' key), or if the form_id coming from the
* \Drupal::request()->request data is set and matches the current form_id.
* - submitted: If TRUE, the form has been submitted. Defaults to FALSE.
* - executed: If TRUE, the form was submitted and has been processed and
* executed. Defaults to FALSE.
......@@ -309,11 +310,12 @@ public function setCache($form_build_id, $form, $form_state);
* @param $form_state
* A keyed array containing the current state of the form. Most important is
* the $form_state['values'] collection, a tree of data used to simulate the
* incoming $_POST information from a user's form submission. If a key is
* not filled in $form_state['values'], then the default value of the
* respective element is used. To submit an unchecked checkbox or other
* control that browsers submit by not having a $_POST entry, include the
* key, but set the value to NULL.
* incoming \Drupal::request()->request information from a user's form
* submission. If a key is not filled in $form_state['values'], then the
* default value of the respective element is used. To submit an unchecked
* checkbox or other control that browsers submit by not having a
* \Drupal::request()->request entry, include the key, but set the value to
* NULL.
* @param ...
* Any additional arguments are passed on to the functions called by
* self::submitForm(), including the unique form constructor function.
......@@ -378,8 +380,8 @@ public function retrieveForm($form_id, &$form_state);
* A keyed array containing the current state of the form. This
* includes the current persistent storage data for the form, and
* any data passed along by earlier steps when displaying a
* multi-step form. Additional information, like the sanitized $_POST
* data, is also accumulated here.
* multi-step form. Additional information, like the sanitized
* \Drupal::request()->request data, is also accumulated here.
*
* @return \Symfony\Component\HttpFoundation\RedirectResponse|null
*/
......@@ -477,8 +479,9 @@ public function validateForm($form_id, &$form, &$form_state);
* redirect is accomplished by returning a RedirectResponse, passing in the
* value of $form_state['redirect'] if it is set, or the current path if it
* is not. RedirectResponse preferentially uses the value of
* $_GET['destination'] (the 'destination' URL query string) if it is
* present, so this will override any values set by $form_state['redirect'].
* \Drupal::request->query->get('destination') (the 'destination' URL query
* string) if it is present, so this will override any values set by
* $form_state['redirect'].
*
* @param $form_state
* An associative array containing the current state of the form.
......@@ -599,7 +602,7 @@ public function executeHandlers($type, &$form, &$form_state);
* A keyed array containing the current state of the form. In this
* context, it is used to accumulate information about which button
* was clicked when the form was submitted, as well as the sanitized
* $_POST data.
* \Drupal::request()->request data.
*
* @return array
*/
......
......@@ -59,7 +59,7 @@ public function mail(array $message) {
foreach ($message['headers'] as $name => $value) {
$mimeheaders[] = $name . ': ' . mime_header_encode($value);
}
$line_endings = settings()->get('mail_line_endings', MAIL_LINE_ENDINGS);
$line_endings = settings()->get('mail_line_endings', PHP_EOL);
// Prepare mail commands.
$mail_subject = mime_header_encode($message['subject']);
// Note: e-mail uses CRLF for line-endings. PHP's API requires LF
......
......@@ -138,7 +138,8 @@ public function buildForm(array $form, array &$form_state) {
*/
public function validateForm(array &$form, array &$form_state) {
// If both fields are empty or filled, cancel.
if (empty($form_state['values']['remote']) == empty($_FILES['files']['name']['upload'])) {
$file_upload = $this->getRequest()->files->get('files[upload]', NULL, TRUE);
if (empty($form_state['values']['remote']) == empty($file_upload)) {
form_set_error('remote', $form_state, $this->t('You must <em>either</em> upload a file or enter a URL.'));
}
}
......
......@@ -74,11 +74,12 @@ public function buildForm(array $form, array &$form_state) {
* {@inheritdoc}
*/
public function validateForm(array &$form, array &$form_state) {
if (!empty($_FILES['files']['error']['import_tarball'])) {
form_set_error('import_tarball', $form_state, $this->t('The import tarball could not be uploaded.'));
$file_upload = $this->getRequest()->files->get('files[import_tarball]', NULL, TRUE);
if ($file_upload && $file_upload->isValid()) {
$form_state['values']['import_tarball'] = $file_upload->getRealPath();
}
else {
$form_state['values']['import_tarball'] = $_FILES['files']['tmp_name']['import_tarball'];
form_set_error('import_tarball', $form_state, $this->t('The import tarball could not be uploaded.'));
}
}
......
......@@ -33,8 +33,8 @@ public function getFormId() {
* The filter format for which this dialog corresponds.
*/
public function buildForm(array $form, array &$form_state, FilterFormat $filter_format = NULL) {
// The default values are set directly from $_POST, provided by the
// editor plugin opening the dialog.
// The default values are set directly from \Drupal::request()->request,
// provided by the editor plugin opening the dialog.
if (!isset($form_state['image_element'])) {
$form_state['image_element'] = isset($form_state['input']['editor_object']) ? $form_state['input']['editor_object'] : array();
}
......
......@@ -33,8 +33,8 @@ public function getFormId() {
* The filter format for which this dialog corresponds.
*/
public function buildForm(array $form, array &$form_state, FilterFormat $filter_format = NULL) {
// The default values are set directly from $_POST, provided by the
// editor plugin opening the dialog.
// The default values are set directly from \Drupal::request()->request,
// provided by the editor plugin opening the dialog.
$input = isset($form_state['input']['editor_object']) ? $form_state['input']['editor_object'] : array();
$form['#tree'] = TRUE;
......
......@@ -777,8 +777,9 @@ function file_save_upload($form_field_name, array &$form_state, $validators = ar
$user = \Drupal::currentUser();
static $upload_cache;
$file_upload = \Drupal::request()->files->get("files[$form_field_name]", NULL, TRUE);
// Make sure there's an upload to process.
if (empty($_FILES['files']['name'][$form_field_name])) {
if (empty($file_upload)) {
return NULL;
}
......@@ -793,40 +794,39 @@ function file_save_upload($form_field_name, array &$form_state, $validators = ar
// Prepare uploaded files info. Representation is slightly different
// for multiple uploads and we fix that here.
$uploaded_files = $_FILES;
if (!is_array($uploaded_files['files']['name'][$form_field_name])) {
foreach (array('name', 'type', 'tmp_name', 'error', 'size') as $value)
$uploaded_files['files'][$value][$form_field_name] = array($uploaded_files['files'][$value][$form_field_name]);
$uploaded_files = $file_upload;
if (!is_array($file_upload)) {
$uploaded_files = array($file_upload);
}
$files = array();
foreach ($uploaded_files['files']['name'][$form_field_name] as $i => $name) {
foreach ($uploaded_files as $i => $file_info) {
// Check for file upload errors and return FALSE for this file if a lower
// level system error occurred. For a complete list of errors:
// See http://php.net/manual/features.file-upload.errors.php.
switch ($uploaded_files['files']['error'][$form_field_name][$i]) {
switch ($file_info->getError()) {
case UPLOAD_ERR_INI_SIZE:
case UPLOAD_ERR_FORM_SIZE:
drupal_set_message(t('The file %file could not be saved because it exceeds %maxsize, the maximum allowed size for uploads.', array('%file' => $name, '%maxsize' => format_size(file_upload_max_size()))), 'error');
drupal_set_message(t('The file %file could not be saved because it exceeds %maxsize, the maximum allowed size for uploads.', array('%file' => $file_info->getFilename(), '%maxsize' => format_size(file_upload_max_size()))), 'error');
$files[$i] = FALSE;
continue;
case UPLOAD_ERR_PARTIAL:
case UPLOAD_ERR_NO_FILE:
drupal_set_message(t('The file %file could not be saved because the upload did not complete.', array('%file' => $name)), 'error');
drupal_set_message(t('The file %file could not be saved because the upload did not complete.', array('%file' => $file_info->getFilename())), 'error');
$files[$i] = FALSE;
continue;
case UPLOAD_ERR_OK:
// Final check that this is a valid upload, if it isn't, use the
// default error handler.
if (is_uploaded_file($uploaded_files['files']['tmp_name'][$form_field_name][$i])) {
if (is_uploaded_file($file_info->getRealPath())) {
break;
}
// Unknown error
default:
drupal_set_message(t('The file %file could not be saved. An unknown error