Download & Extend

Add compatibility with AJAX requests to admin theme module?

Project:Administration theme
Version:7.x-1.0
Component:Code
Category:bug report
Priority:normal
Assigned:Unassigned
Status:active

Issue Summary

Take a peek at http://drupal.org/node/409034

Comment #3 demonstrates the line causing the problem. No idea if this is fixable.

Comments

#1

hmm... it looks like $custom_theme is set by admin_menu depending on the path, but since the AJAX request comes from a different path, then that response doesn't take into account the different theme, and then... bang!

I'll have to think of a reasonable way to fix this. Patches and ideas are welcome. :)

#2

Project:Ajax Load» Administration theme
Version:6.x-1.2» 6.x-1.x-dev
Category:bug report» feature request
Status:active» needs review

Ok, after thinking about different ways to approach this problem, I think it should be the admin_theme module that needs to deal with this particular situation.

Here's how it could be done:

1) When admin_theme module switches the theme by settings the variable $custom_theme, then it should store this fact in some kind of per session persistent storage. It could be $_SESSION, or it could be setcookie(). I guess $_SESSION would be a safe choice and easier to implement. Probably, all user that are allowed to use the admin theme are registered users, so they already have a session.

2) admin_theme could check $_SESSION to see if previous page request enabled the admin theme, and grant admin theme again if the current request is ajax.

<?php
    
}
   }
 
// Check if previous request enabled admin theme.
+  if (isset($_SESSION['admin_theme'])) {
+    unset(
$_SESSION['admin_theme']);
+   
// If it is an ajax request, we need to send the same theme js/css
+    // so can grant access to admin theme with no path checking.
+    if (isset($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest') {
+     
$admin_theme_disallow = FALSE;
+     
$admin_theme = TRUE;
+    }
+  }
+
  
// we should not show the admin theme if the user has no access or the path is in the disallow list
  
if (!user_access('access admin theme') || $admin_theme_disallow) {
?>

<?php
    
global $custom_theme;
    
$custom_theme = variable_get('admin_theme', '0');
    
drupal_add_css(drupal_get_path('module', 'system') .'/admin.css', 'module');
+   
// Tell the next request we have enabled admin theme here.
+    $_SESSION['admin_theme'] = TRUE;
   }
?>

Please, test and let me know if it worked or not. Also, trasfering the issue to the admin_theme queue.

#3

Title:Module causes problems with editable fields used with admin themes or sections module» Add compatibility with AJAX requests to admin theme module?

Better title. I think. :)

#4

Can you roll this as a patch against a specific Drupal version please? Subscribing - I'd like to know the outcome of this.

#5

Ok, here's the patch. Its against the DRUPAL-6--1 branch of admin_menu module.

AttachmentSize
admin_theme-464738-5.patch 1.39 KB

#6

Applied the patch, but It did not solve the issue.
Im getting the same results as without the patch.

#7

@loze #6: "does not work" does not help much. What's your config and what is it that does not work?

#8

I have the same problem as the original issue linked to http://drupal.org/node/409034

I have a view, with editable fields set up.
and an admin theme.

When the view loads the editable fields ajax, it grabs the front-end css and applies it to my admin theme.

I applied the patch, cleared my caches, and get the same results as w/o the patch. (no visible changes)

I am using a zen subtheme on the front-end
and basic for the admin theme.
d6

thanks.

#9

This problem may also be related to #508536: play nice with $custom_theme, if those themes check for $custom_theme using isset(). Try to apply that patch, which is one-liner.

Another thing to try would to test with garland as front-end theme, and any other theme for the admin side. This would help isolate the problem.

#10

Thanks markus

I have applied the patch #508536
And changed the font-end theme to garland and set the admin theme to push button.
And still get the same results.

With firebug i can see that all the css files of the front-end theme are being added to the page when the ajax request is completed.

#11

Status:needs review» needs work

I'm lost on ideas. The patch in #5 works for me here.

hmm... well, we're using $_SESSION to tell the *next* request to use the admin theme if the previous one was using the admin theme. But this only affects the *next* request and if it is an AJAX request. If there's another request in the middle, or more than just one AJAX request, then the patch in #5 might not be enough.

So maybe this needs a bit more work... but I don't have time now. Ideas are welcome.

#12

Thanks for your help.

I was looking over the patch in #5 and it appears to check if the request enables the admin theme.
My problem is that on the admin theme, im getting front-end styles after the ajax request.

Could it be that the patch should check in the opposite direction as well?

#13

It looks like i was able to fix this by adding the following to admin_theme_init()

<?php
 
// Use the admin theme for the current request (if global admin theme setting is checked).
 
if ($admin_theme) {
    global
$custom_theme;
   
$custom_theme = variable_get('admin_theme', '0');
   
drupal_add_css(drupal_get_path('module', 'system') .'/admin.css', 'module');
   
// Tell the next request we have enabled admin theme here.
   
$_SESSION['admin_theme'] = TRUE;
  }
// THIS IS WHAT I ADDED
else {
 
$_SESSION['admin_theme'] = FALSE;
}
?>

