Wordpress Override a private function in a Class

I am working on a Wordpress site and the payment gateway.  I need to over ride a private function and I am not sure how to write it.  I need to replace:
private function add_auth_element
<?php
class WC_Intuit_QBMS_API_Request extends XMLWriter implements SV_WC_Payment_Gateway_API_Request {

private function add_auth_element( $application_login, $application_id, $connection_ticket ) {

		// root auth element <SignonMsgsRq>
		$this->startElement( 'SignonMsgsRq' );

		// <SignonDesktopRq>
		$this->startElement( 'SignonDesktopRq' );

		$this->writeElement( 'ClientDateTime',   gmdate( 'Y-m-d\TH:i:s' ) );
		$this->writeElement( 'ApplicationLogin', $application_login );
		$this->writeElement( 'ConnectionTicket', $connection_ticket );
		$this->writeElement( 'Language',         'English' );
		$this->writeElement( 'AppID',            $application_id );
		$this->writeElement( 'AppVer',           WC_Intuit_Payments::VERSION );

		// </SignonDesktopRq>
		$this->endElement();

		// </SignonMsgsRq>
		$this->endElement();

	}

}

Open in new window


In my themes functions.php file I have:
add_filter( 'add_auth_element', 'heal_add_auth_element', 11, 2 );
    function heal_add_auth_element() {

$application_login  = 123;
$connection_ticket = 123;
$application_id  = 123;
        
		// root auth element <SignonMsgsRq>
		$this->startElement( 'SignonMsgsRq' );

		// <SignonDesktopRq>
		$this->startElement( 'SignonDesktopRq' );

		$this->writeElement( 'ClientDateTime',   gmdate( 'Y-m-d\TH:i:s' ) );
		$this->writeElement( 'ApplicationLogin', $application_login );
		$this->writeElement( 'ConnectionTicket', $connection_ticket );
		$this->writeElement( 'Language',         'English' );
		$this->writeElement( 'AppID',            $application_id );
		$this->writeElement( 'AppVer',           WC_Intuit_Payments::VERSION );

		// </SignonDesktopRq>
		$this->endElement();

		// </SignonMsgsRq>
		$this->endElement();

	}

Open in new window


But this does not do anything.
LVL 7
rgranlundAsked:
Who is Participating?
 
Julian HansenCommented:
When you are overwriting functionality the extended class has to be used IN PLACE of the original. If you don't replace the original instantiation it will just end up using the parent class.

You can't extend the class and then have the old instantiation use the new class, so you can't use a filter to replace that class unless the plugin provides you with one.
0
 
Julian HansenCommented:
You can't override private methods - only public and protected methods.
0
 
rgranlundAuthor Commented:
So, I can change the method to protected correct?  Then how would I override it in the Wordpress Functions file?
0
Get expert help—faster!

Need expert help—fast? Use the Help Bell for personalized assistance getting answers to your important questions.

 
Julian HansenCommented:
It appears I was wrong.

Consider this code
class a {
  private function test() {
	echo "fred";
  }
}
class b extends a {
   public function test() {
      echo "frog";
   }
}

$c = new b();

$c->test();

Open in new window

Output is "frog"

So you can override.

Going to your code - second listing starting at line 7 - you are referring to $this - where does that come from?

You have added a filter that calls a function that uses $this - you need to instantiate an object - where are you doing that.
0
 
rgranlundAuthor Commented:
It starts out higher in the code:
<?php
class WC_Intuit_QBMS_API_Request extends XMLWriter implements SV_WC_Payment_Gateway_API_Request {

	/** QBMS SDK Version number */
	const QBMSXML_VERSION = 4.5;

	/** @var string the request xml */
	private $request_xml;

	/** @var string the application login value */
	private $application_login;

	/** @var string the application id value */
	private $application_id;

	/** @var string the connection ticket value */
	private $connection_ticket;

	/** @var WC_Order optional order object if this request was associated with an order */
	protected $order;


