? 404.php Index: .htaccess =================================================================== RCS file: /cvs/drupal/drupal/.htaccess,v retrieving revision 1.58 diff -u -3 -p -r1.58 .htaccess --- .htaccess 9 Oct 2004 20:41:49 -0000 1.58 +++ .htaccess 5 Jan 2005 10:40:55 -0000 @@ -12,8 +12,12 @@ Options -Indexes Options +FollowSymLinks -# Customized server error messages: -ErrorDocument 404 /index.php +# Customized server error messages and/or GET-only clean URLs. +# If you do not have mod_rewrite support on your server, setting the +# ErrorDocument to 404.php can allow clean URLs for GET, +# but not for POST (i.e. form submission) requests. For this to work, +# you need to enable GET-only clean URLs on the setup screen. +ErrorDocument 404 404.php # Set the default handler to index.php: DirectoryIndex index.php Index: includes/common.inc =================================================================== RCS file: /cvs/drupal/drupal/includes/common.inc,v retrieving revision 1.415 diff -u -3 -p -r1.415 common.inc --- includes/common.inc 30 Dec 2004 13:13:22 -0000 1.415 +++ includes/common.inc 5 Jan 2005 10:41:00 -0000 @@ -916,6 +916,25 @@ function format_name($object) { * must be explicitly generated by modules. */ + /** + * Reverse of parse_str(). Converts array into + * string with query format. + * + * By dante@lorenso.com, from PHP documentation. Might need to be moved away + * from here. + */ + +function query_str($params) { + if (count($params) == 0) return NULL; + + $str = ''; + foreach ($params as $key => $value) { + $str .= (strlen($str) < 1) ? '' : '&'; + $str .= $key . '=' . rawurlencode($value); + } + return ($str); +} + /** * Generate a form from a set of form elements. * @@ -931,9 +950,43 @@ function format_name($object) { * An HTML string with the contents of $form wrapped in a form tag. */ function form($form, $method = 'post', $action = NULL, $attributes = NULL) { + global $base_url; if (!$action) { $action = request_uri(); } + + $parsed_base_url = parse_url($base_url); + $base_path = $parsed_base_url['path']; + $parsed_action = parse_url($action); + $action_query = isset($parsed_action['query']) ? $parsed_action['query'] : NULL; + $action_path = isset($parsed_action['path']) ? $parsed_action['path'] : NULL; + $action_fragment = isset($parsed_action['fragment']) ? $parsed_action['fragment'] : NULL; + + if (substr($action_path, 0, strlen($base_path)) == $base_path) { + parse_str($action_query, $query_components); + + $remainder = substr($action_path,strlen($base_path)); + + // Chop a leading slash, if any. + if (substr($remainder, 0, 1) == "/") { + $remainder = substr($remainder, 1); + } + + if (isset($query_components['q'])) + { + // Query of style index.php?q=... + $q_string = $query_components['q']; + unset($query_components['q']); + + $action = url($q_string, query_str($query_components), $action_fragment, FALSE, TRUE); + } + else + { + // Query of "clean" style. + $action = url($remainder, $action_query, $action_fragment, FALSE, TRUE); + } + } + return '
\n"; } @@ -1395,33 +1448,47 @@ function form_weight($title = NULL, $nam * @param $absolute * Whether to force the output to be an absolute link (beginning with http:). * Useful for links that will be displayed outside the site, such as in an RSS feed. + * @param $isform + * Whether the URL is meant for form submission. This may suppress the generation + * of clean URLs in "Clean only for GET" mode. * @return * an HTML string containing a link to the given path. * * When creating links in modules, consider whether l() could be a better * alternative than url(). */ -function url($path = NULL, $query = NULL, $fragment = NULL, $absolute = FALSE) { +function url($path = NULL, $query = NULL, $fragment = NULL, $absolute = FALSE, $isform = FALSE) { global $base_url; static $script; - if (empty($script)) { - // On some web servers, such as IIS, we can't omit "index.php". So, we - // generate "index.php?q=foo" instead of "?q=foo" on anything that is not - // Apache. - $script = (strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') === false) ? 'index.php' : ''; - } - $path = drupal_get_path_alias($path); if (isset($fragment)) { $fragment = '#'. $fragment; } + $clean_url_var = variable_get('clean_url', '0'); + $use_clean_url = $clean_url_var != '0'; + + if ($isform && $use_clean_url == "2") { + $use_clean_url = FALSE; + + // We need to force absolute since we don't want /admin/index.php?q=... + // put together by the browser if all we specify is index.php?q=... . + $absolute = TRUE; + } + $base = ($absolute ? $base_url . '/' : ''); - if (variable_get('clean_url', '0') == '0') { + if (empty($script)) { + // On some web servers, such as IIS, we can't omit "index.php". So, we + // generate "index.php?q=foo" instead of "?q=foo" on anything that is not + // Apache. + $script = (strpos($_SERVER['SERVER_SOFTWARE'], 'Apache') === false) ? 'index.php' : ''; + } + + if (!$use_clean_url) { if (isset($path)) { if (isset($query)) { return $base . $script .'?q='. $path .'&'. $query . $fragment; Index: modules/system.module =================================================================== RCS file: /cvs/drupal/drupal/modules/system.module,v retrieving revision 1.190 diff -u -3 -p -r1.190 system.module --- modules/system.module 11 Dec 2004 14:13:24 -0000 1.190 +++ modules/system.module 5 Jan 2005 10:41:03 -0000 @@ -194,7 +194,7 @@ function system_view_general() { // check if clean URLs are supported (HTTP 200 = Ok) $request = drupal_http_request($GLOBALS['base_url'] . '/system/test'); $supported = $request->code == 200; - $group .= form_radios(t('Clean URLs'), 'clean_url', variable_get('clean_url', 0), array(t('Disabled'), t('Enabled')), t('This option makes Drupal emit clean URLs (i.e. without?q= in the URL). You\'ll need ModRewrite support for this to work. See the .htaccess file in Drupal\'s top-level directory for more information.'), false, $supported ? NULL : array('disabled' => 'disabled'));
+ $group .= form_radios(t('Clean URLs'), 'clean_url', variable_get('clean_url', 0), array(t('Disabled'), t('Enabled'), t('Enabled for GET requests only')), t('This option makes Drupal emit clean URLs (i.e. without ?q= in the URL). You will need ModRewrite or ErrorDocument support for this to work. See the .htaccess file in Drupal\'s top-level directory for more information.'), false, $supported ? NULL : array('disabled' => 'disabled'));
$output = form_group(t('General settings'), $group);