'=', '!' => '!', '<' => '<', '<=' => '<=', '>' => '>', '>=' => '>=', '~' => '~', ); $form = array('#tree' => TRUE); $items = array(); $fix_depth = FALSE; if (empty($form_state['input']['old_items'])) { $items = themekey_load_rules(); } else { $items = $form_state['input']['old_items']; $fix_depth = TRUE; } $parent_options = array_merge(array(0), array_keys($items)); $parent_options = array_combine($parent_options, $parent_options); foreach ($items as $item) { if ($fix_depth) { if (!empty($item['parent'])) { $item['depth'] = $items[$item['parent']]['depth'] + 1; } else { $item['depth'] = 0; } } $form['old_items'][$item['id']]['depth'] = array( '#type' => 'hidden', '#value' => $item['depth'], ); $form['old_items'][$item['id']]['id'] = array( '#type' => 'hidden', '#value' => $item['id'], ); $property = $item['property']; $wildcard = ''; $static = FALSE; if (!in_array($property, $properties)) { if (!empty($attributes[$property]['static'])) { $static = TRUE; $form['old_items'][$item['id']]['property'] = array( '#type' => 'hidden', '#default_value' => $property, '#value' => $property, '#prefix' => '' . $property . '', ); $form['old_items'][$item['id']]['operator'] = array( '#type' => 'hidden', '#default_value' => '=', '#value' => '=', ); $form['old_items'][$item['id']]['value'] = array( '#type' => 'hidden', '#default_value' => 'static', '#value' => 'static', ); $form['old_items'][$item['id']]['theme'] = array( '#type' => 'select', '#default_value' => 'default', '#options' => array('default' => t('Triggered')), ); } else { $property = 'drupal:path:wildcard'; $wildcard = $item['property']; } } if (!isset($form['old_items'][$item['id']]['property'])) { $form['old_items'][$item['id']]['property'] = array( '#type' => 'select', '#default_value' => $property, '#options' => $properties, ); } $form['old_items'][$item['id']]['wildcard'] = array( '#type' => 'textfield', '#default_value' => $wildcard, '#size' => 10, '#maxlength' => 255, ); if (!isset($form['old_items'][$item['id']]['operator'])) { $form['old_items'][$item['id']]['operator'] = array( '#type' => 'select', '#default_value' => $item['operator'], '#options' => $operators, ); } if (!isset($form['old_items'][$item['id']]['value'])) { $form['old_items'][$item['id']]['value'] = array( '#type' => 'textfield', '#default_value' => $item['value'], '#size' => 20, '#maxlength' => 255, ); } $form['old_items'][$item['id']]['parent'] = array( '#type' => 'select', '#default_value' => $item['parent'], '#options' => $parent_options, ); if (!isset($form['old_items'][$item['id']]['theme'])) { $form['old_items'][$item['id']]['theme'] = array( '#type' => 'select', '#default_value' => $item['theme'], '#options' => $themes, ); } $form['old_items'][$item['id']]['enabled'] = array( '#type' => 'checkbox', '#default_value' => $item['enabled'], ); $form['old_items'][$item['id']]['weight'] = array( '#type' => 'weight', '#delta' => 50, '#default_value' => $item['weight'], ); $form['old_items'][$item['id']]['delete'] = array( '#markup' => $static ? '' : l(t('delete'), 'admin/config/user-interface/themekey/properties/delete/' . $item['id']), ); } $form['new_item']['property'] = array( '#type' => 'select', '#default_value' => !empty($_GET['property']) ? check_plain($_GET['property']) : '', '#options' => $properties, ); $form['new_item']['wildcard'] = array( '#type' => 'textfield', '#default_value' => '', '#size' => 10, '#maxlength' => 255, ); $form['new_item']['operator'] = array( '#type' => 'select', '#default_value' => '=', '#options' => $operators, ); $form['new_item']['value'] = array( '#type' => 'textfield', '#default_value' => !empty($_GET['value']) ? check_plain($_GET['value']) : '', '#size' => 25, '#maxlength' => 255, ); $form['new_item']['theme'] = array( '#type' => 'select', '#default_value' => 'default', '#options' => $themes, ); $form['new_item']['enabled'] = array( '#type' => 'checkbox', '#default_value' => TRUE, ); $form['buttons']['submit'] = array( '#type' => 'submit', '#value' => t('Save configuration'), ); return $form; } /** * Validation of * @see themekey_rule_chain_form() */ function themekey_rule_chain_form_validate(&$form, $form_state) { module_invoke_all('themekey_load_validators'); $attributes = variable_get('themekey_attributes', array()); $values = $form_state['values']; if (!empty($values['old_items'])) { foreach ($values['old_items'] as $key_1 => $value_1) { if ($value_1['enabled'] && !themekey_check_theme_enabled($value_1['theme'])) { form_set_error('old_items][' . $key_1 . '][theme', check_plain(t('Theme is not activated'))); } if (empty($value_1['property'])) { form_set_error('old_items][' . $key_1 . '][property', check_plain(t('Property missing'))); } else { if (0 == drupal_strlen($value_1['value'])) { form_set_error('old_items][' . $key_1 . '][value', check_plain(t('You must enter a value'))); } elseif (!empty($attributes[$value_1['property']]['validator'])) { //validate rule with custom validator $validator = $attributes[$value_1['property']]['validator']; if (function_exists($validator)) { $rule = array( 'property' => $value_1['property'], 'wildcard' => $value_1['wildcard'], 'operator' => $value_1['operator'], 'value' => $value_1['value'], ); $errors = $validator($rule); foreach ($errors as $element => $msg) { form_set_error('old_items][' . $key_1 . '][' . $element, filter_xss($msg, array('em'))); } } else { form_set_error('old_items][' . $key_1 . '][property', filter_xss(t('ThemeKey requested an unknown validator called %validator to validate property %property', array('%validator' => $validator, '%property' => $value_1['property'])), array('em'))); } } } foreach ($values['old_items'] as $key_2 => $value_2) { if ($key_2 == $key_1) { continue; } if ($value_2['enabled'] && !empty($value_1['value']) && $value_2['property'] == $value_1['property'] && $value_2['operator'] == $value_1['operator'] && $value_2['value'] == $value_1['value'] && ($value_2['parent'] == $value_1['parent'] || $value_2['parent'] == $value_1['id'])) { if ('drupal:path:wildcard' != $value_2['property'] || ('drupal:path:wildcard' == $value_2['property'] && $value_2['wildcard'] == $value_1['wildcard'])) { // We have two identical rules with same 'indention' in a chain. // This is allowed only if first one has childs and second one has none and one isn't the parent of the other if (!$value_2['parent'] == $value_1['id']) { $has_childs_1 = FALSE; $has_childs_2 = FALSE; foreach ($values['old_items'] as $key_3 => $value_3) { if ($value_3['parent'] == $value_1['id']) { $has_childs_1 = TRUE; } if ($value_3['parent'] == $value_2['id']) { $has_childs_2 = TRUE; } if ($has_childs_1 && $has_childs_2) { break; } } if ((($value_1['weight'] < $value_2['weight']) && $has_childs_1 && !$has_childs_2) || (($value_1['weight'] > $value_2['weight']) && !$has_childs_1 && $has_childs_2)) { // no error continue; } elseif (($value_1['weight'] > $value_2['weight']) && $has_childs_1 && !$has_childs_2) { form_set_error('old_items][' . $key_1 . '][property', check_plain(t('Theme switching rule could never be reached'))); continue; } elseif (($value_1['weight'] < $value_2['weight']) && !$has_childs_1 && $has_childs_2) { form_set_error('old_items][' . $key_1 . '][property', check_plain(t('Theme switching rule hides a later one'))); continue; } elseif (($value_1['weight'] < $value_2['weight']) && $has_childs_1 && $has_childs_2) { form_set_error('old_items][' . $key_1 . '][property', check_plain(t('Theme switching rule should be combined with an identical one below'))); continue; } elseif (($value_1['weight'] > $value_2['weight']) && $has_childs_1 && $has_childs_2) { form_set_error('old_items][' . $key_1 . '][property', check_plain(t('Theme switching rule should be combined with an identical one above'))); continue; } } form_set_error('old_items][' . $key_1 . '][property', check_plain(t('You entered two identical theme switching rules in the chain'))); form_set_error('old_items][' . $key_2 . '][property', check_plain(t('You entered two identical theme switching rules in the chain'))); } } } } } if (!empty($values['new_item']['value'])) { if ($values['new_item']['enabled'] && !themekey_check_theme_enabled($values['new_item']['theme'])) { form_set_error('new_item][theme', check_plain(t('Theme is not activated'))); } if (empty($values['new_item']['property'])) { form_set_error('new_item][property', check_plain(t('Property missing'))); } else { if (!empty($attributes[$values['new_item']['property']]['validator'])) { //validate rule with custom validator $validator = $attributes[$values['new_item']['property']]['validator']; if (function_exists($validator)) { $rule = array( 'property' => $values['new_item']['property'], 'wildcard' => $values['new_item']['wildcard'], 'operator' => $values['new_item']['operator'], 'value' => $values['new_item']['value'], ); $errors = $validator($rule); foreach ($errors as $element => $msg) { form_set_error('new_item][' . $element, filter_xss($msg)); } } else { form_set_error('new_item][property', filter_xss(t('ThemeKey requested an unknown validator called %validator to validate the property, %property', array('%validator' => $validator, '%property' => $value_1['property']))), array('em')); } } } } } /** * Form submission handler for themekey_rule_chain_form(). * * @see themekey_rule_chain_form() */ function themekey_rule_chain_form_submit($form, &$form_state) { $max_weight = 0; if (!empty($form_state['values']['old_items'])) { foreach ($form_state['values']['old_items'] as $id => $item) { if ($item['weight'] > $max_weight) { $max_weight = $item['weight']; } $item['id'] = $id; if ('drupal:path:wildcard' == $item['property']) { $item['property'] = $item['wildcard']; } unset($item['wildcard']); themekey_rule_set($item); } } if (!empty($form_state['values']['new_item']['value']) || '0' === $form_state['values']['new_item']['value']) { $item = $form_state['values']['new_item']; $item['parent'] = 0; $item['weight'] = $max_weight + 1; if ('drupal:path:wildcard' == $item['property']) { $item['property'] = $item['wildcard']; } unset($item['wildcard']); themekey_rule_set($item); } drupal_set_message(check_plain(t('The configuration options have been saved. Trying to clear page cache ...'))); // fast deletion of page cache (truncate) cache_clear_all('*', 'cache_page', TRUE); } /** * Form builder for the ThemeKey settings form. * * @ingroup forms */ function themekey_settings_form($form, &$form_state) { $form['settings'] = array( '#type' => 'fieldset', '#title' => t('General Settings'), '#collapsible' => FALSE, '#collapsed' => FALSE, ); $form['settings']['themekey_path_case_sensitive'] = array( '#type' => 'checkbox', '#title' => t('Property drupal:path is case sensitive'), '#default_value' => variable_get('themekey_path_case_sensitive', 0), '#description' => t('Drupal paths are case insensitive by default. Modules like Global Redirect might change this behavior.'), ); $form['settings']['themekey_allthemes'] = array( '#type' => 'checkbox', '#title' => t('Provide all themes for selection'), '#default_value' => variable_get('themekey_allthemes', 0), '#description' => t('Make all installed themes available for selection, not enabled ones only.'), ); $form['settings']['themekey_override_custom_theme'] = array( '#type' => 'checkbox', '#title' => t('Force custom theme overriding'), '#default_value' => variable_get('themekey_override_custom_theme', 0), '#description' => t('Select this option to force ThemeKey to set the custom theme. Otherwise ThemeKey will set the custom theme only if it\'s not already set by a different module.
Note: If you activate this feature it turns off theme switching of some other modules like Organic Groups.'), ); $form['settings']['themekey_theme_maintain'] = array( '#type' => 'checkbox', '#title' => t('Retain the theme until a new theme is set'), '#default_value' => variable_get('themekey_theme_maintain', 0), '#description' => t('Select this option to have logged-in users stay in the same theme until they browse to a new page with an explicit theme set.'), ); $form['settings']['themekey_theme_maintain_anonymous'] = array( '#type' => 'checkbox', '#title' => t('Retain the theme until a new theme is set for anonymous users'), '#default_value' => variable_get('themekey_theme_maintain_anonymous', 0), '#description' => t('Select this option to have anonymous users stay in the same theme until they browse to a new page with an explicit theme set.
Warning: This feature is only working correctly if you turn off page caching or use a Drupal core that supports lazy session initialization like !cdclink or !pflink.', array('!cdclink' => l(t('!path', array('!path' => 'Cocomore Drupal Core')), 'http://drupal.cocomore.com/node/175', array('attributes' => array('target' => '_blank'))), '!pflink' => l(t('!path', array('!path' => 'Pressflow')), 'https://launchpad.net/pressflow/6.x/', array('attributes' => array('target' => '_blank'))))), ); if (module_exists('forum')) { $form['settings']['themekey_module_forum_triggers_taxonomy_vid'] = array( '#type' => 'checkbox', '#title' => t('Forum pages trigger property taxonomy:vid'), '#default_value' => variable_get('themekey_module_forum_triggers_taxonomy_vid', 0), '#description' => t('Property taxonomy:vid is set when a single node is shown (e.g. /node/17). If this option is selected, forum pages like /forum/28 will set taxonomy:vid as well.'), ); } $form['settings']['themekey_cron_page_cache'] = array( '#type' => 'checkbox', '#title' => t('Cron cleans up page cache'), '#default_value' => variable_get('themekey_cron_page_cache', 1), '#description' => t('Select this option if ThemeKey should check rules containing time-based properties when cron runs. ThemeKey will carefully clean up the page cache if necessary to provide the right theme to anonymous users automatically, e.g. a Christmas theme.'), ); return system_settings_form($form); } /** * Themes themekey_rule_chain_form() and adds drag'n'drop features. * * @ingroup themeable */ function theme_themekey_rule_chain_form($variables) { $form = $variables['form']; themekey_admin_theme_warning(); $output = ''; $rows = array(); if (!empty($form['old_items'])) { $num_childs = array(); $parents_disabled = array(); $attributes = variable_get('themekey_attributes', array()); foreach ($form['old_items'] as $key => $item) { if (is_numeric($key) && !empty($item['property'])) { $parents_disabled[$key] = FALSE; if (!empty($parents_disabled[$item['parent']['#value']])) { $form['old_items'][$key]['enabled']['#value'] = 0; } if (!$form['old_items'][$key]['enabled']['#value']) { $parents_disabled[$key] = TRUE; } elseif (!empty($item['parent']['#value'])) { $num_childs[$item['parent']['#value']] = empty($num_childs[$item['parent']['#value']]) ? 1 : $num_childs[$item['parent']['#value']] + 1; } } } foreach ($form['old_items'] as $key => $item) { if (is_numeric($key) && !empty($item['property'])) { $row = (isset($form['old_items'][$key]['#attributes']) && is_array($form['old_items'][$key]['#attributes'])) ? $form['old_items'][$key]['#attributes'] : array(); // Add special classes to be used for tabledrag.js. $form['old_items'][$key]['id']['#attributes']['class'] = array('themekey-property-id'); $form['old_items'][$key]['parent']['#attributes']['class'] = array('themekey-property-parent'); $form['old_items'][$key]['weight']['#attributes']['class'] = array('themekey-property-weight'); // Add special classes to be used for themekey-properties.js. $form['old_items'][$key]['property']['#attributes']['class'] = array('themekey-property-property themekey-fadeable'); $form['old_items'][$key]['wildcard']['#attributes']['class'] = array('themekey-property-wildcard themekey-fadeable'); $form['old_items'][$key]['operator']['#attributes']['class'] = array('themekey-fadeable'); $form['old_items'][$key]['value']['#attributes']['class'] = array('themekey-fadeable'); $form['old_items'][$key]['enabled']['#attributes']['class'] = array('themekey-property-enabled'); $form['old_items'][$key]['theme']['#attributes']['class'] = array('themekey-property-theme themekey-fadeable'); // form items of type markup don't have attributes $form['old_items'][$key]['delete']['#markup'] = str_replace('