CiviCRM Community Forums (archive)

*

News:

Have a question about CiviCRM?
Get it answered quickly at the new
CiviCRM Stack Exchange Q+A site

This forum was archived on 25 November 2017. Learn more.
How to get involved.
What to do if you think you've found a bug.



  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion (Moderator: Donald Lobo) »
  • Error thrown during AJAX call causes ENTIRE Drupal page to be returned
Pages: [1] 2

Author Topic: Error thrown during AJAX call causes ENTIRE Drupal page to be returned  (Read 2960 times)

jakecivi

  • I post frequently
  • ***
  • Posts: 140
  • Karma: 0
Error thrown during AJAX call causes ENTIRE Drupal page to be returned
May 31, 2012, 02:34:20 pm
I'm writing a hook_civicrm_buildForm, and in the case of the CRM_Contribute_Form_Contribution form, I'm having problems because the hook seems to run multiple times per page view - once for the main page to load and once for a couple of AJAX calls that seem to happen after load.

I have written the hook to throw CRM_Core_Error::fatal sometimes, which it's doing in the AJAX calls because the the error throws when some URL args are missing.  It seems that throwing a fatal error causes the AJAX call to return the ENTIRE Drupal page with the error message instead of returning some smaller snippet to the ajax target element (see screenshot).

So 2 questions
1) How do I, and is it a good idea to, prevent the hook from running on the AJAX calls, or is there any other solution, and
     1.5) I probably don't want to actually prevent the hook from running, because then the ajax calls will be dealing with a different version of the form, so what do I do instead if my hook does things to $_SESSION that I don't want it to do twice, and
2) Is the returning of the entire page a CiviCRM bug?

xavier

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4453
  • Karma: 161
    • Tech To The People
  • CiviCRM version: yes probably
  • CMS version: drupal
Re: Error thrown during AJAX call causes ENTIRE Drupal page to be returned
May 31, 2012, 03:05:44 pm
Hi,

An easy way to test if it's an ajax call or not (what we use on the ajax api) is testing

Code: [Select]
        $_SERVER['HTTP_X_REQUESTED_WITH'] != "XMLHttpRequest"

I would avoid session as a rule, I'd rather test on params to distinguish if you need to run it or not. Not sure why the ajax is calling buildForm.

It would be great if you could investigate the error function not to return the full page if XMLHttpRequest indeed

X+
-Hackathon and data journalism about the European parliament 24-26 jan. Watch out the result

jakecivi

  • I post frequently
  • ***
  • Posts: 140
  • Karma: 0
Re: Error thrown during AJAX call causes ENTIRE Drupal page to be returned
May 31, 2012, 03:15:13 pm
I can't access any URL query string args from hook_civicrm_post , so I'm forced to pass them by saving them to session variables in hook_civicrm_buildForm .  Is there a better way to do this?

xavier

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4453
  • Karma: 161
    • Tech To The People
  • CiviCRM version: yes probably
  • CMS version: drupal
Re: Error thrown during AJAX call causes ENTIRE Drupal page to be returned
May 31, 2012, 04:06:20 pm
$_SERVER is a superglobal variable (that is always accessible from anywhere). what do you mean you can't access it?

Stop putting stuff in the session! ;)

X+
-Hackathon and data journalism about the European parliament 24-26 jan. Watch out the result

jakecivi

  • I post frequently
  • ***
  • Posts: 140
  • Karma: 0
Re: Error thrown during AJAX call causes ENTIRE Drupal page to be returned
May 31, 2012, 04:57:19 pm
Haha.  I mean that, from hook_civicrm_post, CRM_Utils_Request::retrieve returns null, as does directly accessing $_GET.

Ought I use $_SERVER instead, or are you saying that $_SERVER is the superglobal that contains $_GET?

xavier

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4453
  • Karma: 161
    • Tech To The People
  • CiviCRM version: yes probably
  • CMS version: drupal
