| 1 layout.admin.inc | layout_settings_form_validate(&$form, &$form_state) |
Validates layout_settings_form(), ensuring a valid path.
File
- core/
modules/ layout/ layout.admin.inc, line 970 - Admin page callbacks for the Layout module.
Code
function layout_settings_form_validate(&$form, &$form_state) {
/** @var Layout $layout */
$layout = $form_state['layout'];
// Remove trailing and preceding slashes.
$path = $form_state['values']['path'] = trim($form_state['values']['path'], '/');
if (strpos($path, '%') === 0) {
form_error($form['path'], t('The first part of a path may not be a placeholder.'));
}
// Ensure the path is not already an alias to something else.
if (strpos($path, '%') === FALSE) {
$alias = db_query('SELECT * FROM {url_alias} WHERE alias = :path', array(':path' => $path))->fetchObject();
if ($alias) {
$error = t('That path is currently assigned to be an alias for "@alias".', array('@alias' => $alias->source));
if (user_access('administer url aliases')) {
$error .= ' ' . t('<a href="!url">Delete the alias first</a>, then save this layout.', array('!url' => url('admin/config/urls/path/delete/' . $alias->pid, array('query' => array('destination' => $_GET['q'])))));
}
form_error($form['path'], $error);
}
}
// Ensure path is properly formed.
_layout_set_message_on_path_error($form, 'path', $path);
// Ensure that all conditions have context requirements met.
$context_plugins = array(
'user', // The user plugin is always available for the current user.
);
$contexts = layout_context_required_by_path($path);
foreach ($contexts as $context) {
$context_plugins[] = $context->plugin;
}
if ($form_state['clicked_button']['#value'] == t('Remove')) {
$key = $form_state['clicked_button']['#attributes']['data-layout-additional-path-remove'];
unset($form_state['additional_paths'][$key]);
}
if (isset($form_state['values']['additional_paths'])) {
foreach ($form_state['values']['additional_paths'] as $key => $additional_path) {
$additional_path = trim($additional_path);
if (!empty($additional_path)) {
$alias = NULL;
// Validation for if the primary path has placeholders.
if (strpos($path, '%') !== FALSE) {
// We check string length so we don't throw an error on each
// keystroke since this function runs on keyup when typing paths.
// Additional paths must have the same contexts as the main paths.
$path_parts = explode('%', $path);
$additional_path_parts = explode('%', $additional_path);
$count_path_parts = count($path_parts);
$count_additional_path_parts = count($additional_path_parts);
if (!isset($additional_path_parts[1])) {
if (strpos($path, $additional_path) === FALSE) {
form_set_error('additional_paths_wrapper', t('Additional path %path must match primary path %primary_path since the primary path has placeholders (%).',
array(
'%path' => $additional_path,
'%primary_path' => $path,
)
));
}
}
else {
// Path parts must match up to the last wildcard, otherwise we
// cannot be sure about context positions.
if (abs($count_additional_path_parts - $count_path_parts) > 1) {
form_set_error('additional_paths', t('Additional path %path should have the same number of placeholders as primary path %primary_path.',
array(
'%path' => $additional_path,
'%primary_path' => $path,
)
));
}
elseif ($count_additional_path_parts !== $count_path_parts) {
foreach ($path_parts as $i => $path_part) {
if (isset($additional_path_parts[$i]) && $additional_path_parts[$i] !== $path_parts[$i]) {
form_set_error('additional_paths', t('Additional path %path should have the same number of placeholders as primary path %primary_path.',
array(
'%path' => $additional_path,
'%primary_path' => $path,
)
));
break;
}
}
}
if ($path_parts[0] != $additional_path_parts[0]) {
form_set_error('additional_paths_wrapper', t('Additional path %path must match primary path %primary_path since the primary path has placeholders (%).',
array(
'%path' => $additional_path,
'%primary_path' => $path,
)
));
}
}
}
else {
if (strpos($additional_path, '%')) {
form_set_error('additional_paths_wrapper', t('Additional path %path must match primary path %primary_path since the primary path has no placeholders (%).',
array(
'%path' => $additional_path,
'%primary_path' => $path,
)
));
}
// An additional path like node/5 shouldnt be allowed if there is not
// a context-generating path as primary. But anypath/5 would be fine
// as a layout-provided path.
$all_info = _layout_get_all_info('layout_context');
$split_additional_path = preg_split('/\/[0-9_]+/', $additional_path);
$cleaned_additional_path = $split_additional_path[0];
foreach ($all_info as $context_info) {
foreach ($context_info['menu paths'] as $context_path) {
$cleaned_path = preg_replace('/%[a-z0-9_]+/', '%', $context_path);
if ($cleaned_path == $cleaned_additional_path . '/%') {
form_set_error('additional_paths_wrapper', t('Additional path %path cannot be used as an additional path. It requires a context in the primary path.',
array(
'%path' => $additional_path,
)
));
break 2;
}
}
}
}
if (strpos($additional_path, '%') === FALSE) {
$alias = db_query('SELECT * FROM {url_alias} WHERE alias = :path', array(':path' => $additional_path))->fetchObject();
if (!empty($alias)) {
// E.g. "about" is an alias of "node/2".
form_set_error('additional_paths_wrapper', t('Additional path %path is currently assigned to be an alias for "@alias" and cannot be used.',
array(
'%path' => $additional_path,
'@alias' => $alias->source,
)
));
}
}
// If no errors, save the additional path.
$form_state['additional_paths'][$key] = $additional_path;
// @todo: may not need this. Only if subcontexts like node/%/etc/% allowed.
$contexts_from_additional_paths = layout_context_required_by_path($additional_path);
foreach ($contexts_from_additional_paths as $contexts_from_additional_path) {
$context_plugins[] = $contexts_from_additional_path->plugin;
}
}
}
}
foreach ($layout->conditions as $key => $condition) {
$required_contexts = $condition->getRequiredContexts();
if (array_diff($required_contexts, $context_plugins)) {
form_error($form['conditions']['active'][$key], t('The condition \'!condition\' does not have the required contexts at this path. Remove the condition to save the layout.', array('!condition' => $condition->summary())));
}
}
}