/** * Get all Exchange products that have licensing enabled. * * @api * * @since 1.0 * * @param array $args * * @return \ITELIC\Product[] */ function itelic_get_products_with_licensing_enabled($args = array()) { $args['meta_query'][] = array('key' => '_it_exchange_itelic_enabled', 'value' => true); $args['show_hidden'] = true; $args['posts_per_page'] = -1; return array_map(function (IT_Exchange_Product $product) { return itelic_get_product($product->ID); }, it_exchange_Get_products($args)); }
/** * Serve the request to this endpoint. * * @param \ArrayAccess $get * @param \ArrayAccess $post * * @return Response * * @throws Exception|\Exception * API Exceptions will be treated as expected errors, and will be displayed as such. * All other exceptions will be treated as unexpected errors and will be displayed with error code 0. */ public function serve(\ArrayAccess $get, \ArrayAccess $post) { $product = itelic_get_product($get['ID']); if (!$product) { status_header(404); echo __("No product found.", Plugin::SLUG); } else { echo $product->get_changelog(); } die; }
/** * This echos the feature metabox. * * @since 1.0 * * @param \WP_Post $post */ function print_metabox($post) { $product = itelic_get_product($post); $data = it_exchange_get_product_feature(isset($post->ID) ? $post->ID : 0, $this->slug); $hidden = $data['enable'] ? '' : ' hide-if-js'; if (empty($data['base_path'])) { $path = $this->create_base_upgrade_path($product); } else { $path = Upgrade_Path::get($data['base_path']); } ?> <p><?php echo $this->description; ?> </p> <p> <input type="checkbox" id="itelic-upgrade-enable" name="itelic_upgrade[enable]" <?php checked(true, $data['enable']); ?> > <label for="itelic-upgrade-enable"><?php _e("Enable upgrade paths for this product."); ?> </label> </p> <div class="itelic-upgrade-settings<?php echo esc_attr($hidden); ?> "> <?php echo $this->render_upgrade_path_html($path); ?> </div> <?php }
/** * Generate license keys for a transaction. * * @internal * * @since 1.0 * * @param \IT_Exchange_Transaction $transaction * @param string $status Default ITELIC_Key::ACTIVE * * @return bool */ function generate_keys_for_transaction(\IT_Exchange_Transaction $transaction, $status = '') { $result = false; foreach ($transaction->get_products() as $product) { if (isset($product['renewed_key']) && $product['renewed_key']) { continue; // this is a renewal purchase we shouldn't generate keys here. } $product = itelic_get_product($product['product_id']); if ($product->has_feature('licensing')) { $customer = it_exchange_get_transaction_customer($transaction); if (!$customer instanceof \IT_Exchange_Customer) { $customer = new \IT_Exchange_Customer($customer); } $factory = new Factory($product, $customer, $transaction); if (generate_key_for_transaction_product($transaction, $product, $factory, $status)) { $result = true; } else { $result = false; } } } return $result; }
/** * This saves the value. * * @since 1.0 */ public function save_feature_on_product_save() { // Abort if we don't have a product ID $product_id = empty($_POST['ID']) ? false : $_POST['ID']; if (!$product_id) { return; } $prev = it_exchange_get_product_feature($product_id, $this->slug); $data = $_POST['itelic']; $data['enabled'] = isset($data['enabled']) ? it_exchange_str_true($data['enabled']) : false; $data['enabled_variant_activations'] = isset($data['enabled_variant_activations']) ? it_exchange_str_true($data['enabled_variant_activations']) : false; $data['online-software'] = isset($data['online-software']) ? it_exchange_str_true($data['online-software']) : false; if (!empty($prev['version'])) { unset($data['version']); } $first_release = get_post_meta($product_id, '_itelic_first_release', true); if (!$first_release && isset($data['update-file']) && $data['update-file']) { $download = $data['update-file']; $download_meta = get_post_meta($download, '_it-exchange-download-info', true); if (empty($download_meta)) { return; } $url = $download_meta['source']; /** * @var \wpdb $wpdb */ global $wpdb; $ID = $wpdb->get_var($wpdb->prepare("SELECT ID FROM {$wpdb->posts} WHERE guid = %s", $url)); $file = get_post($ID); if ($file->post_type == 'attachment') { $product = itelic_get_product($product_id); if (isset($data['version'])) { $version = $data['version']; } elseif (isset($prev['version'])) { $version = $prev['version']; } else { $version = ''; } $type = Release::TYPE_MAJOR; $status = get_post_status($product_id) == 'publish' ? Release::STATUS_ACTIVE : Release::STATUS_DRAFT; $changelog = '<ul><li>' . __("Initial release.", Plugin::SLUG) . '</li></ul>'; if ($version) { try { $args = array('product' => $product, 'file' => $file, 'version' => $version, 'type' => $type, 'status' => $status, 'changelog' => $changelog); $release = itelic_create_release($args); if ($release && !is_wp_error($release)) { update_post_meta($product_id, '_itelic_first_release', $release->get_pk()); } } catch (\Exception $e) { } } } } it_exchange_update_product_feature($product_id, $this->slug, $data); }
/** * (PHP 5 >= 5.1.0)<br/> * Constructs the object * * @link http://php.net/manual/en/serializable.unserialize.php * * @param string $serialized <p> * The string representation of the object. * </p> * * @return void */ public function unserialize($serialized) { $data = unserialize($serialized); $this->product = itelic_get_product($data['product']); $this->feature_data = $this->product->get_feature('licensing-discount'); $this->key = itelic_get_key($data['key']); }
/** * Init an object. * * @since 1.0 * * @param \stdClass $data */ protected function init(\stdClass $data) { $this->ID = $data->ID; $this->product = itelic_get_product($data->product); if (!$this->product) { throw new \InvalidArgumentException("Invalid product."); } $this->download = (int) $data->download; $this->version = $data->version; if (array_key_exists($data->status, self::get_statuses())) { $this->status = $data->status; } else { throw new \InvalidArgumentException("Invalid status."); } if (array_key_exists($data->type, self::get_types())) { $this->type = $data->type; } else { throw new \InvalidArgumentException("Invalid type."); } $this->changelog = $data->changelog; if ($data->start_date && $data->start_date != '0000-00-00 00:00:00') { $this->start_date = make_date_time($data->start_date); } }
/** * Get a product. * * @param $products * * @return \ITELIC\Product */ protected function get_product($products) { return itelic_get_product($products[array_rand($products)]); }
/** * Save post data to a new release. * * @since 1.0 */ public function save_new_release() { if (!isset($_POST['itelic-action']) || $_POST['itelic-action'] != 'add-new-release') { return; } if (!isset($_POST['_wpnonce']) || !wp_verify_nonce($_POST['_wpnonce'], 'itelic-add-new-release')) { $this->errors[] = __("Request expired. Please try again.", Plugin::SLUG); return; } if (!isset($_POST['type-select']) || !array_key_exists($_POST['type-select'], Release::get_types())) { $this->errors[] = __("Invalid release type selected.", Plugin::SLUG); return; } $type = $_POST['type-select']; if (empty($_POST['product'])) { $this->errors[] = __("You must select a product.", Plugin::SLUG); return; } try { $product = itelic_get_product($_POST['product']); } catch (\Exception $e) { $this->errors[] = $e->getMessage(); return; } if (!$product->has_feature('licensing')) { $this->errors[] = __("Product selected does not support licensing.", Plugin::SLUG); return; } if (empty($_POST['version'])) { $this->errors[] = __("Invalid version number entered.", Plugin::SLUG); return; } $version = sanitize_text_field($_POST['version']); if (empty($_POST['upload-file'])) { $this->errors[] = __("No software file selected.", Plugin::SLUG); return; } $attachment = get_post($_POST['upload-file']); $changelog = empty($_POST['whats-changed']) ? '' : stripslashes($_POST['whats-changed']); $security_message = empty($_POST['security-message']) ? '' : stripslashes($_POST['security-message']); if (!current_user_can('unfiltered_html')) { $changelog = wp_kses($changelog, wp_kses_allowed_html()); $security_message = wp_kses($security_message, wp_kses_allowed_html()); } $action = isset($_POST['release']) && $_POST['release'] ? 'release' : 'draft'; $status = 'release' == $action ? Release::STATUS_ACTIVE : Release::STATUS_DRAFT; try { $args = array('product' => $product, 'file' => $attachment, 'version' => $version, 'type' => $type, 'status' => $status, 'changelog' => $changelog, 'security-message' => $security_message); /** * Filters the add new release args. * * @since 1.0 * * @param array $args */ $args = apply_filters('itelic_add_new_release_args', $args); $release = itelic_create_release($args); if (is_wp_error($release)) { $this->errors[] = $release->get_error_message(); return; } if ($release) { /** * Fires when a new release is saved. * * @since 1.0 * * @param Release $release */ do_action('itelic_add_new_release_save', $release); $url = add_query_arg('new', true, itelic_get_admin_edit_release_link($release->get_pk())); wp_redirect($url); die; } } catch (\Exception $e) { $this->errors[] = $e->getMessage(); } }
/** * Get a product. * * @param int $post_id * * @return \ITELIC\Product */ function get_object_by_id($post_id) { return itelic_get_product($post_id); }
/** * Get a post object by ID * * @param int $arg * * @return \ITELIC\Product|false */ public function get($arg) { $product = itelic_get_product($arg); if (!$product) { return false; } if (!$product->has_feature('licensing')) { return false; } return $product; }
/** * Create a release. * * @api * * @since 1.0 * * @param array $args * * @return \ITELIC\Release|WP_Error */ function itelic_create_release($args) { $defaults = array('product' => '', 'file' => '', 'version' => '', 'type' => '', 'status' => '', 'changelog' => ''); $args = wp_parse_args($args, $defaults); if (is_numeric($args['product'])) { $product = itelic_get_product($args['product']); } else { $product = $args['product']; } if (!$product) { return new WP_Error('invalid_product', __('Invalid Product', \ITELIC\Plugin::SLUG)); } if (is_numeric($args['file'])) { $file = get_post($args['file']); } else { $file = $args['file']; } if (!$file || get_post_type($file) != 'attachment') { return new WP_Error('invalid_file', __("Invalid File", \ITELIC\Plugin::SLUG)); } $version = $args['version']; $type = $args['type']; $status = $args['status']; $changelog = $args['changelog']; try { $release = \ITELIC\Release::create($product, $file, $version, $type, $status, $changelog); if (isset($args['security-message'])) { $release->add_meta('security-message', $args['security-message']); } return $release; } catch (InvalidArgumentException $e) { return new WP_Error('exception', $e->getMessage()); } }
/** * Create a release. * * [<file>] * : Read changelog from <file> Passing `-` as the filename will cause * changelog to be read from STDIN * * --product=<product> * : ID of the product being released. * * --version=<version> * : Version number of the release being created. * * --file=<file> * : ID of the attachment being used for the software download. * * --type=<type> * : Type of release. Accepted values: major, minor, security, pre-release * * [--status=<status>] * : Status of the release. Accepted values: draft, active. Default: draft * * [--changelog=<changelog>] * : What changed in this release. Version number and date omitted. HTML * allowed. * * [--edit] * : Immediately open system's editor to write or edit changelog. * * [--porcelain] * : Output just the new release ID. * * @param $args * @param $assoc_args */ public function create($args, $assoc_args) { if (!empty($args[0])) { $assoc_args['changelog'] = $this->read_from_file_or_stdin($args[0]); } if (\WP_CLI\Utils\get_flag_value($assoc_args, 'edit')) { $input = \WP_CLI\Utils\get_flag_value($assoc_args, 'post_content', ''); $output = \WP_CLI\Utils\launch_editor_for_input($input, 'WP-CLI: New Release Changelog'); if ($output) { $assoc_args['changelog'] = $output; } else { $assoc_args['changelog'] = $input; } } $assoc_args = wp_parse_args($assoc_args, array('status' => \ITELIC\Release::STATUS_DRAFT, 'changelog' => '')); parent::_create($args, $assoc_args, function ($params) { $product = itelic_get_product($params['product']); if (!$product) { WP_CLI::error('Invalid product ID.'); } $version = $params['version']; $file = get_post($params['file']); if (!$file) { WP_CLI::error('Invalid post ID for download file.'); } $type = $params['type']; $status = $params['status']; if (!in_array($status, array(\ITELIC\Release::STATUS_ACTIVE, \ITELIC\Release::STATUS_DRAFT))) { WP_CLI::error("Invalid status."); } $changelog = $params['changelog']; try { $args = array('product' => $product, 'file' => $file, 'version' => $version, 'type' => $type, 'status' => $status, 'changelog' => $changelog); $release = itelic_create_release($args); if (is_wp_error($release)) { return $release; } return $release->get_pk(); } catch (Exception $e) { WP_CLI::error($e->getMessage()); } }); }
/** * Get the product being upgraded to. * * @since 1.0 * * @return \IT_Exchange_Product */ public function get_upgrade_product() { return itelic_get_product(get_post_meta($this->get_ID(), '_itelic_upgrade_product', true)); }
/** * Initialize this object. * * @param \stdClass $data */ protected function init(\stdClass $data) { $this->key = $data->lkey; $this->transaction = it_exchange_get_transaction($data->transaction_id); $this->product = itelic_get_product($data->product); // account for guest checkouts if ($data->customer) { $this->customer = it_exchange_get_customer($data->customer); } else { $customer = it_exchange_get_transaction_customer($this->transaction); if (!$customer instanceof \IT_Exchange_Customer) { $customer = new \IT_Exchange_Customer($customer); $customer->wp_user->display_name = sprintf(__("Guest (%s)", Plugin::SLUG), $customer->wp_user->user_email); } $this->customer = $customer; } $this->status = $data->status; $this->max = $data->max; if (!empty($data->expires) && $data->expires != '0000-00-00 00:00:00') { $this->expires = make_date_time($data->expires); } foreach (array('transaction', 'product', 'customer') as $maybe_error) { if (!$this->{$maybe_error} || is_wp_error($this->{$maybe_error})) { throw new \InvalidArgumentException("Invalid {$maybe_error}"); } } }
/** * Generate update records. * * ## Options * * <product> * : Product ID to generate update records for. * * @param $args * @param $assoc_args */ public function generate($args, $assoc_args) { list($product) = $args; $product = itelic_get_product($product); if (!$product) { WP_CLI::error("Invalid product ID"); } $releases = itelic_get_releases(array('product' => $product->ID, 'order' => array('start_date' => 'ASC'))); $notify = \WP_CLI\Utils\make_progress_bar(sprintf("Generating Updates: %d", $product->ID), count($releases)); foreach ($releases as $release) { switch ($release->get_type()) { case \ITELIC\Release::TYPE_MAJOR: $percent_updated = 75; break; case \ITELIC\Release::TYPE_MINOR: $percent_updated = 90; break; case \ITELIC\Release::TYPE_SECURITY: $percent_updated = 95; break; case \ITELIC\Release::TYPE_PRERELEASE: $percent_updated = 95; break; default: throw new InvalidArgumentException("Invalid release type."); } $total_activations = new \ITELIC\Query\Activations(array('activation' => array('before' => $release->get_start_date()->format('Y-m-d H:i:s')), 'product' => $product->ID, 'return_value' => 'count')); $total_activations = $total_activations->get_results(); $activations = itelic_get_activations(array('activation' => array('before' => $release->get_start_date()->format('Y-m-d H:i:s')), 'product' => $product->ID, 'order' => 'rand', 'items_per_page' => $total_activations * ($percent_updated / 100))); foreach ($activations as $activation) { if ($activation->get_deactivation() && $activation->get_deactivation() > $release->get_start_date()) { continue; } if ($release->get_type() == ITELIC\Release::TYPE_MAJOR) { $days = rand(0, 10); } else { $days = rand(0, 4); } $upgade_date = $release->get_start_date()->add(new DateInterval("P{$days}D")); \ITELIC\Update::create($activation, $release, $upgade_date); } if ($release->get_status() == \ITELIC\Release::STATUS_ARCHIVED) { $release->set_status(\ITELIC\Release::STATUS_ACTIVE); $release->archive(); } $notify->tick(); } $notify->finish(); }
/** * 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; }
/** * Render the license keys email notification shortcode tag. * * @internal * * @since 1.0 * * @param \IT_Exchange_Email_Notifications $email_notifications * * @return string */ function render_license_keys_email_notification_shortcode(\IT_Exchange_Email_Notifications $email_notifications) { $transaction = it_exchange_get_transaction($email_notifications->transaction_id); $out = ''; foreach ($transaction->get_products() as $product) { $product = itelic_get_product($product['product_id']); $key = get_key_for_transaction_product($transaction->ID, $product->ID); if ($key) { $out .= "<li>" . $product->post_title . ": " . $key->get_key() . "</li>"; } } if ($out) { $out = "<h4>" . __("License Keys", Plugin::SLUG) . "<h4/>" . "<ul>{$out}</ul>"; } return $out; }
/** * Apply the renewal discount. * * @since 1.0 * * @param string|float $db_base_price * @param array $product * @param bool $format * * @return string|float */ public function apply_renewal_discount($db_base_price, $product, $format) { try { $product = itelic_get_product($product['product_id']); } catch (\Exception $e) { return $db_base_price; } if (!$product->get_feature('licensing')) { return $db_base_price; } $session = $this->get_cache_data(); if (!isset($session["p" . $product->ID]) || $session["p" . $product->ID] === null) { return $db_base_price; } $key = $session["p" . $product->ID]; $key = itelic_get_key($key); $discount = new Discount($key); if (!$discount->is_discount_valid()) { return $db_base_price; } return $discount->get_discount_price($format); }
<?php if ($license !== null) { ?> <?php continue; ?> <?php } else { ?> <li> <label for="itelic-renew-product-<?php echo esc_attr($product); ?> "> <?php echo itelic_get_product($product)->post_title; ?> </label> <select id="itelic-renew-product-<?php echo esc_attr($product); ?> " name="itelic_key[<?php echo esc_attr($product); ?> ]"> <?php $keys = itelic_get_keys(array('customer' => it_exchange_get_current_customer_id(), 'product' => $product)); ?> <?php foreach ($keys as $key) {