Re: Error thrown during AJAX call causes ENTIRE Drupal page to be returned
May 31, 2012, 10:57:31 pm
Hi,

Yes, I meant that you use $_SERVER. I don't understand how $_GET can be empty.
Anyway, if $_SERVER isn't, that's what you need

X+
-Hackathon and data journalism about the European parliament 24-26 jan. Watch out the result

jakecivi

  • I post frequently
  • ***
  • Posts: 140
  • Karma: 0
Re: Error thrown during AJAX call causes ENTIRE Drupal page to be returned
June 01, 2012, 11:10:16 am
Maybe the post hook works from the form's "action" url, which is "/civitest/civicrm/contact/view/contribution" and has no query string, whereas the buildForm hook can see the query string.  In other words, the buildForm runs in a subse

Sorry, xavier, by "I meant that you use $_SERVER", are you telling me to store things there instead of session, or that I am already using it because $_GET is a part of it?

If I used $_SERVER, that would still be a way to pass variables from one hook to another through a globally accessible array, so I still ideally need to make a hash that I can assign to a particular instance of editing/saving the form so signals don't get crossed when someone has multiple windows open and is trying to edit multiple registrations at once.  Is that correct?


jakecivi

  • I post frequently
  • ***
  • Posts: 140
  • Karma: 0
Re: Error thrown during AJAX call causes ENTIRE Drupal page to be returned
June 01, 2012, 12:12:30 pm
About the error function, I've traced why it's outputting an entire Drupal page.  These are line numbers in Civi 4.1.

It looks like we're explicitly telling Drupal to theme an entire page and directly print the results.  We really have what we want in Error.php on line 304:
Code: [Select]
$content = $template->fetch( $config->fatalErrorTemplate );But then we go on to return an entire themed Drupal or other CMS page:

CRM/Core/Error.php, line 309:
Code: [Select]
echo CRM_Utils_System::theme( 'page', $content );
That calls either CRM/Utils/System/Base.php, line 37:
Code: [Select]
print theme('maintenance_page', array('content' => $content));
or CRM/Utils/System/Drupal6.php, line 70:
Code: [Select]
$out = theme( $type, $content, $args );where $type is that first argument passed in from Error.php, which in this case is 'page'.

It would be good if we could stop and return just the result of Error.php line 304 under certain circumstances like an AJAX call.  Ideally, it would be entirely different and that's all it would ever return under any circumstances, and it could be passed to CiviCRM's normal themeing mechanism.  It seems that calling CRM_Utils_System::theme is premature and bypasses a few important steps in producing output.

xavier

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4453
  • Karma: 161
    • Tech To The People
  • CiviCRM version: yes probably
  • CMS version: drupal
Re: Error thrown during AJAX call causes ENTIRE Drupal page to be returned
June 01, 2012, 03:28:10 pm

Quote from: jakecivi on June 01, 2012, 11:10:16 am
Maybe the post hook works from the form's "action" url, which is "/civitest/civicrm/contact/view/contribution" and has no query string, whereas the buildForm hook can see the query string.  In other words, the buildForm runs in a subse

Sorry, xavier, by "I meant that you use $_SERVER", are you telling me to store things there instead of session, or that I am already using it because $_GET is a part of it?

If I used $_SERVER, that would still be a way to pass variables from one hook to another through a globally accessible array, so I still ideally need to make a hash that I can assign to a particular instance of editing/saving the form so signals don't get crossed when someone has multiple windows open and is trying to edit multiple registrations at once.  Is that correct?

Why would you need to pass variables between hooks? if you need to check, from any hook, if you are called by ajax, just test $_SERVER['HTTP_X_REQUESTED_WITH'] != "XMLHttpRequest"

and that's it. I don't understand your need to pass variables between hooks.

X+
-Hackathon and data journalism about the European parliament 24-26 jan. Watch out the result

jakecivi

  • I post frequently
  • ***
  • Posts: 140
  • Karma: 0