Im not sure if this screws anything else up, but it appears to work for me now.
thanks again.

#14

I have been having problems similar to those previously mentioned in this thread, especially with CCK fields and Panels that use AJAX/AHAH to load/reload certain parts of admin pages.

I came up with a relatively simple solution that does not require the use of $_SESSION as it is rather unreliable. For instance, if a user loads an admin page, then loads a regular page in another tab, and then loads the AJAX functionality in the admin tab it will fail because $_SESSION['admin_theme'] was reset in the regular tab.

My patch relies on the HTTP headers X-Requested-With and Referer, meaning that if those are not set correctly by the user agent it will not work. It has however been tested in a number of modern browsers that all apply these correctly.

Basically if the HTTP headers are set it will use the path from $_SERVER['HTTP_REFERER'] instead of $_GET['q'], thus pretending to be the requesting page itself and applying admin theme as necessary.

I would like to hear your opinions on it and see if it needs further improvement.

<?php
/**
  * Implementation of hook_init().
  */
function admin_theme_init() {
  
$admin_theme_disallow = FALSE;
  
$admin_theme = FALSE;
-
+
// set the path for the current page
$path = $_GET['q'];
+
// handle ajax requests
+  if (!empty($_SERVER['HTTP_X_REQUESTED_WITH']) && strtolower($_SERVER['HTTP_X_REQUESTED_WITH']) == 'xmlhttprequest' && !empty($_SERVER['HTTP_REFERER'])) {
+   
// use the path the request was made from
+    $path = trim(parse_url($_SERVER['HTTP_REFERER'], PHP_URL_PATH), '/');
+  }
+
// re-apply core rules for admin theme
+  if (arg(0, $path) == 'admin' || (variable_get('node_admin_theme', '0') && arg(0, $path) == 'node' && (arg(1, $path) == 'add' || arg(2, $path) == 'edit'))) {
+   
$admin_theme = TRUE;
+  }
+
  
// check if some paths are disallow to get the theme
  
if (trim(variable_get('admin_theme_path_disallow', '')) != '') {
    
// pages that are defined by their normal path
-    $admin_theme_disallow = drupal_match_path($_GET['q'], variable_get('admin_theme_path_disallow', ''));
+   
$admin_theme_disallow = drupal_match_path($path, variable_get('admin_theme_path_disallow', ''));

    
// pages that are defined with their alias
-    $alias = drupal_get_path_alias($_GET['q']);
-    if (
$alias != $_GET['q']) {
+   
$alias = drupal_get_path_alias($path);
+    if (
$alias != $path) {
      
$admin_theme_disallow = $admin_theme || drupal_match_path($alias, variable_get('admin_theme_path_disallow', ''));
     }
   }

  
// we should not show the admin theme if the user has no access or the path is in the disallow list
  
if (!user_access('access admin theme') || $admin_theme_disallow) {
     unset(
$GLOBALS['custom_theme']);
     return;
   }

  
// check if an option is enabled and if it results to TRUE
  
$list = admin_theme_list();
   foreach (
$list as $info) {
    
$var = admin_theme_variable_name($info['module'], $info['option']);
     if ((bool)
variable_get($var, '0') && module_invoke($info['module'], 'admin_theme_options', 'check', $info['option'])) {
      
$admin_theme = TRUE;
     }
   }

  
// some custom defined pages should get admin theme
  
if (trim(variable_get('admin_theme_path', '')) != '') {
    
// pages that are defined by their normal path
-    $admin_theme = $admin_theme || drupal_match_path($_GET['q'], variable_get('admin_theme_path', ''));
+   
$admin_theme = $admin_theme || drupal_match_path($path, variable_get('admin_theme_path', ''));

    
// pages that are defined with their alias
-    $alias = drupal_get_path_alias($_GET['q']);
-    if (
$alias != $_GET['q']) {
+   
$alias = drupal_get_path_alias($path);
+    if (
$alias != $path) {
      
$admin_theme = $admin_theme || drupal_match_path($alias, variable_get('admin_theme_path', ''));
     }
   }

  
// Use the admin theme for the current request (if global admin theme setting is checked).
  
if ($admin_theme) {
     global
$custom_theme;
    
$custom_theme = variable_get('admin_theme', '0');
    
drupal_add_css(drupal_get_path('module', 'system') .'/admin.css', 'module');
   }
}
?>

#15

Version:6.x-1.x-dev» 7.x-1.0
Category:feature request» bug report
Priority:normal» major

This problem also occurs in D7. Still.
I'm marking this as major because the module causes other modules not to work properly.

For example, Field UI and Display Suite: It's impossible to drag and drob fields in the manage display area.

And of course, views with a large amount of rows are not able to have editable fields, because the whole layout is broken when ajax_load comes in the game.

Greetings

#16

Priority:major» normal
Status:needs work» needs review

seems this will be fixed in the upcoming D7 release, see http://drupal.org/node/967166

#17

Status:needs review» active

problem is still there with D7.14.