/**
  * Toggle whether renewal discounts should be enabled globally.
  *
  * @param bool $enable
  */
 protected function _toggle_global_renewal_discount($enable)
 {
     $options = it_exchange_get_option('addon_itelic', true, true);
     $options['enable-renewal-discounts'] = $enable;
     it_exchange_save_option('addon_itelic', $options);
     it_exchange_get_option('addon_itelic', true, true);
 }
Ejemplo n.º 2
0
 /**
  * Get information about the licensing add-on.
  */
 public function info()
 {
     $settings = it_exchange_get_option('addon_itelic');
     if ($settings['renewal-discount-type'] == 'percent') {
         $discount = $settings['renewal-discount-amount'] . '%';
     } else {
         $discount = it_exchange_format_price($settings['renewal-discount-amount']);
     }
     $info = array('version' => ITELIC\Plugin::VERSION, 'online_software_enabled' => $settings['sell-online-software'] ? 'yes' : 'no', 'remote_activation_enabled' => $settings['enable-remote-activation'] ? 'yes' : 'no', 'remote_deactivation_enabled' => $settings['enable-remote-deactivation'] ? 'yes' : 'no', 'renewal_discounts_enabled' => $settings['enable-renewal-discounts'] ? 'yes' : 'no', 'renewal_discount' => $discount, 'renewal_discount_expiry' => sprintf("%d days", $settings['renewal-discount-expiry']));
     $args = array('fields' => array_keys($info));
     $formatter = new \WP_CLI\Formatter($args);
     $formatter->display_item($info);
 }
Ejemplo n.º 3
0
 /**
  * Check if the discount is disabled for this product.
  *
  * @since 1.0
  *
  * @return bool
  */
 public function is_disabled()
 {
     $options = it_exchange_get_option('addon_itelic');
     if (!empty($this->feature_data['override'])) {
         return false;
     }
     if (!empty($this->feature_data['disable'])) {
         return true;
     }
     if (!$options['enable-renewal-discounts']) {
         return true;
     }
     return false;
 }
