Problem/Motivation
Currently, it's impossible to pull query suggestions from different collections/front-ends. Only the one collection/frontend combo selected in the Drupal Google Appliance configuration screen. There could be many reasons to use different collections/frontends for different query suggestion sets. The reason initially proposed was different languages provided by different collections/frontends to return suggestions in the right language.
Proposed resolution
Implement a alter/hook to provide google_appliance_suggest_callback.php with a different site/frontend. If none are provided, we can still default to what's currently being used.
User interface changes
There should be no user interface changes required.
API changes
We may be need to add a hook_google_appliance_suggest_query_alter().
Original report by wavepoint
Hi there,
I've found that when using this module with i18n it isn't able to pass the appropriate language via users session. The primary reason for this I thought, was because the bootstrap process was set to variables, which doesn't include language information. After some changes to bootstrap full, I've found that when passing the language variable, it's only passed as the sites default. I believe this is cause due to initiating a second bootstrap, which creates a secondary user session due to the way the google_appliance_suggest_callback.php is coded.
Instead of having the JavaScript form callback go directly to the google_appliance_suggest_callback.php page, I'm looking at creating a menu router, and sending it through the main module instead. This way google_appliance_suggest_callback.php won't need it's own bootstrap process, which is un-necessary.
A secondary option could be to make the language part of the request call to the callback.php page, however I don't like the idea of exposing this URL to a PHP page directly.
Overall the module works great, but doesn't play nice with Internationalization (i18n) so I'll see what I can do to contribute.
Thanks,
Steve
| Comment | File | Size | Author |
|---|---|---|---|
| #9 | google_appliance_suggest-allow_site_collection_alteration-1799936-9.patch | 5.11 KB | iamEAP |
| #2 | google_appliance_suggest-fixing_i18n-1799936-1.patch | 10.46 KB | cdnsteve |
Comments
Comment #1
iamEAP commentedThe reason it goes through the secondary bootstrap process is performance. Going the usual menu router route would mean that Drupal would be fully bootstrapped (almost) every keystroke when someone searches. I'd prefer to keep to improve the secondary boostrap process over adding a menu router option, but we'll see how things progress.
Is GSA capable of returning query suggestions specific to a language anyway? If so, do you know how? I'd be interested in this functionality.
Comment #2
cdnsteve commentedHere's the code which enables i18n support, through the Admin interface, it also disables the last part of the JavaScript due to errors in IE 7.
It also provides input filtering on the $_GET request before sending it to the GSA for security reasons.
Thanks,
Steve
Comment #3
iamEAP commentedThanks for the patch, @cdnsteve.
Could we open separate issues for the following from your patch?
Regarding the i18n support, it appears your patch appends the language to the collection/frontend. While that may suit your particular use-case, I don't believe this naming convention for frontends/collection is necessarily common practice. In other words, it's not specifically multilingual support (although it could be), it's actually just the ability to dynamically alter the frontend/collection. Maybe a drupal_alter/hook would be better suited, so you could perform that modification in your own module?
Comment #4
cdnsteve commentedIt's my first Drupal patch attempt so my apologies if it's not following the normal conventions!
I'll separate those two issues into new items and submit patches.
You're correct it's specific to my particular configuration. I never considered a drupal_alter or hook, I'll look into doing that. Thanks :)
Comment #5
iamEAP commented@cdnsteve Didn't know it was your first patch attempt. Very cool! A couple of other notes: your patch above also included some packaging details that Drupal adds automatically. Not 100% sure how that got in there, but you might find this page useful for creating patches for this particular module.
Back to the main issue: after digging into GSA documentation, I can't find any specific multilingual support for query suggestions (no extra variables to pass, for instance). As hinted at by patches/suggestions previously, the best we can do is to allow other modules to dynamically alter the frontend/collection before making the suggestion query to the GSA.
I think a
hook_google_appliance_suggest_query_alterjust before the query is sent and ahook_google_appliance_suggest_results_alterbefore the results are displayed should be more than adequate. I'd still really prefer to keep this in the alternate bootstrap rather than adding a menu callback, but I'm not sure how well alters/hooks will play in the alternate bootstrap process.Comment #5.0
iamEAP commentedUpdating issue using d.o issue template.
Comment #6
iamEAP commentedAnd actually, after digging into the code a bit, I think the best we can do in terms of altering the site/client is to append them to the file name in the autocomplete path, and change the callback to expect it in the form of:
/path/to/google_appliance_suggest_callback.php/site/client/tokenIf we're going to introduce that kind of a pattern, though, we could get away with passing everything we're forced to get via variable_get() in the callback, and using a lower bootstrap level in the callback. Something like...
/path/to/google_appliance_suggest_callback.php/cache/hostname/timeout/max/site/client/tokenAllowing us to avoid loading all modules in DRUPAL_BOOTSTRAP_VARIABLES, and potentially avoiding database initialization completely if the user opts not to cache the suggestions.
A hook/alter interface for editing those variables is still desirable, though.
Comment #7
cdnsteve commentedI should back up an explain where my issue is coming from a bit more.
I think the issue in my case is because of the way the google_appliance module operates. It only allows for one collection and frontend to be specified, in my case, for a multilingual site is a problem. As a work around for this, I've already used their hook_gsa_google_appliance_query_alter and sent in my current language to be appended to the frontend and collection name.
What is actually stored in the interface and DB for collection and frontend is only half of what's needed.
EG:
Collection;
mysite
The GSA's actual collection is mysite_en and mysite_fr.
I hook on and alter the collection to be mysite_lang, similar to what I've changed in this patch.
GSA Suggest doesn't seem to have a language parameter we can pass as you said. However, the suggest data that is returned from the GSA depends on the current Frontend defined in the module. Therefore, if you have two different language Frontends, with respective collections (multilingual site), the terms become intermixed and create bad results. It becomes important to separate these search suggestions or the data in the GSA will not be what you expect.
As a side note, I did find something in their documentation that might be useful, if you go to your GSA URL http://yourgsa/ss.js they have a pre-made JavaScript file for use. I haven't looked to deeply into this yet.
In my case of using the external bootstrap with this file, no language is passed from the current users session from i18n, so it doesn't work.
I agree that the hook_alter would work well, so everyone can customize based on their needs, similar to what I did with the google_appliance hook but this will still need leverage the menu hook.
// allow implementation of hook_google_appliance_query_alter() by other modules
drupal_alter('google_appliance_query', $search_query_data);
Comment #8
iamEAP commentedI actually tried building a version of this module when my organization's site was on Drupal 6 using the JavaScript files provided by the Appliance (the ss.js you mentioned). It was very messy and required some server reconfiguration. Check this sandbox project for details.
I may have a patch for this later today. If there isn't one here by then, others are more than welcome to chime in.
Comment #9
iamEAP commentedHere's a patch that adds the ability to alter all aspects of the query, including: hostname, collection, frontend, timeout, whether or not to cache the result, and the maximum number of results to return. For example:
Part of me thinks this isn't the best idea, but another part of me loves that we're adding additional functionality and making it more performant.
Some very rough benchmarking. Average time it takes to deliver query suggestion results:
Comment #10
cdnsteve commentedCurious, what are you using to do the benchmarking?
I'd like to see how fast the menu router option is.
Comment #11
cdnsteve commentedI've tried doing the following benchmark using the menu router method.
in the callback.inc
Start of the file:
function google_appliance_suggest_callback() {
$time = microtime(true);
Then when outputting
drupal_json_output($response);
$micro = $time - floor($time); // microseconds part
print $micro * 100;
Then gone directly to the URL producting the GSA query and watched the output and refreshed a few times.
57.0334911346
40.3610944748
53.8459062576
24.0187883377
It's pretty snappy, not sure if there's a better way to test this.
Comment #12
iamEAP commentedBack from holiday. Sorry for the delay!
All I did was look at the network pane of webkit's developer tools and averaged 10 visits per scenario. That being said, specific results from this will vary wildly between sites. My baseline was a very high 0.15 seconds because it was on a site with over 100 modules installed. What's important is the difference between the baseline and what's being proposed. Mine shows a ~2x gain because it ends up not having to reload all 100 of those modules into memory on the server every time a user adds a keystroke to their search query.
In an ideal world, we'd make a direct call via AJAX to the GSA unit but can't due to JavaScript's same origin policy, hence the workaround. The closer we can get to the ideal in terms of speed, the better.
What I'm less certain of is the security implications of passing all of the query parameters via the URL.
Comment #13
cdnsteve commentedI was thinking about the direct call via AJAX as well, it sounds good in theory but it doesn't work in my specific corporate environment.
The reason being is that the GSA is not directly externally available, so JavaScript doesn't work.
I haven't had time to submit my other issues but in regards to the security addition about passing query params, whether using GET or POST, I added filtering to the request first. I'd suggest adding a filter_xss or check_url to the request before sending it off to the GSA.
Comment #13.0
cdnsteve commentedFixing malformed HTML.