'. t('Enter the path you wish to create the alias for, followed by the name of the new alias.') .'
'; } +} + +/** + * Implementation of hook_theme() + */ +function path_theme() { + return array( + 'path_form' => array( + 'arguments' => array('form' => NULL), + ), + ); } /** @@ -74,11 +85,18 @@ function path_menu() { /** * Menu callback; handles pages for creating and editing URL aliases. */ -function path_admin_edit($pid = 0) { - if ($pid) { - $alias = path_load($pid); - drupal_set_title(check_plain($alias['dst'])); - $output = path_form($alias); +function path_admin_edit($language = '') { + $args = func_get_args(); + unset($args[0]); + // Unset the first language argument. + + $src = implode('/', $args); + + if (!empty($src)) { + $language = (isset($language) && $language != 'all') ? $language : ''; + $aliases = path_load('', $src, $language); + drupal_set_title(check_plain($src)); + $output = path_form($src, $language, $aliases); } else { $output = path_form(); @@ -124,7 +142,7 @@ function path_admin_delete($pid = 0) { /** * Set an aliased path for a given Drupal path, preventing duplicates. */ -function path_set_alias($path = NULL, $alias = NULL, $pid = NULL, $language = '') { +function path_set_alias($path = NULL, $alias = NULL, $pid = NULL, $active = '', $language = '') { if ($path && !$alias) { // Delete based on path db_query("DELETE FROM {url_alias} WHERE src = '%s' AND language = '%s'", $path, $language); @@ -145,11 +163,14 @@ function path_set_alias($path = NULL, $a if ($alias_count == 0) { if ($pid) { // Existing path changed data - db_query("UPDATE {url_alias} SET src = '%s', dst = '%s', language = '%s' WHERE pid = %d", $path, $alias, $language, $pid); + db_query("UPDATE {url_alias} SET src = '%s', dst = '%s', active = %d, language = '%s' WHERE pid = %d", $path, $alias, $active, $language, $pid); } else { // No such alias yet in this language - db_query("INSERT INTO {url_alias} (src, dst, language) VALUES ('%s', '%s', '%s')", $path, $alias, $language); + if ($active) { + db_query("UPDATE {url_alias} SET active = '' WHERE src = '%s'", $path); + } + db_query("INSERT INTO {url_alias} (src, dst, active, language) VALUES ('%s', '%s', %d, '%s')", $path, $alias, $active, $language); } } // The alias exists. @@ -160,10 +181,9 @@ function path_set_alias($path = NULL, $a } else { // This will delete the path that alias was originally pointing to. - path_set_alias(NULL, $alias, NULL, $language); + path_set_alias(NULL, $alias, NULL, $active, $language); // This will remove the current aliases of the path. - path_set_alias($path, NULL, NULL, $language); - path_set_alias($path, $alias, NULL, $language); + path_set_alias($path, $alias, NULL, $active, $language); } } if ($alias_count == 0 || $path_count == 0) { @@ -175,43 +195,155 @@ function path_set_alias($path = NULL, $a /** * Return a form for editing or creating an individual URL alias. */ -function path_form($edit = array('src' => '', 'dst' => '', 'language' => '', 'pid' => NULL)) { +function path_form($src = '', $language = '', $aliases = array()) { $form['#submit'][] = 'path_form_submit'; $form['#validate'][] = 'path_form_validate'; - $form['#alias'] = $edit; - - $form['src'] = array( + $form['#theme'] = 'path_form'; + $form['aliases']['#tree'] = TRUE; + + $active_alias = 'src'; + $options['src'] = ''; + $form['aliases']['src'] = array( '#type' => 'textfield', '#title' => t('Existing system path'), - '#default_value' => $edit['src'], + '#default_value' => $src, '#maxlength' => 64, '#size' => 45, '#description' => t('Specify the existing path you wish to alias. For example: node/28, forum/1, taxonomy/term/1+2.'), '#field_prefix' => url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q=') ); - $form['dst'] = array( + + $options['new'] = ''; + $form['aliases']['new'] = array( '#type' => 'textfield', - '#title' => t('Path alias'), - '#default_value' => $edit['dst'], + '#title' => t('New alias'), '#maxlength' => 64, - '#size' => 45, - '#description' => t('Specify an alternative path by which this data can be accessed. For example, type "about" when writing an about page. Use a relative path and don\'t add a trailing slash or the URL alias won\'t work.'), + '#size' => 45, + '#weight' => 1, + '#description' => t('Specify a new alternative path by which this data can be accessed. For example: about, faq, etc.'), '#field_prefix' => url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q=') ); + if (!empty($aliases)) { + $count = 1; + foreach ($aliases as $alias) { + $active_alias = !empty($alias['active']) ? $alias['pid'] : $active_alias; + $options[$alias['pid']] = ''; + $form['aliases'][$alias['pid']] = array( + '#type' => 'textfield', + '#title' => t('Alias !number', array('!number' => ($count++))), + '#default_value' => $alias['dst'], + '#maxlength' => 64, + '#size' => 45, + '#field_prefix' => url(NULL, array('absolute' => TRUE)) . (variable_get('clean_url', 0) ? '' : '?q=') + ); + } + } + else { + $active_alias = 'new'; + } + $form['active'] = array( + '#type' => 'radios', + '#options' => $options, + '#default_value' => $active_alias, + ); + + if (!empty($aliases)) { + $attributes = array('disabled' => 'disabled'); + } + else { + $attributes = array(); + } + // This will be a hidden value unless locale module is enabled $form['language'] = array( '#type' => 'value', - '#value' => $edit['language'] + '#value' => $language, + '#attributes' => $attributes ); - if ($edit['pid']) { - $form['pid'] = array('#type' => 'hidden', '#value' => $edit['pid']); - $form['submit'] = array('#type' => 'submit', '#value' => t('Update alias')); + + if (!empty($aliases)) { + $form['edit_mode'] = array('#type' => 'value', '#value' => TRUE); + $form['submit'] = array('#type' => 'submit', '#value' => t('Update')); } else { $form['submit'] = array('#type' => 'submit', '#value' => t('Create new alias')); } return $form; +} + +/** + * Theme the path add/edit form. + */ +function theme_path_form($form) { + $header = array(t('Active'), t('Alias')); + $rows = array(); + uasort($form['aliases'], '_element_sort'); + foreach (element_children($form['aliases']) as $key) { + $rows[] = array( + drupal_render($form['active'][$key]), + drupal_render($form['aliases'][$key]), + ); + } + $output = theme('table', $header, $rows); + $output .= drupal_render($form); + return $output; +} + +/** + * Verify that a new URL alias is valid + */ +function path_form_validate(&$form_values) { + $active = $form_values['active']; + if ($active == 'new' && empty($form_values['aliases'][$active])) { + form_set_error('aliases][new', t('You can not set an empty field as an active alias.')); + } + + // Language is only set if locale module is enabled, otherwise save for all languages. + $language = isset($form_values['language']) ? $form_values['language'] : ''; + + foreach ($form_values['aliases'] as $pid => $alias) { + if ($alias && db_result(db_query("SELECT COUNT(dst) FROM {url_alias} WHERE pid != %d AND dst = '%s' AND language = '%s'", $pid, $alias, $language))) { + form_set_error('aliases]['. $pid, t('The alias %alias is already in use in this language.', array('%alias' => $alias))); + } + } +} + +/** + * Save a new URL alias to the database. + */ +function path_form_submit($form_values, $form, &$form_state) { + $src = $form_values['aliases']['src']; + $new = $form_values['aliases']['new']; + + // Language is only set if locale module is enabled, otherwise save for all languages. + $language = isset($form_values['language']) ? $form_values['language'] : ''; + + unset($form_values['aliases']['src'], $form_values['aliases']['new']); + // Unset source and new alias, preparing a list of existing aliases. + + if (!empty($form_values['aliases'])) { + foreach ($form_values['aliases'] as $pid => $alias) { + if (!empty($alias)) { + path_set_alias($src, $alias, $pid, ($pid == $form_values['active']), $language); + } + else { + // Delete based on alias + db_query("DELETE FROM {url_alias} WHERE pid = %d", $pid); + drupal_clear_path_cache(); + } + } + } + + if (!empty($new)) { + path_set_alias($src, $new, NULL, ($form_values['active'] == 'new'), $language); + } + + menu_rebuild(); + drupal_set_message(t('The aliases have been saved.')); + + //$form_state['redirect'] = 'admin/build/path'; + return; } /** @@ -307,7 +439,10 @@ function path_perm() { * When filter key passed, perform a standard search on the given key, * and return the list of matching URL aliases. */ -function path_admin_overview($keys = NULL) { +function path_admin_overview() { + $args = func_get_args(); + $keys = implode('/', $args); + // Add the filter form above the overview table. $output = drupal_get_form('path_admin_filter_form', $keys); // Enable language column if locale is enabled or if we have any alias with language @@ -337,7 +472,8 @@ function path_admin_overview($keys = NUL $rows = array(); $destination = drupal_get_destination(); while ($data = db_fetch_object($result)) { - $row = array(check_plain($data->dst), check_plain($data->src), l(t('edit'), "admin/build/path/edit/$data->pid", array('query' => $destination)), l(t('delete'), "admin/build/path/delete/$data->pid", array('query' => $destination))); + $language = !empty($data->language) ? $data->language : 'all' ; + $row = array(check_plain($data->dst), check_plain($data->src), l(t('edit'), "admin/build/path/edit/$language/$data->src", array('query' => $destination)), l(t('delete'), "admin/build/path/delete/$data->pid", array('query' => $destination))); if ($multilanguage) { $row[4] = $row[3]; $row[3] = $row[2]; @@ -360,71 +496,65 @@ function path_admin_overview($keys = NUL /** * Fetch a specific URL alias from the database. */ -function path_load($pid) { - return db_fetch_array(db_query('SELECT * FROM {url_alias} WHERE pid = %d', $pid)); -} - -/** - * Verify that a new URL alias is valid - */ -function path_form_validate($form_values, $form, &$form_state) { - $src = $form_values['src']; - $dst = $form_values['dst']; - $pid = isset($form_values['pid']) ? $form_values['pid'] : 0; - // Language is only set if locale module is enabled, otherwise save for all languages. - $language = isset($form_values['language']) ? $form_values['language'] : ''; - - if (db_result(db_query("SELECT COUNT(dst) FROM {url_alias} WHERE pid != %d AND dst = '%s' AND language = '%s'", $pid, $dst, $language))) { - form_set_error('dst', t('The alias %alias is already in use in this language.', array('%alias' => $dst))); +function path_load($pid, $src = '', $language = '') { + if (!empty($pid)) { + return db_fetch_array(db_query('SELECT * FROM {url_alias} WHERE pid = %d', $pid)); + } + else if (!empty($src)) { + $result = db_query("SELECT * FROM {url_alias} WHERE src = '%s' AND language = '%s'", $src, $language); + while ($row = db_fetch_array($result)) { + $output[] = $row; + } + return $output; } } /** - * Save a new URL alias to the database. - */ -function path_form_submit($form_values, $form, &$form_state) { - // Language is only set if locale module is enabled - path_set_alias($form_values['src'], $form_values['dst'], isset($form_values['pid']) ? $form_values['pid'] : 0, isset($form_values['language']) ? $form_values['language'] : ''); - - drupal_set_message(t('The alias has been saved.')); - $form_state['redirect'] = 'admin/build/path'; - return; -} - -/** * Return a form to filter URL aliases. */ -function path_admin_filter_form($keys = '') { +function path_admin_filter_form() { + $args = func_get_args(); + $keys = implode('/', $args); + $form['#attributes'] = array('class' => 'search-form'); - $form['basic'] = array('#type' => 'fieldset', - '#title' => t('Filter aliases') - ); - $form['basic']['inline'] = array('#prefix' => '