Ejemplo n.º 4
0
 /**
  * Do custom initialization.
  */
 public function setUp()
 {
     parent::setUp();
     it_exchange_temporarily_load_addon('guest-checkout');
     it_exchange_temporarily_load_addon('digital-downloads-product-type');
     it_exchange_add_feature_support_to_product_type('recurring-payments', 'digital-downloads-product-type');
     $null = null;
     $this->exchange_admin = new IT_Exchange_Admin($null);
     it_exchange_save_option('settings_general', $this->exchange_admin->set_general_settings_defaults(array()));
     it_exchange_get_option('settings_general', true);
     $this->product_factory = new ITELIC_UnitTest_Factory_For_Products();
     $this->key_factory = new ITELIC_UnitTest_Factory_For_Keys($this->factory);
     $this->activation_factory = new ITELIC_UnitTest_Factory_For_Activations($this->factory);
     $this->release_factory = new ITELIC_UnitTest_Factory_For_Releases($this->factory);
     $this->update_factory = new ITELIC_UnitTest_Factory_For_Updates($this->factory);
     WP_Mock::setUp();
 }
 /**
  * Get the chart for this report.
  *
  * @since 1.0
  *
  * @param string $date_type
  * @param int    $product
  *
  * @return Base
  */
 public function get_chart($date_type = 'this_year', $product = 0)
 {
     $start = date('Y-m-d H:i:s', $this->convert_date($date_type));
     $end = date('Y-m-d H:i:s', $this->convert_date($date_type, true));
     $grouping = self::get_grouping_for_date_type($date_type);
     $sql = self::get_group_by($grouping, 'r.renewal_date');
     $group = $sql['group'];
     $per = $sql['per'];
     if ($per) {
         $per .= ' AS d, ';
     }
     if ($group) {
         $group = "GROUP BY {$group}";
     }
     /**
      * @var \wpdb $wpdb
      */
     global $wpdb;
     $rtn = Manager::get('itelic-renewals')->get_table_name($wpdb);
     $ktn = Manager::get('itelic-keys')->get_table_name($wpdb);
     if ($product) {
         $raw = "SELECT {$per}SUM(revenue) as c FROM {$rtn} r JOIN {$ktn} k ON(k.lkey = r.lkey AND k.product = %d) WHERE r.renewal_date BETWEEN %s AND %s";
         $raw .= $group;
         $revenue = $wpdb->get_results($wpdb->prepare($raw, $product, $start, $end));
     } else {
         $raw = "SELECT {$per}SUM(revenue) as c FROM {$rtn} r  WHERE r.renewal_date BETWEEN %s AND %s";
         $raw .= $group;
         $revenue = $wpdb->get_results($wpdb->prepare($raw, $start, $end));
     }
     $revenue = self::fill_gaps(self::translate_results($revenue), $start, $end, $grouping);
     $labels = self::get_labels($revenue, $date_type);
     $before = $after = '';
     $settings = it_exchange_get_option('settings_general');
     $currency = html_entity_decode(it_exchange_get_currency_symbol($settings['default-currency']));
     if ('after' === $settings['currency-symbol-position']) {
         $after = $currency;
     } else {
         $before = $currency;
     }
     $chart = new Line($labels, 600, 200, array('responsive' => true, 'tooltipTemplate' => "{$before}<%= value %>{$after}"));
     $chart->add_data_set(array_values($revenue), __("Revenue", Plugin::SLUG), array('fillColor' => "rgba(140,197,62,0.2)", 'strokeColor' => "rgba(140,197,62,1)", 'pointColor' => "rgba(140,197,62,1)", 'pointStrokeColor' => "#fff", 'pointHighlightFill' => "#fff", 'pointHighlightStroke' => "rgba(140,197,62,1)"));
     return $chart;
 }
Ejemplo n.º 6
0
/**
 * Create a license key.
 *
 * @api
 *
 * @param array $args        {
 *
 * @type string $key         The license key to be used. If empty, one will be
 *       generated.
 * @type int    $transaction Transaction ID. If empty, one will be manually
 *       generated
 * @type int    $product     Product ID.
 * @type int    $customer    Customer ID.
 * @type string $status      The key's status. Accepts 'active', 'expired',
 *       'disabled'
 * @type float  $paid        If manually generating a transaction, the amount
 *       paid.
 * @type int    $limit       Activation limit.
 * @type string $expires     Expiration date. Pass null or empty string for
 *       forever.
 * @type string $date        When the transaction occurred. GMT.
 * }
 *
 * @return \ITELIC\Key|WP_Error
 */
