2

I am working on a plugin for 'hooking' an extra payment provider into a checkout system.

I have a class gtpCheckoutData in my function.php which calculates the prices.

In my plugin I want to use data from this gtpCheckoutData class, but if I do that I get a:

Fatal error: Class gtpCheckoutData not found in

My plugin code:

class gtpMollieGateway {
   private $mollie, $price;

   function __construct() {
       $this->mollie    = new Mollie_API_Client;

       // THIS IS THE PROBLEM
       $this->price     = new gtpCheckoutData;

       add_action( 'init', array( $this, 'gtpCreatePayment' ) );
   }

   function gtpCreatePayment() {
       if( isset( $_POST['checkout_submit'] ) ) {
           $payment     = $this->mollie->payments->create(array(
                'amount'        => $this->price->getPrice( 'inclusive' ),

           ));
           header( "Location: " . $payment->getPaymentUrl() );
       }
   }
}

My gtpCheckoutData class in functions.php

class gtpCheckoutData {
    private $tax, $price;

    public function __construct() {
        $this->tax      = get_gtp_option( 'gtp_tax' ) / 100;
        $this->price    = $_SESSION['shopping_cart']['total_price'] + $_SESSION['shopping_cart']['shipping_price'];
        $this->shipping = $_SESSION['shopping_cart']['shipping_price'];
    }

    public function getPrice( $type ) {

        if( isset( $type ) ) {
            switch( $type ) {
                case 'exclusive' : 
                    $totalPrice = $this->price;
                    break;
                case 'tax' :
                    $totalPrice = $this->price * $this->tax;
                    break;  
                case 'inclusive' :
                    $totalPrice = $this->price * ( $this->tax + 1 );
                    break;
            }
            return $totalPrice;
        }
    }
}

2 Answers 2

1

Plugins are loaded before functions.php. You should include the class in your plugin if possible.

I have had scenarios where a class was part of the theme, but also needed in a plugin where you couldn't assume the class was included in the theme. In those cases, I simply included the class in both places and wrapped it in a "class exists" check.

Like this:

if(!class_exists('My_Class'))
{
 class My_Class{

    // Class Methods and Properties
 }
}

You could also include the class only once in MU Plugins, which is loaded before the other plugins.

1
  • No problem. As Kaiser said in his answer, having to maintain two separate files of the same class is not ideal. However, if you're using the class in other places in the theme, you can't assume that the plugin is present and activated.
    – SkyShab
    Commented Nov 19, 2014 at 17:03
4

Plugins load before themes. The earliest hooks available to plugins is plugins_loaded (or muplugins_loaded for mu-plugins), while themes run on after_setup_theme and later hooks. So you better just load the file [that contains the class] on a specific hook in your plugin. It probably is best to load it on a lower priority than the default 10. Below I use 5 to make it available to callbacks running on the default priority. This is more error safe for your users as they might not add a priority and therefore the callback runs on 10 and the error will be thrown (again).

add_action( 'after_setup_theme', function()
{
    require plugin_dir_path( __FILE__ ).'src/your-class.php`;
}, 5 );

Then, in your themes functions.php file you can just rely on the class. It also avoids duplicating your code (and maintaining it in two places) and does not need unnecessary class_exists checks which just reduce performance. Also it's predictable where your class is available and ready to use.

Keep in mind that the current FIG PSR-4 standard does not allow more than one class per file (and nothing else there). Going with this makes your setup more future proof as your code is namespace-ready. (Current PHP version is 5.6 and 5.3 is at the end of life).

2
  • Thanks for your great answer! The only problem I get then is that get_gtp_option() a function is created in functions.php. So then I get an error again.
    – Robbert
    Commented Nov 19, 2014 at 16:44
  • @Robbert Please update your question with more details, then ping me here so I can understand your problem completely.
    – kaiser
    Commented Nov 19, 2014 at 16:50

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

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