I am using a custom theme for iFrames which loads up fine... except when a form is submitted (such as search) and then the 'app' remains in the iFrame (it's not breaking out completely to the site) but the site default theme is used from then on. The themes are extremely similar but the iFrame theme is optimized for the width of an iFrame.

I have examined #555038: Theme won't stick in iFrame applications which as first blush looks like the same issue, but my problem is the theme changing only on form submits, not any subsequent page loads. I found that issue by way of this issue: #749718: fb_canvas_is_iframe and fb_is_iframe_canvas don't return TRUE consistently.

I was working with FBML pages and the app broke out of FB entirely and had made progress as told trough this issue: #711654: form submit path/action not right?, but unfortunately we are using Ubercart and a lot of Javascript which doesn't mix too well with FBML, and it looks like FBML is, shall we say, passe. So I'm working with iFrames.

On the first page and any subsequent non-form page I get a nice FB Dev Block:
Facebook Devel Info
Page Status = Rendering iframe.
fb_facebook_user = 1151032822
users_isAppUser = 1
users_isAppUser(1151032822) = 1
local user = flix
fb_get_fbu = 1151032822
base_url = http://flixfling.com/drupal_dev
base_path = /drupal_dev/
url() returns = /drupal_dev/
$_REQUEST[q] is = user/1/mymovies
arg(0) is = user
arg(1) is = 1
session_id = fb_canvas_4a0c4ab2e3b96aed2fd9aacb326cbcd5
session_name = SESScanvas4a0c4ab2e3b96aed2fd9aacb326cbcd5

Another example:
Page Status = Rendering iframe.
fb_facebook_user = 1151032822
users_isAppUser = 1
users_isAppUser(1151032822) = 1
local user = flix
fb_get_fbu = 1151032822
base_url = http://flixfling.com/drupal_dev
base_path = /drupal_dev/
url() returns = /drupal_dev/
$_REQUEST[q] is = node/51
arg(0) is = node
arg(1) is = 51
session_id = fb_canvas_4a0c4ab2e3b96aed2fd9aacb326cbcd5
session_name = SESScanvas4a0c4ab2e3b96aed2fd9aacb326cbcd5

Once I submit a form I get the wrong theme and the Dev block looks like this:
Page Status = Connected via Facebook Connect
fb_facebook_user =
fb_api_check_session() = Returned FALSE
local user = flix
fb_get_fbu = 1151032822
base_url = http://flixfling.com/drupal_dev
base_path = /drupal_dev/
url() returns = /drupal_dev/
$_REQUEST[q] is = search/node/pennance
arg(0) is = search
arg(1) is = node
session_id = bd5f888c0e3105da6dd8d0b5bb5b660d
session_name = SESSconnecte4b269e2c3c142f8658f57a5ce09cf26

I am thinking it's the 'fb_api_check_session() = Returned FALSE' that revealing the problem, but I dunno.

The form is going through the fb_canvas_form_alter() function on the form submission, and the part of the the function at line 407 or so is doing what it's supposed to do:

  elseif (fb_canvas_is_iframe()) {
    // Include the fb_sig so that when post is received, we know we are still in a canvas.
    watchdog('fb_canvas', 'Form before function: !data', array('!data' => '<pre>'. check_plain(print_r($form, TRUE)) .'</pre>')); 
    foreach ($_REQUEST as $key => $value) {
      if (strpos($key, 'fb_sig') === 0) {
        $form['fb_canvas_iframe'][$key] = array(
          '#type' => 'hidden',
          '#value' => $value,
        );
      }
    }
    watchdog('fb_canvas', 'Form after function: !data', array('!data' => '<pre>'. check_plain(print_r($form, TRUE)) .'</pre>'));
  }

I added in the watchdog functions to make sure that this section is running and doing what it's supposed to do, which it is. So the $form['fb_canvas_iframe'] array is being filled out, which is supposed to get the page back into the iFrame, but somehow the $fb_app->fb_app_data['fb_canvas']['theme_iframe'] value (fb_flix in our case) which is listed in the Dev block isn't getting recognized on the form submit.

I'm unsure of where I should look next to troubleshoot.

Comments

ironsizide’s picture

Let me follow up first by saying that I have read the README file and followed it to the letter. I tried ripping out DFF 2-rc2 and upgrading to 3-dev which led to it's own problems so I went back to 2-rc2.

I have modified the code in includes/theme.inc to include the code suggested in #187868: Facebook not using fbml theme, comment #11 which led to these observations:
The main page in FB shows the following Locations/Referrer pattern:
Location - http://flixfling.com/drupal_dev/?fb_sig_in_iframe=1&fb_sig_iframe_key=0a8005f5594bd67041f88c6196192646&fb_sig_locale=en_US&fb_sig_in_new_facebook=1&fb_sig_time=1276093265.2018&fb_sig_added=1&fb_sig_profile_update_time=1274971926&fb_sig_expires=1276099200&fb_sig_user=100001144279508&fb_sig_session_key=2.LUla0LSemn0WISnLEEvxAA__.3600.1276099200-100001144279508&fb_sig_ss=gYb0NNI2QTFuLUSiUkAfow__&fb_sig_cookie_sig=e0ead4f64f9dd3327c1d60f48cd23102&fb_sig_ext_perms=auto_publish_recent_activity&fb_sig_country=us&fb_sig_api_key=093ae4c6af0fbc23e84d56838a82155d&fb_sig_app_id=112721765427901&fb_sig=e2f613b45dabfe47222e825db54866b8
Referrer - http://apps.facebook.com/flixfling/

Clicking on any non-form link shows the same pattern:
Location - http://flixfling.com/drupal_dev/node/215?fb_sig_in_iframe=1&fb_sig_iframe_key=0a8005f5594bd67041f88c6196192646&fb_sig_locale=en_US&fb_sig_in_new_facebook=1&fb_sig_time=1276093270.8711&fb_sig_added=1&fb_sig_profile_update_time=1274971926&fb_sig_expires=1276099200&fb_sig_user=100001144279508&fb_sig_session_key=2.LUla0LSemn0WISnLEEvxAA__.3600.1276099200-100001144279508&fb_sig_ss=gYb0NNI2QTFuLUSiUkAfow__&fb_sig_cookie_sig=e0ead4f64f9dd3327c1d60f48cd23102&fb_sig_ext_perms=auto_publish_recent_activity&fb_sig_country=us&fb_sig_api_key=093ae4c6af0fbc23e84d56838a82155d&fb_sig_app_id=112721765427901&fb_sig=89c4cd5c8e47a4487ea3e2e4fe5d0d4c
Referrer - http://apps.facebook.com/flixfling/node/215

However submitting a form (in this case the search form) the Location and Referrer look like this:
Location - http://flixfling.com/drupal_dev/search/node/drugs
Referrer - http://flixfling.com/drupal_dev/?fb_sig_in_iframe=1&fb_sig_iframe_key=0a8005f5594bd67041f88c6196192646&fb_sig_locale=en_US&fb_sig_in_new_facebook=1&fb_sig_time=1276092832.9162&fb_sig_added=1&fb_sig_profile_update_time=1274971926&fb_sig_expires=1276099200&fb_sig_user=100001144279508&fb_sig_session_key=2.LUla0LSemn0WISnLEEvxAA__.3600.1276099200-100001144279508&fb_sig_ss=gYb0NNI2QTFuLUSiUkAfow__&fb_sig_cookie_sig=e0ead4f64f9dd3327c1d60f48cd23102&fb_sig_ext_perms=auto_publish_recent_activity&fb_sig_country=us&fb_sig_api_key=093ae4c6af0fbc23e84d56838a82155d&fb_sig_app_id=112721765427901&fb_sig=93dfc5d7c96adb448912db7e0d427104

I'm guessing the Location not having the fb_sig... info is what is breaking the page out of the iFrame-designated theme and reverting to the default theme. The back traces don't seem to be showing any other theming function being called before init_theme - is the back trace listed in the same order as the function calls or reverse order? The back trace is showing inti_theme being called at the top of the list:

	init_theme backtrace

array(12) {
  [0]=>
  array(4) {
    ["file"]=>
    string(52) "/home/flix/public_html/drupal_dev/includes/theme.inc"
    ["line"]=>
    int(615)
    ["function"]=>
    string(10) "init_theme"
    ["args"]=>
    array(0) {
    }
  }

And to be complete the search submit shows the following themes chosen: 'init_theme has chosen flix, custom_theme is '. Other pages show: 'init_theme has chosen fb_flix, custom_theme is fb_flix'

Delving deeper and hoping this helps someone else....

Dave Cohen’s picture

ironsizide,

What you're describing could be the cause, but shouldn't be. There is code in fb_canvas_form_alter to add all those parameters to the form post.

More likely, the form's submit handler is doing a drupal_goto or somehow redirecting the form. At that point, the extra info that tells Drupal for Facebook this is a canvas frame is lost.

ironsizide’s picture

Dave,
Looks like it's definitely a problem with the submit handlers. I gave the code ccshannon posted in #711654: form submit path/action not right? a shot, modifying it work over the search form:

function dff_custom_form_alter(&$form, $form_state, $form_id) {
  if(fb_canvas_is_iframe()) {
     if ($form_id == 'views_exposed_form') {
      // I don't want the exposed_view forms to redirect, but I may want to do something custom to the form(s) here
    } else {
      // By making the form's action target=_top, the form results leave the frame and load a new URL in the locator
      // But this will create the problem of 'relative URL' actions, and your resulting window will be of your Drupal site URL outside of FB chrome, in the site default theme
      // We will correct this later
  
      $form['#attributes'] = array('target' => '_top');
    }
  
  // Dave's suggestion below fixes the issue with exposed form results messing up the theme
  // So, THAT problem IS a theme problem
  
    if (fb_canvas_is_iframe()) {
      // Include the fb_sig so that when post is received, we know we are still in a canvas.                      
      foreach ($_REQUEST as $key => $value) {
        if (strpos($key, 'fb_sig') === 0) {
          $form['fb_canvas_iframe'][$key] = array(
            '#type' => 'hidden',
            '#value' => $value,
          );                                                                                                      
        }                                                                                                         
      }                                                                                                           
    }    
  
  // Now we setup how the results properly redirect
  // Also keep in mind that the links to your forms may contain a destination query string, and that other modules may redirect your forms for you
  // I suggest really getting to know your forms, their IDs and their submit handlers by checking the #submit array in $form
  
  // I picked this up from another Drupal discussion, and this works well for me.
  // With most other forms, you can just attach a submit handler to $form[#submit][] = 'my_handler_function', but to get the Node ID ...
    if (isset($form['search_block_form']) ) {
      if (fb_canvas_is_iframe()) {
        $form['#submit'][] = 'dff_custom_search_redirect_handler';
        if (isset( $_GET['destination'])) {
          $dest = $_GET['destination'];
          $fbpath = _dff_custom_my_fb_app_path();
          $pos = strpos($dest, $fbpath);
          if ($pos === FALSE) {
            $dest = $fbpath . '/' . $dest;
          }
          $form['custom_dest'] = array(
            '#type' => 'value',
            '#value' => $dest,
          );
        }
      }
    }

  }
}

function _dff_custom_my_fb_app_path() {
  $domain = 'http://apps.facebook.com/';
  $myapplabel = 'myapplabel';
  $path = $domain . $myapplabel;
  return $path;
}

function dff_custom_search_redirect_handler($form, &$form_state) {
    if (isset($form['custom_dest'])) {
      $form_state['redirect'] = $form['custom_dest']['#value'];
    } else {
      // This handler was added because we are in an iframe. So I just call for my fb path again
      $fbpath = _dff_custom_my_fb_app_path();
      $form_state['redirect'] = $fbpath . '/search/node/' . $form['#parameters'][1]['post']['search_block_form'];
    }
}

And lo and behold, it works! The search results are returned in the iFrame AND my FB iFrame theme is retained. Of course now I have a new problem: the search result links are not FB-ized, they send the user to the site. This happens on the drupalforfacebook.org site as well:
- Go to http://apps.facebook.com/drupalforfacebook/node/2000
- Search for somehting on the small search form (not the one up top).
- Results are returned in the canvas page.
- Click on any link and you go to the drupalforfacebook.org site instead of staying in the canvas page.

That's damned annoying, but a whole other issue if it could be considered that. I think it's outside of the scope of DFF and requires a custom function to work with the links the search.module returns. All I know is my boss wants the app to work in FB and never leave.

Dave Cohen’s picture

I don't like this bit of code...

     if ($form_id == 'views_exposed_form') {
      // I don't want the exposed_view forms to redirect, but I may want to do something custom to the form(s) here
    } else {
      // By making the form's action target=_top, the form results leave the frame and load a new URL in the locator
      // But this will create the problem of 'relative URL' actions, and your resulting window will be of your Drupal site URL outside of FB chrome, in the site default theme
      // We will correct this later
  
      $form['#attributes'] = array('target' => '_top');
    }

.. specifically the target=_top part because it means the form submit will go to facebook, not your server. This means file uploads would not work and facebook gets to see all the data posted by the user. So in my opinion, there's another better way to solve the problem.

What I still don't get is why I don't need this code on apps.facebook.com/drupalforfacebook. What is different about your setup?

Thanks for pointing out the links presented by search results. I consider this another problem. (Probably a bug in fb_canvas_process(). I think that is the function adding target=_top to those links, but failing to make the links start with apps.facebook.com/....)

ironsizide’s picture

I tried taking commenting out the code above (target=top) and I started getting the FB chrome AND iFrame withing FB chrome jazz. Interesting.

I am wondering why you don't have the same problems too! I can provide a list of modules we have installed (there are quite a few) - I imagine DFF.org has more modest needs for additional modules. Even so, aside from Ubercart and the road to madness therein lies I can't think of too many other modules that are very form intensive that we need access to on the app.

Sounds about right on the search links. Anything I can do to help with that let me know.

srinikasturi’s picture

Facing same problem. Also trying to use Ubercart. But faced the problem even before installing Ubercart - with basic node submit form.

srinikasturi’s picture

Example available at http://second7.peppervillage.net. Add to cart and see this break on the app: apps.facebook.com/srinikas. To look under the hood, please feel free to log in to the site with username: admin and password: admin.

Thanks
Srini

srinikasturi’s picture

upgraded to 3.x and everything's perfect. thanks!