function itelic_create_key($args)
{
    $defaults = array('key' => '', 'transaction' => '', 'product' => '', 'customer' => '', 'status' => '', 'paid' => '');
    $args = ITUtility::merge_defaults($args, $defaults);
    $product = itelic_get_product($args['product']);
    if (!$product->has_feature('licensing')) {
        return new WP_Error('invalid_product', __("Product does not have licensing enabled.", \ITELIC\Plugin::SLUG));
    }
    $customer = it_exchange_get_customer($args['customer']);
    if (!$customer) {
        return new WP_Error('invalid_customer', __("Invalid customer", \ITELIC\Plugin::SLUG));
    }
    $transaction = it_exchange_get_transaction($args['transaction']);
    if (!$args['transaction']) {
        if (!function_exists('it_exchange_manual_purchases_addon_transaction_uniqid')) {
            return new WP_Error('no_manual_purchases', __("Manual purchases add-on is not installed.", \ITELIC\Plugin::SLUG));
        }
        // Grab default currency
        $settings = it_exchange_get_option('settings_general');
        $currency = $settings['default-currency'];
        $description = array();
        $product_id = $product->ID;
        $itemized_data = apply_filters('it_exchange_add_itemized_data_to_cart_product', array(), $product_id);
        if (!is_serialized($itemized_data)) {
            $itemized_data = maybe_serialize($itemized_data);
        }
        $key = $product_id . '-' . md5($itemized_data);
        $products[$key]['product_base_price'] = $product->get_feature('base-price');
        $products[$key]['product_subtotal'] = $products[$key]['product_base_price'];
        //need to add count
        $products[$key]['product_name'] = get_the_title($product_id);
        $products[$key]['product_id'] = $product_id;
        $products[$key]['count'] = 1;
        $description[] = $products[$key]['product_name'];
        $description = apply_filters('it_exchange_get_cart_description', join(', ', $description), $description);
        // Package it up and send it to the transaction method add-on
        $total = empty($args['paid']) ? 0 : it_exchange_convert_to_database_number($args['paid']);
        $object = new stdClass();
        $object->total = number_format(it_exchange_convert_from_database_number($total), 2, '.', '');
        $object->currency = $currency;
        $object->description = $description;
        $object->products = $products;
        remove_action('it_exchange_add_transaction_success', 'ITELIC\\on_add_transaction_generate_license_keys');
        $uniquid = it_exchange_manual_purchases_addon_transaction_uniqid();
        $txn_args = array();
        if (isset($args['date'])) {
            $date = \ITELIC\make_date_time($args['date']);
            $txn_args['post_date'] = \ITELIC\convert_gmt_to_local($date)->format('Y-m-d H:i:s');
            $txn_args['post_date_gmt'] = $date->format('Y-m-d H:i:s');
        }
        $tid = it_exchange_add_transaction('manual-purchases', $uniquid, 'Completed', $customer->id, $object, $txn_args);
        add_action('it_exchange_add_transaction_success', 'ITELIC\\on_add_transaction_generate_license_keys');
        $transaction = it_exchange_get_transaction($tid);
    }
    $factory = new \ITELIC\Key\Factory($product, $customer, $transaction);
    $key = \ITELIC\generate_key_for_transaction_product($transaction, $product, $factory, $args['status'], $args['key']);
    if (isset($args['limit'])) {
        if (empty($args['limit']) || $args['limit'] == '-') {
            $limit = '';
        } else {
            $limit = $args['limit'];
        }
        $key->set_max($limit);
    }
    if (isset($args['expires'])) {
        if (is_string($args['expires'])) {
            $expires = \ITELIC\make_date_time($args['expires']);
        } else {
            $expires = $args['expires'];
        }
        if (!$expires instanceof DateTime) {
            $expires = null;
        }
        $key->set_expires($expires);
    }
    return $key;
}
Ejemplo n.º 7
0
 /**
  * Return the product's features
  *
  * @since 1.0
  *
  * @param mixed   $existing   the values passed in by the WP Filter API.
  *                            Ignored here.
  * @param integer $product_id the WordPress post ID
  * @param array   $options
  *
  * @return string product feature
  */
 public function get_feature($existing, $product_id, $options = array())
 {
     $settings = it_exchange_get_option('addon_itelic');
     $defaults = array('enabled' => false, 'online-software' => $settings['sell-online-software'], 'limit' => '', 'key-type' => '', 'update-file' => '', 'version' => '', 'enabled_variant_activations' => false, 'activation_variant' => array());
     $values = get_post_meta($product_id, '_it_exchange_itelic_feature', true);
     $raw_meta = \ITUtility::merge_defaults($values, $defaults);
     if (!function_exists('it_exchange_variants_addon_create_inital_presets')) {
         $raw_meta['enabled_variant_activations'] = false;
     }
     if (!isset($options['field'])) {
         // if we aren't looking for a particular field
         return $raw_meta;
     }
     if ($options['field'] == 'limit' && isset($options['for_hash'])) {
         $hash = $options['for_hash'];
         if (isset($raw_meta['activation_variant'][$hash])) {
             return $raw_meta['activation_variant'][$hash];
         } else {
             $atts = it_exchange_get_variant_combo_attributes_from_hash($product_id, $hash);
             $alt_hashes = it_exchange_addon_get_selected_variant_alts($atts['combo'], $product_id);
             foreach ($alt_hashes as $alt_hash) {
                 if (isset($raw_meta['activation_variant'][$alt_hash])) {
                     return $raw_meta['activation_variant'][$alt_hash];
                 }
             }
             return null;
         }
     }
     $field = $options['field'];
     if (isset($raw_meta[$field])) {
         // if the field exists with that name just return it
         return $raw_meta[$field];
     } else {
         if (strpos($field, ".") !== false) {
             // if the field name was passed using array dot notation
             $pieces = explode('.', $field);
             $context = $raw_meta;
             foreach ($pieces as $piece) {
                 if (!is_array($context) || !array_key_exists($piece, $context)) {
                     // error occurred
                     return null;
                 }
                 $context =& $context[$piece];
             }
             return $context;
         } else {
             return null;
             // we didn't find the data specified
         }
     }
 }
