I am using CiviCRM 4.7.22 with Drupal 7 on Windows. I have a basic question. In the formRule() function inside the MembershipRenewal.php containing Membership Renewal Form if I use $this as below

$this->assign('endDate', CRM_Utils_Date::customFormat(CRM_Core_DAO::getFieldValue('CRM_Member_DAO_Membership', $this->_id, 'end_date')));

I get a PHP error:

PHP Fatal error: Using $this when not in object context in ...\MembershipRenewal.php on line xxx

Although this code works in preProcess() and buildQuickForm() without any issues. If its part of the same class then why the issue.

What is the alternative for me get the value of end_date or join_date in formRule() to perform some validition. In general, how do I get any value which is NOT part of a form in formRule().


If you take a look at the formRule() method, you will notice that it is static:

public static function formRule($params) {

When methods are invoked statically, you don't have access to $this. There is a similar construct to $this->, which is self:: (see http://php.net/manual/en/language.oop5.static.php) for more info, but I don't think it will help in your case as assign is expecting a form object to work with.

If you want to add validation to a form, you probably want to use the addRules() method. You can define a custom function (callback) that will accept the values submitted into the form and expects you to return an array of errors.

* If your form requires special validation, add one or more callbacks here
function addRules() {
  $this->addFormRule(array('CRM_Example_Form', 'myRules'));
* Here's our custom validation callback
static function myRules($values) {
  $errors = array();
  if ($values['foo'] != 'abc') {
    $errors['foo'] = ts('You entered the wrong text!');
  return empty($errors) ? TRUE : $errors;

see https://wiki.civicrm.org/confluence/display/CRMDOC/QuickForm+Reference for more details.

Another method I have used is

public function validate() {
  $this->setElementError(); // <-- more details here...
  return parent::validate();

See https://pear.php.net/manual/en/package.html.html-quickform.html-quickform.setelementerror.php for more info, though I think the above method is a little off piste.

Though having said that, the correct method really depends on why you are modifying the MembershipRenewal.php form.

If you are making a modification for your local site, you should really create an extension and use the https://docs.civicrm.org/dev/en/latest/hooks/hook_civicrm_validateForm/ hook.

If you are looking to make a more generic improvement and submit it to core, then the approach described above is the way to go, but you'll want to discuss your planned modifications with others before doing too much work somewhere like https://chat.civicrm.org/civicrm/channels/dev.

  • Thanks for your detailed reply. I am trying to work on a reported bug that is why looking at modifying the core. Just doing some homework before I can submit any request to resolve it. I checked most of the documentation you mentioned. Can't find the documentation on how to create complex rule using addRule, i.e. like comparing two dates. Will self:: work - I can then use a variable instead of assign(). – Amal Aug 3 '17 at 9:42
  • Can you, @ErikH or someone suggest a solution also - last part of my question. Right now I got it working using a hidden field. Is that the right approach? – Amal Aug 3 '17 at 9:52
  • @amal, i added some more detail on how you can/should use the addRules function. I'm not sure what you are using ->assign for, but if you are performing validation, then the typical approach is to use the $values and return an invalid message as part of the $errors array. If you want to reference the issue number, I might be able to give you a bit more help. – michaelmcandrew Aug 3 '17 at 11:29
  • The issue #CRM-20571 @michaelmcandrew [link]( issues.civicrm.org/jira/browse/CRM-20571). I understood how $values works but it doesn't contain the join_date. I am new to CiviCRM so still trying to understand how it all works. I have to compare join_date and renewal_date. I wasn't planning to use assign, just using it as an example to understand how to get values not available on the form. Thanks for your help. – Amal Aug 3 '17 at 15:09
  • hmm, i am guessing join_date is not in the form because this is a membership renewal? is the membership ID passed into values? If so, then one option would be to look up the join date in your validation callback. Else you could also overwrite the validate function (I added a stub above). Feel free to join chat.civicrm.org/civicrm/channels/dev and we can chat in real time if you like. – michaelmcandrew Aug 3 '17 at 15:40

First of all, I get the idea that you are actually modifying CiviCRM core code in your installation? If so, I would sincerely advise you NOT to do this but create an extension to customize what you need.

AFAIK formRule will be a static function, so will indeed not recognize your $this.

  • Trying to work on a bug @ErikH. – Amal Aug 3 '17 at 9:45
  • Good job @Amal! – ErikH - CiviCooP Aug 3 '17 at 10:41

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.