Tax Plugins

This article assumes you have a clear understanding of PHP, PHP Classes, and arrays, as well as a good working knowledge of CartThrob.

CartThrob has a tax plugin interface, and several helper functions that simplify the creation of tax plugins. Refer to one of the included tax plugins as an example. The "Cartthrob_tax_default.php" plugin uses most of the functionality available to your tax plugins, so it's a good starter example of what's possible.

Overview

Tax plugins are PHP Classes that contain at a minimum a $title, a get_tax, tax_shipping, tax_rate, and a tax_name function.

All tax plugins are stored in the following location: cartthrob > cartthrob > plugins > tax. You can look there for additional tax plugins to use as a reference.

IMPORTANT

  1. Your plugin classname should match your plugin file name.

  2. Your plugin filename/classname needs to begin with Cartthrob_tax or it will not be recognized as a tax plugin.

  3. By default, sessions data is automatically available for all tax plugins you create, so you do not have to, and should not start a session for your plugin, or plugin functions.

  4. You need to create a language file for each tax plugin (see more about language files). Each language file should be named the same name as your tax plugin, plus _lang at the end, and in all lower case (example: cartthrob_tax_my_tax_plugin_lang.php)

Table of Contents

Plugin Information

These fields, located at the top of the plugin allow you to set some general information about your plugin. Title is required. The rest are optional.

    public $title = 'Global Tax';
    public $note = 'This tax applies to everything';
Language Files

You should probably create a language file for your plugin if you intend to have any settings available to select from. The naming convention for the language file is as follows:

cartthrob_tax_YOUR_PLUGIN_NAME_lang.php

Review existing language files for an example of the proper formatting. Create language key/value pairs as needed, for example.

my_title => 'Global Tax 2', 

You would access this like so:

public $title   = 'my_title';

CartThrob will look for the my_title key in the language file, and replace it with the relevant value. If it's not found, then my_title will be used instead.

Plugin Settings

Each plugin has the ability to store and manage its own settings. Each setting is an array that requires at a minimum array keys for name, type, and short_name of the setting. You can also add a default, options, note, settings (to generate a matrix settings).

name

required key

Name is the settings name that the customer will see. Use plain text, or a reference to a language file key.

type

required key

This is the type of setting. The following settings types are recognized:

  1. text
  2. textarea
  3. radio (see options)
  4. select (see options)
  5. checkbox (see options) (if not checked, will not return ANY value.)
  6. matrix (see settings)
  7. header

The type will determine whether data stored in this setting is string data or an array. text, textarea and header are the only string types. The rest are arrays

short_name

required key

The short_name is what will be used by your plugin to access the content of this setting (see plugin_settings function below). Short_names should only include "alpha-dash" characters. Alphabet + numeric + underscore and hyphen.

default

optional key

This is default data that should populate the setting. Default data can not be used to preset matrixes. Each individual matrix field can contain a default, but an entire row can't be set using one default.

options

(usually) optional key

Required if you are using a non-text type. Options is an array containing the selectable options in a radio or select dropdown. The option key is accessible using the plugin_settings function. The value is descriptive for the client only, and is not accessible, except by using the key in conjunction with a call to the language file.

'options' => array(
    'option' => 'Descriptive Name',
    'option2' => 'Other Descriptive Name',
),
note

optional key

Optional & purely descriptive. Generally the "name" key should be fairly short, but the "note" key can contain one or more paragraphs as needed to describe the setting in detail to the user.

Settings key

If you are using a matrix type, then you'll need to add a settings key that will contain additional keys for each matrix field. CartThrob tax plugins do not allow the use of a matrix within a matrix.

Example
public $settings = array(
    array(
        'name' => 'use_tax_table',
        'note' => 'use_tax_table_note',
        'short_name' => 'use_tax_table',
        'type' =>'radio',
        'default' => 'no',
        'options' => array(
            "yes"   => 'yes',
            'no'    => 'no'
        ),
    ),
    array(
        'name' => 'tax_by_location_settings',
        'short_name' => 'tax_settings',
        'type' => 'matrix',
        'settings' => array(
            array(
                'name' => 'name',
                'short_name' => 'name',
                'type' =>'text',    
            ),
            array(
                'name' => 'tax_percent',
                'short_name' => 'rate',
                'type' => 'text'
            ),
            array(
                'name' => 'state_country',
                'short_name' => 'state',
                'type' => 'select',
                'attributes' => array(
                    'class' => 'states_and_countries',
                ),
                'options' => array(),
            ),
            array(
                'name' => 'zip_region',
                'short_name' => 'zip',
                'type' => 'text',
            ),
            array(
                'name' => 'tax_shipping',
                'short_name' => 'tax_shipping',
                'type' => 'checkbox',
            ),
        )
    )
);

Using the "settings" array, you can create multiple setting fields that will display in the plugin's settings when it is selected.