Ejemplo n.º 8
0
/**
 * Create a renewal transaction key.
 *
 * @api
 *
 * @param array $args {
 *
 * @type string $key  The license key to be used. If empty, one will be
 *       generated.
 * @type float  $paid If manually generating a transaction, the amount paid.
 * @tpye string $date When the transaction occurred. GMT.
 * }
 *
 * @return IT_Exchange_Transaction
 */
function itelic_create_renewal_transaction($args)
{
    $defaults = array('key' => '', 'paid' => '', 'date' => '');
    $args = ITUtility::merge_defaults($args, $defaults);
    $key = itelic_get_key($args['key']);
    if (!$key) {
        return new WP_Error('invalid_key', __("Invalid key", \ITELIC\Plugin::SLUG));
    }
    $product = $key->get_product();
    if (!function_exists('it_exchange_manual_purchases_addon_transaction_uniqid')) {
        return new WP_Error('no_manual_purchases', __("Manual purchases add-on is not installed.", \ITELIC\Plugin::SLUG));
    }
    // Grab default currency
    $settings = it_exchange_get_option('settings_general');
    $currency = $settings['default-currency'];
    $description = array();
    $product_id = $product->ID;
    $itemized_data = apply_filters('it_exchange_add_itemized_data_to_cart_product', array(), $product_id);
    if (!is_serialized($itemized_data)) {
        $itemized_data = maybe_serialize($itemized_data);
    }
    $i = $product_id . '-' . md5($itemized_data);
    $discounted = new \ITELIC\Renewal\Discount($key);
    $discounted = $discounted->get_discount_price();
    $products[$i]['product_base_price'] = $discounted;
    $products[$i]['product_subtotal'] = $products[$i]['product_base_price'];
    //need to add count
    $products[$i]['product_name'] = get_the_title($product_id);
    $products[$i]['product_id'] = $product_id;
    $products[$i]['count'] = 1;
    $description[] = $products[$i]['product_name'];
    $description = apply_filters('it_exchange_get_cart_description', join(', ', $description), $description);
    // Package it up and send it to the transaction method add-on
    $total = empty($args['paid']) ? $discounted : it_exchange_convert_to_database_number($args['paid']);
    $object = new stdClass();
    $object->total = number_format(it_exchange_convert_from_database_number($total), 2, '.', '');
    $object->currency = $currency;
    $object->description = $description;
    $object->products = $products;
    remove_action('it_exchange_add_transaction_success', 'ITELIC\\renew_key_on_renewal_purchase');
    $uniquid = it_exchange_manual_purchases_addon_transaction_uniqid();
    $txn_args = array();
    if (isset($args['date'])) {
        $date = \ITELIC\make_date_time($args['date']);
        $txn_args['post_date'] = \ITELIC\convert_gmt_to_local($date)->format('Y-m-d H:i:s');
        $txn_args['post_date_gmt'] = $date->format('Y-m-d H:i:s');
    }
    $customer = $key->get_customer()->id;
    $tid = it_exchange_add_transaction('manual-purchases', $uniquid, 'Completed', $customer, $object, $txn_args);
    add_action('it_exchange_add_transaction_success', 'ITELIC\\renew_key_on_renewal_purchase');
    return it_exchange_get_transaction($tid);
}
 /**
  * Display a notice to register this add-on.
  *
  * @since 1.0
  */
 public function display_register_notice()
 {
     $options = it_exchange_get_option('addon_itelic');
     if (!empty($options['license']) && !empty($options['activation'])) {
         return;
     }
     $ID = self::ID;
     echo '</tr><tr class="plugin-update-tr"><td colspan="3" class="plugin-update"><div class="update-message">';
     echo sprintf(esc_html__('%sRegister%s this add-on to receive access to automatic upgrades and support. Need a license key? %sPurchase one now%s.', self::SLUG), '<a href="' . admin_url() . 'admin.php?page=it-exchange-addons&add-on-settings=licensing">', '</a>', "<a href=\"https://ironbounddesigns.com?p={$ID}\">", '</a>');
     echo '</div></td>';
 }