	/**
	 * Construct an Intuit QBMS request object
	 *
	 * @since 1.0
	 * @param string $application_login application login value
	 * @param string $application_id application id value
	 * @param string $connection_ticket connection ticket value
	 */
	public function __construct( $application_login, $application_id, $connection_ticket ) {

		$this->application_login = $application_login;
		$this->application_id    = $application_id;
		$this->connection_ticket = $connection_ticket;

	}

Open in new window


What I need to do is hook into the top code to ultimately create a "switch." This is for a shopping cart using Intuit as the payment gateway.  They have two different stores and each has a different "connection ticket."  So, depending upon what is ordered in the online store, it will "switch" the Connection Ticket. Line 14 at the top.
0
 
Julian HansenCommented:
Ok but you have a class and you are trying to override that with a WP function hook - that does not make sense.
0
 
rgranlundAuthor Commented:
I have the following in my functions.php file but it breaks the site:

class Heal_QBMS_Mod extends WC_Intuit_QBMS_API_Request {

    public function add_auth_element() {

        $this->init_document();

        $application_login = 123;
        $connection_ticket = 123;
        $application_id = 123;

        // root auth element <SignonMsgsRq>
        $this->startElement('SignonMsgsRq');

        // <SignonDesktopRq>
        $this->startElement('SignonDesktopRq');

        $this->writeElement('ClientDateTime', gmdate('Y-m-d\TH:i:s'));
        $this->writeElement('ApplicationLogin', $application_login);
        $this->writeElement('ConnectionTicket', $connection_ticket);
        $this->writeElement('Language', 'English');
        $this->writeElement('AppID', $application_id);
        $this->writeElement('AppVer', WC_Intuit_Payments::VERSION);

        // </SignonDesktopRq>
        $this->endElement();

        // </SignonMsgsRq>
        $this->endElement();
    }

}

$run_Heal_QBMS_Mod = new Heal_QBMS_Mod();
$run_Heal_QBMS_Mod->add_auth_element();

Open in new window

0
 
Julian HansenCommented:
It will break the site - that code (it appears) is running in the functions.php file directly - not inside a function - that means that code will run as soon as functions.php is loaded - which is not what you want.

Maybe you want this bit inside a function hook?

$run_Heal_QBMS_Mod = new Heal_QBMS_Mod();
$run_Heal_QBMS_Mod->add_auth_element();

Open in new window


You are overriding a class - where is the original class being used?
0
 
rgranlundAuthor Commented:
I actually heard from the Intuit Payment Plugin Developer. They told me that the only way I can modify/override the Class is to edit the core file.  I really don't want to do this for all of the obvious reasons.  I'm going to put this on the back burner.  As we continue to discuss how to handle this, the question is becoming more clear in my mind.
There is a class that is part of a plugin.  I need to override the call to that file with an "If" statement.  If var A = "Foo" then use File A.  If var A ="Bar" then use file B.

I can place this logic directly into the template that has the Class but it would be better if I knew how to do it outside of the core plugin files.  Intuit won't help because they did not build the plugin.  The plugin developer is hard to reach.  So I'm looking for direction.
0
 
Julian HansenCommented:
The only way to do this is to find where the class is used and change the instantiation of that class from the original to your new class

Somewhere you have this
$somevar = new WC_Intuit_QBMS_API_Request(); // ASSUMING WC_Intuit_QBMS_API_Request Is the original class

Open in new window


What you want to do is create a new class
class YourClassNameHere extends WC_Intuit_QBMS_API_Request
{
   private function add_auth_element( $application_login, $application_id, $connection_ticket ) {
     // your code here - remember that you are overriding if replacing then all functionality for
     // this function must be replaced if extending then  call
     // parent::add_auth_element(...) before or after your code depending on requirement
   }
}

Open in new window


Then where the instantiation takes place you change the code to

$somevar = new YourClassNameHere();

Open in new window


If the above only happens in the plugin files then you don't have any option but to do it there.
0
 
rgranlundAuthor Commented:
What about the classes that the Class extends? class WC_Intuit_QBMS_API_Request extends XMLWriter implements SV_WC_Payment_Gateway_API_Request {

And assuming that where the class is instantiated within the plugin code, I will still need to add a filter to that function?

I'm trying not to confuse myself.
0
Question has a verified solution.

Are you are experiencing a similar issue? Get a personalized answer when you ask a related question.

Have a better answer? Share it in a comment.

All Courses

From novice to tech pro — start learning today.