Re: Error thrown during AJAX call causes ENTIRE Drupal page to be returned
June 04, 2012, 01:32:27 pm
I'm sorry, I'm asking two questions in this thread, and the AJAX error page issue has nothing to do with the passing of variables.

As for the variable passing problem, I think my problem is that the buildForm hook deals with the instance of Drupal that runs when the form is built, and then the related post hook that I'm writing actually deals with the next instance of Drupal, which runs when when the form is submitted.  The form's "action" is /civitest/civicrm/contact/view/contribution , which has no URL query string, so of course the post hook, which runs upon form submission, can't see any query string arguments.  That's why I was using $_SESSION - because I want to access values from the query string that was used to build the form the user is now submitting.

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Re: Error thrown during AJAX call causes ENTIRE Drupal page to be returned
June 04, 2012, 03:22:11 pm
Hi,

In 4.2 I did some work on errors so that the fatal function *should* throw an exception (which would be caught by the API) if the api had been initialised. At the moment the BAO throws fatal errors where I believe it should throw exceptions & leave the calling layer (form or api or whatever) to handle it.

It would be interesting to see if the changes I made have changed the behaviour you are reporting.
Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

jakecivi

  • I post frequently
  • ***
  • Posts: 140
  • Karma: 0
Re: Error thrown during AJAX call causes ENTIRE Drupal page to be returned
June 07, 2012, 01:27:31 pm
Yes.  Good to know.  Anyone have any idea on the variable passing problem above?

Quote
... I think my problem is that the buildForm hook deals with the instance of Drupal that runs when the form is built, and then the related post hook that I'm writing actually deals with the next instance of Drupal, which runs when when the form is submitted.  The form's "action" is /civitest/civicrm/contact/view/contribution , which has no URL query string, so of course the post hook, which runs upon form submission, can't see any query string arguments.  That's why I was using $_SESSION - because I want to access values from the query string that was used to build the form the user is now submitting.

How can I get a URL argument used by buildForm passed on to the subsequent page load (the one that handles form submission) so I can access the same argument in the post hook?

Eileen

  • Forum Godess / God
  • I’m (like) Lobo ;)
  • *****
  • Posts: 4195
  • Karma: 218
    • Fuzion
Re: Error thrown during AJAX call causes ENTIRE Drupal page to be returned
June 07, 2012, 02:15:25 pm
jakecivi - there are some hook handling fixes (maybe only for d6) in 4.1.3 so I would suggest you try that upgrade in case it helps
Make today the day you step up to support CiviCRM and all the amazing organisations that are using it to improve our world - http://civicrm.org/contribute

Donald Lobo

  • Administrator
  • I’m (like) Lobo ;)
  • *****
  • Posts: 15963
  • Karma: 470
    • CiviCRM site
  • CiviCRM version: 4.2+
  • CMS version: Drupal 7, Joomla 2.5+
  • MySQL version: 5.5.x
  • PHP version: 5.4.x
Re: Error thrown during AJAX call causes ENTIRE Drupal page to be returned
June 07, 2012, 02:37:04 pm

the post hook is called on all object creation and hence does not get a form/page handle. Its a very low level hook, IMO

the postProcess hook does get the form object, and u can store/retrieve GET params there and/or from the form object

lobo
A new CiviCRM Q&A resource needs YOUR help to get started. Visit our StackExchange proposed site, sign up and vote on 5 questions

jakecivi

  • I post frequently
  • ***
  • Posts: 140
  • Karma: 0
Re: Error thrown during AJAX call causes ENTIRE Drupal page to be returned
June 07, 2012, 03:56:04 pm
Alright, that makes sense then.  I need to do the business end of things in the post hook.  Perhaps then it would work to use the postProcess hook to declare and assign a global variable (global $pid = $_GET['pid'];), which then the post hook will have access to.  Does that sound right?

Pages: [1] 2
  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion (Moderator: Donald Lobo) »
  • Error thrown during AJAX call causes ENTIRE Drupal page to be returned

This forum was archived on 2017-11-26.