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) »
  • My membership extension works, but then silently fails.
Pages: [1]

Author Topic: My membership extension works, but then silently fails.  (Read 712 times)

konadave

  • I’m new here
  • *
  • Posts: 19
  • Karma: 0
  • CiviCRM version: 4.2.6
  • CMS version: Drupal 7.17
  • MySQL version: 5.1.66
  • PHP version: 5.3.19
My membership extension works, but then silently fails.
October 31, 2013, 09:30:44 am
I have developed an extension that adds a couple of custom data fields to the add/renew membership screens. For one particular test contact when adding a new membership, all the various records are created, but then it silently fails and all the records go hasta la bye-bye. Below is some logging proving the records are created. I've also included the complete code for the hooks the extension implements.

Adding a new membership to the same contact with the extension disabled works.

Does anybody have a clue as to what might be causing this to fail? So far, it's only happened to this one contact, but it's enough that the client hasn't accepted it.

This is CiviCRM 4.2.6

Thanks for taking the time to look at this.

Dave

[09:41:56] buildForm CRM_Member_Form_Membership
[09:41:58] buildForm CRM_Member_Form_Membership
[09:42:03] buildForm CRM_Member_Form_Membership
[09:42:39] buildForm CRM_Member_Form_Membership
[09:42:39] validateForm CRM_Member_Form_Membership
[09:42:39] pre create Membership (?)
[09:42:39] post create Membership (126815)
[09:42:39] pre create Contribution (?)
[09:42:39] post create Contribution (305384)
[09:42:39] custom create group 11, entity 305384
[09:42:39] custom create group 11, entity 305384
[09:42:41] pre create Activity (?)
[09:42:41] post create Activity (656396)
[09:42:41] pre create LineItem (305384)
[09:42:41] post create LineItem (305384)
[09:42:41] pre create MembershipPayment (?)
[09:42:41] post create MembershipPayment (260522)
[09:42:42] pre create Activity (?)
[09:42:42] post create Activity (656397)
[09:42:43] buildForm CRM_Activity_Form_ActivityLinks

The extension implements the civicrm_buildForm, civicrm_validateForm, and civicrm_post hooks. Here is the code...


/*/*
 * buildForm - inject region, chapter, and premium fields
 */