Ejemplo n.º 10
0
    /**
     * Render the page.
     *
     * @since 1.0
     */
    public function render()
    {
        $df = it_exchange_php_date_format_to_jquery_datepicker_format(get_option('date_format'));
        $options = it_exchange_get_option('settings_general');
        $position = $options['currency-symbol-position'];
        $decimals = $options['currency-decimals-separator'];
        $thousands = $options['currency-thousands-separator'];
        $symbol = it_exchange_get_currency_symbol($options['default-currency']);
        $form = \ITUtility::merge_defaults($_POST, array('product' => '', 'customer' => '', 'username' => '', 'email' => '', 'first' => '', 'last' => '', 'activations' => '', 'expiration' => '', 'license' => '', 'paid' => '', 'customer-type' => 'existing'));
        ?>

		<form method="POST" action="<?php 
        echo esc_attr(add_query_arg('view', 'add-new', Dispatch::get_tab_link('licenses')));
        ?>
">
			<div class="main-editor">

				<?php 
        do_action('itelic_add_new_license_screen_before_steps');
        ?>

				<ol>
					<?php 
        do_action('itelic_add_new_license_screen_begin_steps');
        ?>

					<li>
						<label for="product"><?php 
        _e("Select a Product", Plugin::SLUG);
        ?>
</label>

						<div class="product-container">
							<select id="product" name="product">
								<?php 
        foreach ($this->products as $product) {
            ?>
									<option value="<?php 
            echo $product->ID;
            ?>
" <?php 
            selected($form['product'], $product->ID);
            ?>
>
										<?php 
            echo $product->post_title;
            ?>
									</option>
								<?php 
        }
        ?>
							</select>
						</div>
					</li>

					<li>
						<fieldset id="customer-type">
							<label><?php 
        _e("Select a Customer", Plugin::SLUG);
        ?>
</label>

							<div class="new-customer-container">
								<p>
									<input type="radio" id="new-customer" name="customer-type" value="new" <?php 
        checked($form['customer-type'], 'new');
        ?>
>
									<label for="new-customer"><?php 
        _e("New Customer", Plugin::SLUG);
        ?>
</label>
								</p>
							</div>

							<div class="existing-customer-container">
								<p>
									<input type="radio" id="existing-customer" name="customer-type" value="existing" <?php 
        checked($form['customer-type'], 'existing');
        ?>
>
									<label for="existing-customer"><?php 
        _e("Existing Customer", Plugin::SLUG);
        ?>
</label>
								</p>
							</div>
						</fieldset>

						<fieldset class="new-customer-form <?php 
        echo $form['customer-type'] == 'new' ? '' : 'hide-if-js';
        ?>
">
							<p>
								<label for="username"><?php 
        _e("Username", Plugin::SLUG);
        ?>
</label>
								<input type="text" id="username" name="username" value="<?php 
        echo $form['username'];
        ?>
">
							</p>

							<p>
								<label for="email"><?php 
        _e("Email", Plugin::SLUG);
        ?>
</label>
								<input type="email" id="email" name="email" value="<?php 
        echo $form['email'];
        ?>
">
							</p>

							<p>
								<label for="first"><?php 
        _e("First Name", Plugin::SLUG);
        ?>
</label>
								<input type="text" id="first" name="first" value="<?php 
        echo $form['first'];
        ?>
">
							</p>

							<p>
								<label for="last"><?php 
        _e("Last Name", Plugin::SLUG);
        ?>
</label>
								<input type="text" id="last" name="last" value="<?php 
        echo $form['last'];
        ?>
">
							</p>
						</fieldset>

						<fieldset class="existing-customer-form <?php 
        echo $form['customer-type'] == 'existing' ? '' : 'hide-if-js';
        ?>
">
							<p>
								<label for="customer" class="screen-reader-text"><?php 
        _e('Customer', Plugin::SLUG);
        ?>
</label>
								<select id="customer" name="customer">
									<?php 
        foreach (get_users() as $user) {
            ?>
										<option value="<?php 
            echo $user->ID;
            ?>
" <?php 
            selected($form['customer'], $user->ID);
            ?>
>
											<?php 
            echo $user->user_login;
            ?>
										</option>
									<?php 
        }
        ?>
								</select>
							</p>
						</fieldset>
					</li>
					<li>
						<div class="activations-container">
							<label for="activations"><?php 
        _e("Activation Limit", Plugin::SLUG);
        ?>
</label>
							<input type="number" id="activations" name="activations" min="0" value="<?php 
        echo $form['activations'];
        ?>
">

							<p class="description"><?php 
        _e("Leave blank for unlimited activations.");
        ?>
</p>
						</div>
					</li>
					<li>
						<div class="expiration-container">

							<label for="expiration"><?php 
        _e("Expiration Date", Plugin::SLUG);
        ?>
</label>
							<input type="date" id="expiration" name="expiration" value="<?php 
        echo $form['expiration'];
        ?>
" data-format="<?php 
        echo esc_attr($df);
        ?>
">

						</div>
					</li>

					<li>
						<div class="key-container">
							<label for="license"><?php 
        _e('License Key', Plugin::SLUG);
        ?>
</label>

							<p>
								<a href="javascript:" id="trigger-manual-key" class="<?php 
        echo empty($form['license']) ? '' : 'hide-if-js';
        ?>
">
									<?php 
        _e("Set the license key manually.", Plugin::SLUG);
        ?>
								</a>

								<a href="javascript:" id="trigger-automatic-key" class="<?php 
        echo empty($form['license']) ? 'hide-if-js' : '';
        ?>
">
									<?php 
        _e("Let Exchange automatically generate a license key for you.", Plugin::SLUG);
        ?>
								</a>
							</p>

							<input type="text" name="license" id="license" value="<?php 
        echo $form['license'];
        ?>
" class="<?php 
        echo empty($form['license']) ? 'hide-if-js' : '';
        ?>
">

						</div>
					</li>

					<li>
						<div class="paid-container">

							<label for="paid"><?php 
        _e("Amount Paid", Plugin::SLUG);
        ?>
</label>
							<input type="text" name="paid" id="paid" value="<?php 
        echo $form['paid'];
        ?>
"
							       data-symbol="<?php 
        echo $symbol;
        ?>
" data-symbol-position="<?php 
        echo $position;
        ?>
"
							       data-thousands-separator="<?php 
        echo $thousands;
        ?>
"
							       data-decimals-separator="<?php 
        echo $decimals;
        ?>
">

						</div>
					</li>

					<?php 
        do_action('itelic_add_new_license_screen_end_steps');
        ?>
				</ol>

				<?php 
        do_action('itelic_add_new_license_screen_after_steps');
        ?>

				<p class="buttons">
					<?php 
        submit_button(__("Create", Plugin::SLUG), 'primary', 'itelic-add-new-key', false);
        ?>
				</p>
			</div>

			<?php 
        wp_nonce_field('itelic-add-new-key');
        ?>

		</form>

		<?php 
    }
 /**
  * Check if we can remotely deactivate this license key.
  *
  * @since 1.0
  *
  * @param array $options
  *
  * @return bool
  */
 public function can_remote_deactivate($options = array())
 {
     if (!$this->license) {
         return false;
     }
     $settings = it_exchange_get_option('addon_itelic');
     return $settings['enable-remote-deactivation'] && $this->license->get_product()->get_feature('licensing', array('field' => 'online-software'));
 }
