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

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

CommentFileSizeAuthor
#5 admin_theme-464738-5.patch1.39 KBmarkus_petrux
Support from Acquia helps fund testing for Drupal Acquia logo

Comments

markus_petrux’s picture

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. :)

markus_petrux’s picture

Project: Ajax Load » Administration theme
Version: 6.x-1.2 » 6.x-1.x-dev
Category: bug » feature
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.

     }
   }
  
+  // 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) {
     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.

markus_petrux’s picture

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. :)

chriscohen’s picture

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

markus_petrux’s picture

FileSize
1.39 KB

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

loze’s picture

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

markus_petrux’s picture

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

loze’s picture

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.

markus_petrux’s picture

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.

loze’s picture

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.

markus_petrux’s picture

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.

loze’s picture

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?

loze’s picture

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

  // 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.

yosh’s picture

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.

 /**
  * 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');
   }
 }
mxh’s picture

Version: 6.x-1.x-dev » 7.x-1.0
Category: feature » bug
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

mxh’s picture

Priority: Major » Normal
Status: Needs work » Needs review

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

mxh’s picture

Status: Needs review » Active

problem is still there with D7.14.

Andrew Answer’s picture

.