function cambr_civicrm_buildForm($formName, &$form) {

	
if ((
$formName == 'CRM_Member_Form_Membership') || ($formName == 'CRM_Member_Form_MembershipRenewal')) {
	
	
$api = new civicrm_api3();
      
$renderer = CRM_Core_Form_Renderer::singleton();

      
$defaults = array();
	
	

	
	
ob_start();

	
	
/**********
	
	
 * REGION *
	
	
 **********/
	
	
$api->CustomField->Get(array('id' => 76));
	
	
if (!
$api->result->is_error) {
	
	
	
$region = $api->result->values[0];

	
	
	
$api->OptionGroup->GetValue(array('id' => $region->option_group_id, 'return' => 'name'));
	
	
	

	
	
	
if (!
$api->result->is_error) {
	
	
	
	
$options = CRM_Core_OptionGroup::values($api->result);
	
	
	
	
asort($options);
	
	
	
	
$select = $form->add('select', 'custom_76', ts($region->label), array('' => '- select -') + $options);

	
	
	
	
if (
$region->is_required && ((count($_POST) == 0) || (isset($_POST['record_contribution']) && ($_POST['record_contribution'] == '1'))))
	
	
	
	
	
$form->addRule('custom_76', ts("{$region->label} is a required field."), 'required');
	
	
	
	

	
	
	
	
$el = $renderer->_elementToArray($select, false, '');
	
	

	
	
	
	
echo 
'<textarea id="custom_76_tr"><tr><td></td><td><hr /></td></tr><tr><td class="label">',$el['label'],
	
	
	
	
	
(
$region->is_required ? ' <span class="crm-marker" title="This field is required.">*</span>' : ''),
	
	
	
	
	
'</td><td>', $el['html'], '</td></tr></textarea>';
	
	
	
}
	
	
}

	
	
/***********
	
	
 * CHAPTER *
	
	
 ***********/
	
	
$api->CustomField->Get(array('id' => 77));
	
	
if (!
$api->result->is_error) {
	
	
	
$chapter = $api->result->values[0];

	
	
	
$api->OptionGroup->GetValue(array('id' => $chapter->option_group_id, 'return' => 'name'));
	
	
	

	
	
	
if (!
$api->result->is_error) {
	
	
	
	
$options = CRM_Core_OptionGroup::values($api->result);
	
	
	
	
asort($options);
	
	
	
	
$select = $form->add('select', 'custom_77', ts($chapter->label), array('' => '- select -') + $options);
	
	

	
	
	
	
if (
$chapter->is_required && ((count($_POST) == 0) || (isset($_POST['record_contribution']) && ($_POST['record_contribution'] == '1'))))
	
	
	
	
	
$form->addRule('custom_77', ts("{$chapter->label} is a required field."), 'required');

	
	
	
	
$el = $renderer->_elementToArray($select, false, '');
	
	

	
	
	
	
echo 
'<textarea id="custom_77_tr"><tr><td class="label">',$el['label'],
	
	
	
	
	
(
$chapter->is_required ? ' <span class="crm-marker" title="This field is required.">*</span>' : ''),
	
	
	
	
	
'</td><td>', $el['html'], '</td></tr></textarea>';
	
	
	
}
	
	
}

	
	
/***********
	
	
 * PREMIUM *
	
	
 ***********/
	
	
$select = $form->add('select', 'premium', ts('Premium'));
	
	
$select->addOption('- select -', '');
	
	
$premium_options = array();
	
	

	
	
$dao = CRM_Core_DAO::executeQuery("SELECT id,name,options FROM civicrm_product WHERE is_active=1 ORDER BY name ASC");
	
	
while (
$dao->fetch()) {
	
	
	
$select->addOption($dao->name, $dao->id);
	
	
	
if (
$dao->options) {
	
	
	
	
$opt = $form->add('select', "premium_{$dao->id}");
	
	
	
	
$options = explode(',', $dao->options);
	
	
	
	
foreach(
$options as $option) {
	
	
	
	
	
if (
$option = trim($option))
	
	
	
	
	
	
$opt->addOption($option, $option);
	
	
	
	
}
	
	
	
	
$premium_options[] = $opt;
	
	
	
}
	
	
}

	
	
$el = $renderer->_elementToArray($select, false, '');
	
	

	
	
echo 
'<textarea id="premiums_tr"><tr><td class="label">', $el['label'], '</td><td>', $el['html'];

	
	
foreach(
$premium_options as $prem) {
	
	
	
$el = $renderer->_elementToArray($prem, false, '');
	
	
	
echo 
$el['html'];
	
	
}
	
	
	

	
	
echo 
'</td></tr><tr><td></td><td><hr /></td></tr></textarea>';
	
	

	
	
echo 
'
	
	
	
<script type="text/javascript">
	
	
	
	
var s, cr, cc, prem;
	
	
	
	
cr = cj("#'
, 'custom_76_tr");
	
	
	
	
cc = cj("#'
, 'custom_77_tr");
	
	
	
	
prem = cj("#premiums_tr");

	
	
	
	
if (cj("#recordContribution").length == 1) {
	
	
	
	
	
s = "#recordContribution table:first tr:last";
	
	
	
	
	
cj(cr[0].value).insertAfter(cj(s));
	
	
	
	
	
cj(cc[0].value).insertAfter(cj(s));
	
	
	
	
	
cj(prem[0].value).insertAfter(cj(s));
	
	
	
	
}
	
	
	
	
else {
	
	
	
	
	
s = ".crm-membership-form-block-total_amount";
	
	
	
	
	
cj(prem[0].value).insertAfter(cj(s));
	
	
	
	
	
cj(cc[0].value).insertAfter(cj(s));
	
	
	
	
	
cj(cr[0].value).insertAfter(cj(s));
	
	
	
	
}
	
	
	
	

	
	
	
	
cr.remove();
	
	
	
	
cc.remove();
	
	
	
	
prem.remove();

	
	
	
	
cj("select[name^=\'premium_\']").css("display", "none");
	
	
	
	

	
	
	
	
cj("#premium").change(
	
	
	
	
	
function(evt) {
	
	
	
	
	
	
cj("select[name^=\'premium_\']").css("display", "none");
	
	
	
	
	
	
cj("#premium_" + evt.target.value).css("display", "inline");
	
	
	
	
	
}
	
	
	
	
);
	
	
	
</script>
	
	
'
;

	
	
CRM_Core_Region::instance('page-body')->add(array('markup' => ob_get_clean()));
	
}
}

/*
 * validateForm - capture submitted values
 */
function rcp_civicrm_validateForm($formName, &$fields, &$files, &$form, &$errors) {

	
if ((
$formName == 'CRM_Member_Form_Membership') || ($formName == 'CRM_Member_Form_MembershipRenewal')) {
	
	
$po = 'premium_' . $fields['premium'];

	
	
$GLOBALS["value_custom_76"] = $fields['custom_76'];
	
	
$GLOBALS["value_custom_77"] = $fields['custom_77'];
	
	
$GLOBALS['value_premium'] = $fields['premium'];
	
	
$GLOBALS['value_premium_option'] = isset($fields[$po]) ? $fields[$po] : null;
	
}
	
return 
true;
}

/*
 * post - assign values to contribution
 */
function rcp_civicrm_post($op, $objectName, $objectId, &$objectRef) {

	
if ((
$op == 'create') && ($objectName == 'Contribution')) {
	
	
if (isset(
$GLOBALS["value_custom_76"])) {
	
	
	
$api = new civicrm_api3();
	
	
	

	
	
	
if (
$GLOBALS["value_custom_76"])
	
	
	
	
$api->CustomValue->Create(array('entity_id' => $objectId, 'custom_76' => $GLOBALS["value_custom_76"]));

	
	
	
if (
$GLOBALS["value_custom_77"])
	
	
	
	
$api->CustomValue->Create(array('entity_id' => $objectId, 'custom_77' => $GLOBALS["value_custom_77"]));

	
	
	
if (
$id = $GLOBALS['value_premium']) {
	
	
	
	
$query = "INSERT INTO civicrm_contribution_product
	
	
	
	
	
	
	
(product_id, contribution_id, product_option, quantity)
	
	
	
	
	
	
	
VALUES (
$id, $objectId, '{$GLOBALS['value_premium_option']}', 1)";
	
	
	
	
CRM_Core_DAO::executeQuery($query);
	
	
	
}
	
	
}
	
	

	
}
}

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: My membership extension works, but then silently fails.
October 31, 2013, 04:23:50 pm

without looking at the code, most likely a fatal error is being thrown and the transaction is being rolled back, and hence the records disappear.

your next step would be to figure out where and why the error is being thrown

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

konadave

  • I’m new here
  • *
  • Posts: 19
  • Karma: 0
  • CiviCRM version: 4.2.6
  • CMS version: Drupal 7.17
  • MySQL version: 5.1.66
  • PHP version: 5.3.19
Re: My membership extension works, but then silently fails.
October 31, 2013, 06:28:33 pm
I understand that something is causing the transaction to be rolled back, but I don't know where to begin looking. That's why I came to the experts. I did forget to mention that debug is on. No messages of any kind are displayed when this happens. As I mentioned, the extension implements only three hooks. Perhaps if we walk through the sequence you'll understand why I'm at such a loss.

The hook is called when initially displaying the form...

[09:42:03] buildForm CRM_Member_Form_Membership   <-- fields added to the form

It's called again when the form is submitted...

[09:42:39] buildForm CRM_Member_Form_Membership   <-- fields added to the form
[09:42:39] validateForm CRM_Member_Form_Membership   <-- values captured

Then records start to be created...

[09:42:39] pre create Membership (?)
[09:42:39] post create Membership (126815)   <-- called, but ignored
[09:42:39] pre create Contribution (?)

It implements civicrm_post, but it ignores everything but the creation of a contribution, where it creates the custom data fields...

[09:42:39] post create Contribution (305384)
[09:42:39] custom create group 11, entity 305384   <-- capture values used to create custom data
[09:42:39] custom create group 11, entity 305384   <-- capture values used to create custom data

Then more records are created...

[09:42:41] pre create Activity (?)
[09:42:41] post create Activity (656396)   <-- called, but ignored
[09:42:41] pre create LineItem (305384)
[09:42:41] post create LineItem (305384)   <-- called, but ignored
[09:42:41] pre create MembershipPayment (?)
[09:42:41] post create MembershipPayment (260522)   <-- called, but ignored
[09:42:42] pre create Activity (?)
[09:42:42] post create Activity (656397)   <-- called, but ignored

The last time the extension is called is for a form it doesn't handle. It ignores it...

[09:42:43] buildForm CRM_Activity_Form_ActivityLinks

The last time the extension does anything is during the creation of the contribution record, which pre-dates other records being created. I don't understand why this is failing. If the extension is disabled, adding the membership works. Adding the membership to any other contact when the extension is enabled also works.

The only code I didn't include in my initial post is the boilerplate generated by civix.

I'm not expecting to be handed the answer, unless of course you have it. But can anybody possibly point me in the right direction?

Thanks again.

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: My membership extension works, but then silently fails.
November 01, 2013, 08:26:53 am

1. any error message in your ConfigAndLog directory being logged?

2. Enable mysql query logging and see the queries being generated. The last queries before the rollback might give you an idea as to what is failing (and potentially why)

3. You can also add a debug and backtrace statement here: CRM/Core/Transaction.php, function rollback

to see who is calling the rollback

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

konadave

  • I’m new here
  • *
  • Posts: 19
  • Karma: 0
  • CiviCRM version: 4.2.6
  • CMS version: Drupal 7.17
  • MySQL version: 5.1.66
  • PHP version: 5.3.19
Re: My membership extension works, but then silently fails.
November 01, 2013, 01:06:59 pm
Thank you for the pointers. I will give them a try as soon as I get a chance.

Pages: [1]
  • CiviCRM Community Forums (archive) »
  • Old sections (read-only, deprecated) »
  • Developer Discussion (Moderator: Donald Lobo) »
  • My membership extension works, but then silently fails.

This forum was archived on 2017-11-26.