Ejemplo n.º 12
0
 /**
  * Get info about the key.
  *
  * @since 1.0.2
  *
  * @param bool $break_cache
  *
  * @return object|bool
  */
 protected function get_key_info($break_cache = false)
 {
     $options = it_exchange_get_option('addon_itelic');
     $key = $options['license'];
     if ($break_cache || false === ($data = get_transient('itelic_key_info'))) {
         $data = Plugin::$updater->get_info($key);
         if (!is_wp_error($data)) {
             set_transient('itelic_key_info', $data, DAY_IN_SECONDS);
         }
     }
     return $data;
 }
Ejemplo n.º 13
0
/**
 * Get tags that are shared between managers.
 *
 * @internal
 *
 * @since 1.0
 *
 * @return Listener[]
 */
function get_shared_tags()
{
    return array(new Listener('full_customer_name', function (\WP_User $to) {
        return $to->first_name . " " . $to->last_name;
    }), new Listener('customer_first_name', function (\WP_User $to) {
        return $to->first_name;
    }), new Listener('customer_last_name', function (\WP_User $to) {
        return $to->last_name;
    }), new Listener('customer_email', function (\WP_User $to) {
        return $to->user_email;
    }), new Listener('store_name', function () {
        $settings = it_exchange_get_option('settings_general');
        return $settings['company-name'];
    }));
}
Ejemplo n.º 14
0
 /**
  * Return the product's features
  *
  * @since 1.0
  *
  * @param mixed   $existing   the values passed in by the WP Filter API. Ignored here.
  * @param integer $product_id the WordPress post ID
  * @param array   $options
  *
  * @return string product feature
  */
 public function get_feature($existing, $product_id, $options = array())
 {
     $defaults = array('override' => false, 'disable' => false, 'type' => 'percent', 'amount' => '', 'expiry' => '');
     $values = get_post_meta($product_id, '_it_exchange_itelic_renewal_discount', true);
     $raw_meta = \ITUtility::merge_defaults($values, $defaults);
     if (!$raw_meta['override'] && empty($options['db'])) {
         $settings = it_exchange_get_option('addon_itelic', true);
         $raw_meta['type'] = $settings['renewal-discount-type'];
         $raw_meta['amount'] = $settings['renewal-discount-amount'];
         $raw_meta['expiry'] = $settings['renewal-discount-expiry'];
     }
     if (!isset($options['field'])) {
         // if we aren't looking for a particular field
         return $raw_meta;
     }
     $field = $options['field'];
     if (isset($raw_meta[$field])) {
         // if the field exists with that name just return it
         return $raw_meta[$field];
     } else {
         if (strpos($field, ".") !== false) {
             // if the field name was passed using array dot notation
             $pieces = explode('.', $field);
             $context = $raw_meta;
             foreach ($pieces as $piece) {
                 if (!is_array($context) || !array_key_exists($piece, $context)) {
                     // error occurred
                     return null;
                 }
                 $context =& $context[$piece];
             }
             return $context;
         } else {
             return null;
             // we didn't find the data specified
         }
     }
 }