Required Functions

get_tax

The get_tax function is a required function.

parameters: price (optional) return: float (the tax cost)

public function get_tax()
{
    return 10; 
}
tax_name

This plugin returns the name of the tax

parameters: none return: string (the name of the tax)

tax_shipping

Whether shipping should be taxed or not

parameters: none return: boolean

tax_rate

Return the current rate items are being taxed at.

parameters: none return: float

Optional Functions

initialize

Only needed if you want to set a plugin wide variable in one central location.

parameters: If not passing any, PHP 7 requires empty arrays at a minimum return: void

protected $default_rate = 0;

public function initialize($params = array(), $defaults = array())
{
     if ($this->plugin_settings('default_rate') )
    {
        $this->default_rate = $this->plugin_settings('default_rate'); 
    }
}
tax_data

Helps get data for one or more thresholds

parameters: key return: array|string

public function tax_data($key = FALSE)
{
    if (is_null($this->tax_data))
    {
        $this->tax_data = array();

        $prefix = ($this->core->store->config('tax_use_shipping_address')) ? 'shipping_' : '';

        $locations = array(); 

        $tax_settings = $this->plugin_settings('tax_settings'); 

        if ($this->core->cart->customer_info($prefix.'zip') )
        {
            $locations['zip'] = $this->core->cart->customer_info($prefix.'zip'); 
        }

        if (is_array($tax_settings))
        {
            foreach ($tax_settings as $tax_data)
            {   
                if ($this->core->cart->customer_info($prefix.'zip') && $tax_data['zip'] == $this->core->cart->customer_info($prefix.'zip'))
                {
                    $this->tax_data = $tax_data;
                    break;
                }
            }
        }
    }
    if ($key === FALSE)
    {
        return $this->tax_data;
    }

    return (isset($this->tax_data[$key])) ? $this->tax_data[$key] : FALSE;
}

Core Cart Functions

Any of CartThrob's methods can be used by a shipping plugin, the following is a short list of the most useful core cart functions available for shipping purposes.

  1. taxable_subtotal
  2. customer_info
  3. plugin_settings
  4. cart_items
  5. get_tax_rates
  6. round
  7. sanitize_number

ExpressionEngine functions can also be called if it is instantiated.

$this->EE =& get_instance(); 
taxable_subtotal

This returns the total of items that are taxable in the cart

(float) $this->core->cart->taxable_subtotal(); 
customer_info

This returns an array of all of the customer information.

(array) $this->core->cart->customer_info(); 

You can also call specific customer info:

$this->core->cart->customer_info("first_name"); 
plugin_settings

Outputs the contents of a particular setting, called by the setting's "short_name"

(mixed) $this->plugin_settings('YOUR_KEY'); 

example:

if ($this->plugin_settings('test_mode') == 'test')
{
    $sample_price = 10; 
}
get_tax_rates

If tax rates are set in the database, rather than in the settings, you access the tax data with this function

$prefix = "";

$locations['zip'] = $this->core->cart->customer_info($prefix.'zip'); 
$locations['special'] = $this->core->cart->customer_info($prefix.'region'); 
$locations['state'] = $this->core->cart->customer_info($prefix.'state'); 
$locations['country'] = $this->core->cart->customer_info($prefix.'country_code');

$locations_array = $this->core->get_tax_rates($locations); 
cart_items

Outputs the contents of all items in the cart.

(object) $this->core->cart->items(); 

You can also access object methods for each item in the cart:

foreach ($this->core->cart->items() as $key => $item)
{
    echo $item->quantity(); 
    echo $item->price();
    echo $item->weight(); 
}
round

Rounds a number to a standard monetary float value (ex. 10.10)

(float) $this->core->round("11.203"); // would equal 11.20
sanitize_number

Cleans a number so that it's a float value. This helps remove incompatible formatting like $ signs or commas.

$this->core->sanitize_number($this->plugin_settings('default_tax')
Examples

The following is a very simple example. Check cartthrob > cartthrob > plugins > taxes for additional tax plugins to use as a reference.

<?php if ( ! defined('CARTTHROB_PATH')) Cartthrob_core::core_error('No direct script access allowed');

class Cartthrob_tax_standard extends Cartthrob_tax
{
    public $title = 'tax_standard';
    public $settings = array(
        array(
            'name' => 'default_tax',
            'note' => 'default_tax_note',
            'short_name' => 'default_tax',
            'type' =>'text',
            'default' => '8',
        )
    );

    protected $tax_data;

    public function get_tax($price)
    {
        return $this->core->round($price * $this->tax_rate());
    }

    public function tax_name()
    {
        return "Standard Taxes";
    }

    public function tax_rate()
    {
        return $this->core->sanitize_number(10)/100;
    }

    public function tax_shipping()
    {
        return TRUE; 
    }
}