/** * Serve the request to this endpoint. * * @param \ArrayAccess $get * @param \ArrayAccess $post * * @return Response * * @throws Exception|\Exception */ public function serve(\ArrayAccess $get, \ArrayAccess $post) { if (!isset($post['location'])) { throw new Exception(__("Activation location is required.", Plugin::SLUG), self::CODE_NO_LOCATION); } /** * Fires when the activate API endpoint is being validated. * * This occurs after authentication has taken place. You can return an error response by throwing an * \ITELIC\API\Exception in your callback. * * @since 1.0 * * @param \ArrayAccess $get * @param \ArrayAccess $post */ do_action('itelic_api_validate_activate_request', $get, $post); $location = sanitize_text_field($post['location']); $version = isset($post['version']) ? $post['version'] : ''; if (isset($post['track']) && in_array($post['track'], array('stable', 'pre-release'))) { $track = $post['track']; } else { $track = 'stable'; } if ($version) { $release = itelic_get_release_by_version($this->key->get_product()->ID, $version); } else { $release = null; } $activation = itelic_get_activation_by_location($location, $this->key); try { if ($activation) { if ($activation->get_status() == Activation::DEACTIVATED) { $activation->reactivate(); } $activation->update_meta('track', $track); if ($release) { $activation->set_release($release); } } else { $activation = itelic_activate_license_key($this->key, $location, null, $release, $track); } } catch (\LengthException $e) { throw new Exception($e->getMessage(), Endpoint::CODE_INVALID_LOCATION, $e); } catch (\OverflowException $e) { throw new Exception($e->getMessage(), Endpoint::CODE_MAX_ACTIVATIONS, $e); } /** * Fires when an activation is activated via the HTTP API. * * @since 1.0 * * @param Activation $activation * @param \ArrayAccess $get * @param \ArrayAccess $post */ do_action('itelic_api_activate_key', $activation, $get, $post); return new Response(array('success' => true, 'body' => $activation)); }
/** * Get an activation record by its location. * * @api * * @since 1.0 * * @param string $location * @param \ITELIC\Key $key * * @return \ITELIC\Activation|null */ function itelic_get_activation_by_location($location, \ITELIC\Key $key) { $activations = itelic_get_activations(array('location' => $key->is_online_product() ? itelic_normalize_url($location) : $location, 'key' => $key->get_key(), 'items_per_page' => 1)); if (empty($activations)) { return null; } return reset($activations); }
/** * Serve the request to this endpoint. * * @param \ArrayAccess $get * @param \ArrayAccess $post * * @return Response * * @throws Exception|\Exception */ public function serve(\ArrayAccess $get, \ArrayAccess $post) { $now = \ITELIC\make_date_time(); $expires = $now->add(new \DateInterval("P1D")); $release = $this->activation->get_key()->get_product()->get_latest_release_for_activation($this->activation); // this really is a safeguard. if (!$release) { throw new \UnexpectedValueException(__("No releases available for this product.", Plugin::SLUG)); } if ($release->get_type() == Release::TYPE_SECURITY) { $notice = $release->get_meta('security-message', true); } else { if ($release->get_type() == Release::TYPE_MAJOR) { $notice = __("Warning! This is a major upgrade. Make sure you backup your website before updating.", Plugin::SLUG); } else { $notice = ''; } } /** * Filters the upgrade notice sent back from the API. * * @since 1.0 * * @param string $notice * @param Release $release */ $notice = apply_filters('itelic_get_release_upgrade_notice', $notice, $release); // if the installed version of the software is passed to the API, // and the installed version is greater than the version on record, create an update record // this accounts for manually updating the theme or plugin if (isset($get['installed_version'])) { $installed = itelic_get_release_by_version($this->key->get_product()->ID, $get['installed_version']); if ($installed && version_compare($installed->get_version(), $this->activation->get_release()->get_version(), '>')) { Update::create($this->activation, $installed); } } $info = array('version' => $release->get_version(), 'package' => \ITELIC\generate_download_link($this->activation), 'expires' => $expires->format(\DateTime::ISO8601), 'upgrade_notice' => $notice, 'type' => $release->get_type()); /** * Filter the version info returned by the API. * * @since 1.0 * * @param array $info * @param Key $key * @param Product $product */ $info = apply_filters('itelic_api_version_info', $info, $this->key, $this->key->get_product()); return new Response(array('success' => true, 'body' => array('list' => array($this->key->get_product()->ID => $info)))); }
/** * Retrieve the activations. * * @since 1.0 * * @return \ITELIC\Activation[] */ protected function get_activations() { if ($this->license) { return $this->license->get_activations(\ITELIC\Activation::ACTIVE); } else { return array(); } }
/** * Serve the request to this endpoint. * * @param \ArrayAccess $get * @param \ArrayAccess $post * * @return Response * * @throws Exception|\Exception */ public function serve(\ArrayAccess $get, \ArrayAccess $post) { if (!isset($post['id'])) { throw new Exception(__("Activation ID is required.", Plugin::SLUG), self::CODE_NO_LOCATION_ID); } /** * Fires when the deactivate API endpoint is being validated. * * This occurs after authentication has taken place. You can return an error response by throwing an * \ITELIC\API\Exception in your callback. * * @since 1.0 * * @param \ArrayAccess $get * @param \ArrayAccess $post */ do_action('itelic_api_validate_deactivate_request', $get, $post); $activation_id = absint($post['id']); $activation = itelic_get_activation($activation_id); if ($activation) { if ($activation->get_key()->get_key() !== $this->key->get_key()) { throw new Exception(__("Activation record ID does not match license key.", Plugin::SLUG), self::CODE_INVALID_LOCATION); } else { $activation->deactivate(); } } else { throw new Exception(__("Activation record could not be found.", Plugin::SLUG), self::CODE_INVALID_LOCATION); } /** * Fires when an activation is deactivated via the HTTP API. * * @since 1.0 * * @param Activation $activation * @param \ArrayAccess $get * @param \ArrayAccess $post */ do_action('itelic_api_deactivate_key', $activation, $get, $post); return new Response(array('success' => true, 'body' => $activation)); }
/** * Serve the request to this endpoint. * * @param \ArrayAccess $get * @param \ArrayAccess $post * * @return Response */ public function serve(\ArrayAccess $get, \ArrayAccess $post) { $readme = $this->key->get_product()->get_feature('licensing-readme'); $contributors = array(); if ($readme['author']) { $usernames = explode(',', $readme['author']); foreach ($usernames as $username) { $contributors[$username] = "//profiles.wordpress.org/{$username}"; } } $release = $this->key->get_product()->get_latest_release_for_activation($this->activation); $info = array('id' => $this->key->get_product()->ID, 'name' => $this->key->get_product()->post_title, 'description' => $this->key->get_product()->get_feature('description'), 'version' => $release->get_version(), 'tested' => $readme['tested'], 'requires' => $readme['requires'], 'contributors' => $contributors, 'last_updated' => empty($readme['last_updated']) ? '' : $readme['last_updated']->format(\DateTime::ISO8601), 'banner_low' => $readme['banner_low'], 'banner_high' => $readme['banner_high'], 'package_url' => \ITELIC\generate_download_link($this->activation), 'description_url' => get_permalink($this->key->get_product()->ID), 'changelog' => $this->key->get_product()->get_changelog(), 'sections' => array()); /** * Filter the product info returned by the API. * * @since 1.0 * * @param array $info * @param Product $product */ $info = apply_filters('itelic_api_product_info', $info, $this->key->get_product()); return new Response(array('success' => true, 'body' => array('list' => array($this->key->get_product()->ID => $info)))); }
/** * Get a key. * * @api * * @since 1.0 * * @param string $key * * @return \ITELIC\Key */ function itelic_get_key($key) { $key = \ITELIC\Key::get($key); /** * Filters the key as it is retrieved from the database. * * @since 1.0 * * @param \ITELIC\Key $key */ $filtered = apply_filters('itelic_get_key', $key); if ($filtered instanceof \ITELIC\Key) { $key = $filtered; } return $key; }
/** * Create an activation. * * @param Key $key * @param string $location * @param \DateTime $activation * @param Release $release * @param string $status * * @return Activation * * @throws \LogicException|DB_Exception */ public static function create(Key $key, $location, \DateTime $activation = null, Release $release = null, $status = '') { if (empty($key) || empty($location)) { throw new \InvalidArgumentException(__("The license key and install location are required.", Plugin::SLUG)); } if (strlen($location) > 191) { throw new \LengthException("The location field has a max length of 191 characters."); } if ($key->get_max() && $key->get_active_count() >= $key->get_max()) { throw new \OverflowException(__("This license key has reached it's maximum number of activations.", Plugin::SLUG)); } if ($activation === null) { $activation = make_date_time()->format('Y-m-d H:i:s'); } else { $activation = $activation->format('Y-m-d H:i:s'); } if (empty($status)) { $status = self::ACTIVE; } if ($key->is_online_product()) { $location = itelic_normalize_url($location); } $data = array('lkey' => $key->get_key(), 'location' => $location, 'activation' => $activation, 'deactivation' => null, 'status' => $status); if ($release) { $data['release_id'] = $release->get_pk(); } $db = Manager::make_simple_query_object('itelic-activations'); $existing_activation = itelic_get_activation_by_location($location, $key); if ($existing_activation) { throw new \InvalidArgumentException(__("An activation with this same location already exists.", Plugin::SLUG)); } $id = $db->insert($data); if (!$id) { return null; } $activation = self::get($id); Cache::add($activation); if (!$release) { $latest = $key->get_product()->get_latest_release_for_activation($activation); if ($latest) { $activation->set_release($latest); } } /** * Fires when an activation record is created. * * @since 1.0 * * @param Activation $activation */ do_action('itelic_create_activation', $activation); return $activation; }
/** * Perform the activation. * * @since 1.0 * * @param Key $key * @param string $location * @param string $nonce * * @return Activation * * @throws \InvalidArgumentException|\UnexpectedValueException on error. */ public function do_activation(Key $key, $location, $nonce) { if (!wp_verify_nonce($nonce, "itelic-remote-activate-key-{$key->get_key()}")) { throw new \InvalidArgumentException(__("Sorry, this page has expired. Please refresh and try again.", Plugin::SLUG)); } if (!current_user_can('manage_options')) { throw new \InvalidArgumentException(__("Sorry, you don't have permission to do this.", Plugin::SLUG)); } $record = itelic_activate_license_key($key, $location); if (!$record instanceof Activation) { throw new \UnexpectedValueException(__("Something went wrong. Please refresh and try again.", Plugin::SLUG)); } return $record; }
/** * Parse the status query. * * @since 1.0 * * @return Where|null */ protected function parse_status() { if ($this->args['status'] === 'any') { return null; } else { $white_list = Key::get_statuses(); $statuses = (array) $this->args['status']; foreach ($statuses as $status) { if (!isset($white_list[$status])) { throw new \InvalidArgumentException("Invalid status {$status}"); } } return new Where('status', true, (array) $this->args['status']); } }
/** * Get data to display for a single object. * * @param \ITELIC\Key $object * @param bool $raw * * @return array */ protected function get_fields_for_object(\ITELIC\Key $object, $raw = false) { return array('key' => $object->get_key(), 'status' => $object->get_status(!$raw), 'product' => $raw ? $object->get_product()->ID : $object->get_product()->post_title, 'transaction' => $raw ? $object->get_transaction()->ID : it_exchange_get_transaction_order_number($object->get_transaction()), 'customer' => $raw ? $object->get_customer()->id : $object->get_customer()->wp_user->display_name, 'expires' => $object->get_expires() ? $object->get_expires()->format(DateTime::ISO8601) : '-', 'max' => $object->get_max() ? $object->get_max() : 'Unlimited', 'activations' => $object->get_active_count()); }
/** * (PHP 5 >= 5.1.0)<br/> * String representation of object * * @link http://php.net/manual/en/serializable.serialize.php * @return string the string representation of the object or null */ public function serialize() { $data = array('product' => $this->product->ID, 'key' => $this->key->get_key()); return serialize($data); }
/** * Prepare an individual key view. * * @since 1.0 * * @param Key $key * * @return array */ protected function prepare_key(Key $key) { $data = array('key' => $key->get_key(), 'status' => $key->get_status(false), 'product' => '<a href="' . get_edit_post_link($key->get_product()->ID) . '">' . $key->get_product()->post_title . '</a>', 'customer' => $key->get_customer()->wp_user->display_name, 'expires' => $key->get_expires() === null ? __("Never", Plugin::SLUG) : $key->get_expires()->format(get_option('date_format')), 'active_installs' => $key->get_active_count(), 'max_active' => $key->get_max() ? $key->get_max() : '∞', 'transaction' => '<a href="' . get_edit_post_link($key->get_transaction()->ID) . '">' . it_exchange_get_transaction_order_number($key->get_transaction()) . '</a>'); /** * Filter the columns on the license key list table. * * @since 1.0 * * @param array $data * @param Key $key */ $data = apply_filters('itelic_licenses_list_table_columns', $data, $key); return $data; }
/** * Generate an automatic renewal URL. * * @api * * @since 1.0 * * @param \ITELIC\Key $key * * @return string */ function itelic_generate_auto_renewal_url(\ITELIC\Key $key) { $product_link = get_permalink($key->get_product()->ID); $args = array('renew_key' => $key->get_key()); return add_query_arg($args, $product_link); }
/** * Get the chart for this report. * * @since 1.0 * * @param string $date_type * @param int $product * * @return Chart */ 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, 'p.post_date'); $group = $sql['group']; $per = $sql['per']; if ($per) { $per .= ' AS d, '; } if ($group) { $group = "GROUP BY {$group}"; } /** * @var \wpdb $wpdb */ global $wpdb; $ktn = Manager::get('itelic-keys')->get_table_name($wpdb); $ptn = $wpdb->posts; $raw = "SELECT {$per}COUNT(1) as c FROM {$ktn} k JOIN {$ptn} p ON (k.transaction_id = p.ID and p.post_date BETWEEN %s and %s) WHERE k.status = %s "; if ($product) { $product = absint($product); $raw .= "AND product = '{$product}' "; } $raw .= $group; $active = $wpdb->get_results($wpdb->prepare($raw, $start, $end, Key::ACTIVE)); $expired = $wpdb->get_results($wpdb->prepare($raw, $start, $end, Key::EXPIRED)); $disabled = $wpdb->get_results($wpdb->prepare($raw, $start, $end, Key::DISABLED)); $active = self::fill_gaps(self::translate_results($active), $start, $end, $grouping); $expired = self::fill_gaps(self::translate_results($expired), $start, $end, $grouping); $disabled = self::fill_gaps(self::translate_results($disabled), $start, $end, $grouping); $labels = self::get_labels($active, $date_type); $chart = new Line($labels, 600, 200, array('ibdShowLegend' => '#legend-' . $this->get_slug(), 'responsive' => true)); $statuses = Key::get_statuses(); $chart->add_data_set(array_values($active), $statuses[Key::ACTIVE], 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)")); $chart->add_data_set(array_values($expired), $statuses[Key::EXPIRED], array('fillColor' => "rgba(255,186,0,0.2)", 'strokeColor' => "rgba(255,186,0,1)", 'pointColor' => "rgba(255,186,0,1)", 'pointStrokeColor' => "#fff", 'pointHighlightFill' => "#fff", 'pointHighlightStroke' => "rgba(255,186,0,1)")); $chart->add_data_set(array_values($disabled), $statuses[Key::DISABLED], array('fillColor' => "rgba(221,61,54,0.2)", 'strokeColor' => "rgba(221,61,54,1)", 'pointColor' => "rgba(221,61,54,1)", 'pointStrokeColor' => "#fff", 'pointHighlightFill' => "#fff", 'pointHighlightStroke' => "rgba(221,61,54,1)")); return $chart; }
/** * Get an associative array ( id => link ) with the list * of views available on this table. * * @since 1.0 * @access protected * * @return array */ protected function get_views() { $statuses = Key::get_statuses(); $any = array('any' => __("All", Plugin::SLUG)); $statuses = $any + $statuses; $links = array(); foreach ($statuses as $status => $label) { $links[$status] = sprintf('<a href="%1$s">%2$s</a>', $this->get_view_link($status), $label) . " ({$this->counts[$status]})"; } $selected = isset($_GET['status']) ? $_GET['status'] : 'any'; $links[$selected] = "<strong>{$statuses[$selected]} ({$this->counts[$selected]})</strong>"; return $links; }
/** * Render the view. */ public function render() { if (!$this->key) { return; } wp_enqueue_style('itelic-admin-license-detail'); wp_enqueue_script('itelic-admin-license-detail'); wp_localize_script('itelic-admin-license-detail', 'ITELIC', array('ajax' => admin_url('admin-ajax.php'), 'key' => $this->key->get_key(), 'disabling' => __("Deactivating", Plugin::SLUG), 'df' => it_exchange_php_date_format_to_jquery_datepicker_format($this->get_short_df()), 'update_nonce' => wp_create_nonce('itelic-update-key-' . $this->key->get_key()), 'statuses' => json_encode(Key::get_statuses()))); $jdf = it_exchange_php_date_format_to_jquery_datepicker_format($this->get_short_df()); $online = $this->key->is_online_product(); $disable_activate = $this->key->get_status() != Key::ACTIVE; $disable_tip = __("Disabled or expired licenses cannot be activated.", Plugin::SLUG); $disable_title = $disable_activate ? "title=\"{$disable_tip}\"" : ''; $disable_class = $disable_activate ? 'button-disabled' : ''; $disabled_input = $disable_activate ? ' disabled' : ''; ?> <div id="it-exchange-license-details"> <div class="spacing-wrapper bottom-border header-block"> <div class="status status-<?php echo esc_attr($this->key->get_status()); ?> "> <span data-value="<?php echo esc_attr($this->key->get_status()); ?> " title="<?php esc_attr_e("Click to edit", Plugin::SLUG); ?> "> <?php echo $this->key->get_status(true); ?> </span> </div> <div class="name-block"> <h2 class="customer-name"><?php echo $this->key->get_customer()->wp_user->display_name; ?> </h2> <h2 class="product-name"><?php echo $this->key->get_product()->post_title; ?> </h2> </div> <div class="key-block"> <p> <label for="license-key" class="screen-reader-text"><?php _e("License Key", Plugin::SLUG); ?> </label> <input type="text" id="license-key" size="<?php echo strlen($this->key->get_key()); ?> " readonly value="<?php echo esc_attr($this->key->get_key()); ?> "> </p> </div> </div> <div class="spacing-wrapper bottom-border third-row misc-block"> <div class="third expires"> <h4><?php _e("Expires", Plugin::SLUG); ?> </h4> <h3 title="<?php esc_attr_e("Click to edit", Plugin::SLUG); ?> " data-df="<?php echo $jdf; ?> "> <?php if (null === ($d = $this->key->get_expires())) { ?> <?php _e("Never", Plugin::SLUG); ?> <?php } else { ?> <?php echo \ITELIC\convert_gmt_to_local($d)->format($this->get_short_df()); ?> <?php } ?> </h3> </div> <div class="third transaction"> <h4><?php _e("Transaction", Plugin::SLUG); ?> </h4> <h3> <a href="<?php echo esc_url(get_edit_post_link($this->key->get_transaction()->ID)); ?> "> <?php echo it_exchange_get_transaction_order_number($this->key->get_transaction()); ?> </a> </h3> </div> <div class="third max-activations"> <h4><?php _e("Max Activations", Plugin::SLUG); ?> </h4> <h3 title="<?php esc_attr_e("Click to edit", Plugin::SLUG); ?> "> <?php echo $this->key->get_max() ? $this->key->get_max() : __('Unlimited', Plugin::SLUG); ?> </h3> </div> </div> <div class="spacing-wrapper activations<?php echo count($this->renewals) ? ' bottom-border' : ''; ?> "> <h3><?php _e("Activations", Plugin::SLUG); ?> </h3> <table id="activations-table" class="widefat"> <thead> <tr> <th class="location-col"><?php _e("Location", Plugin::SLUG); ?> </th> <th class="status-col"><?php _e("Status", Plugin::SLUG); ?> </th> <th class="activation-col"><?php _e("Activation", Plugin::SLUG); ?> </th> <th class="deactivation-col"><?php _e("Deactivation", Plugin::SLUG); ?> </th> <th class="version-col"><?php _e("Version", Plugin::SLUG); ?> </th> <th class="delete-col"> <span class="screen-reader-text"><?php _e("Delete", Plugin::SLUG); ?> </span></th> </tr> </thead> <tbody> <?php foreach ($this->key->get_activations() as $activation) { ?> <?php echo $this->get_activation_row_html($activation); ?> <?php } ?> </tbody> </table> <h4><?php _e("Remote Activate", Plugin::SLUG); ?> </h4> <label for="remote-activate-location" class="screen-reader-text"><?php _e("Install Location", Plugin::SLUG); ?> </label> <input type="<?php echo $online ? 'url' : 'text'; ?> " id="remote-activate-location" placeholder="<?php _e("Install Location", Plugin::SLUG); ?> "<?php echo $disabled_input; ?> > <input type="submit" id="remote-activate-submit" class="it-exchange-button <?php echo $disable_class; ?> " value="<?php esc_attr_e("Activate", Plugin::SLUG); ?> " data-tip="<?php echo $disable_tip; ?> "<?php echo $disable_title; ?> > <input type="hidden" id="remote-activate-key" value="<?php echo esc_attr($this->key->get_key()); ?> "> <?php wp_nonce_field('itelic-remote-activate-key-' . $this->key->get_key()); ?> </div> <?php if (count($this->renewals)) { ?> <div class="spacing-wrapper renewals"> <h3><?php _e("Renewal History", Plugin::SLUG); ?> </h3> <ul> <?php foreach ($this->renewals as $renewal) { ?> <li> <?php echo $renewal->get_renewal_date()->format(get_option('date_format')); ?> — <?php if ($renewal->get_transaction()) { ?> <a href="<?php echo get_edit_post_link($renewal->get_transaction()->ID); ?> "> <?php echo it_exchange_get_transaction_order_number($renewal->get_transaction()); ?> </a> <?php } else { ?> <?php _e("Manual Renewal", Plugin::SLUG); ?> <?php } ?> </li> <?php } ?> </ul> </div> <?php } ?> <?php /** * Fires at the end of the single license screen. * * @since 1.0 * * @param Key $key */ do_action('itelic_single_license_screen_end', $this->key); ?> </div> <?php /** * Fires after the main single license screen. * * @since 1.0 * * @param Key $key */ do_action('itelic_single_license_screen_after', $this->key); }
/** * Create a renewal record. * * @since 1.0 * * @param Key $key * @param \IT_Exchange_Transaction $transaction * @param \DateTime $expired * @param \DateTime $renewal * * @return Renewal */ public static function create(Key $key, \IT_Exchange_Transaction $transaction = null, \DateTime $expired, \DateTime $renewal = null) { if (empty($renewal)) { $renewal = make_date_time(); } $revenue = '0.00'; if ($transaction) { $tid = $transaction->ID; foreach ($transaction->get_products() as $product) { if ($product['product_id'] == $key->get_product()->ID) { $revenue = $product['product_subtotal']; break; } } } else { $tid = 0; } $data = array('lkey' => $key->get_key(), 'renewal_date' => $renewal->format("Y-m-d H:i:s"), 'key_expired_date' => $expired->format("Y-m-d H:i:s"), 'transaction_id' => $tid, 'revenue' => $revenue); $db = Manager::make_simple_query_object('itelic-renewals'); $id = $db->insert($data); $renewal = self::get($id); if ($renewal) { /** * Fires when a renewal record is created. * * @since 1.0 * * @param Renewal $renewal */ do_action('itelic_create_renewal', $renewal); Cache::add($renewal); } return $renewal; }
public function test_statuses_exist() { $statuses = Key::get_statuses(); $this->assertArrayHasKey('active', $statuses, 'Active status does not exist.'); $this->assertArrayHasKey('disabled', $statuses, 'Disable status does not exist.'); $this->assertArrayHasKey('expired', $statuses, 'Expired status does not exist.'); }
/** * Generate a key for a certain transaction product. * * @internal * * @since 1.0 * * @param \IT_Exchange_Transaction $transaction * @param Product $product * @param Factory $factory * @param string $status Optionally override the new key's status. Default active. * @param string $key Optionally specify the license key to be used. If empty, uses Factory. * * @return Key */ function generate_key_for_transaction_product(\IT_Exchange_Transaction $transaction, Product $product, Factory $factory, $status = '', $key = '') { $customer = it_exchange_get_transaction_customer($transaction); if (!$customer instanceof \IT_Exchange_Customer) { $customer = new \IT_Exchange_Customer($customer); } if (!$key) { $key = $factory->make(); } foreach ($transaction->get_products() as $tran_product) { if ($tran_product['product_id'] == $product->ID) { if (empty($tran_product['itemized_data'])) { continue; } if (is_string($tran_product['itemized_data'])) { $itemized = maybe_unserialize($tran_product['itemized_data']); } else { $itemized = $tran_product['itemized_data']; } if (isset($itemized['it_variant_combo_hash'])) { $hash = $itemized['it_variant_combo_hash']; $max = $product->get_feature('licensing', array('field' => 'limit', 'for_hash' => $hash)); } } } if (!isset($max)) { $max = $product->get_feature('licensing', array('field' => 'limit')); } if (!$product->has_feature('recurring-payments')) { $expires = null; } else { $type = $product->get_feature('recurring-payments', array('setting' => 'interval')); $count = $product->get_feature('recurring-payments', array('setting' => 'interval-count')); $interval = convert_rp_to_date_interval($type, $count); $expires = make_date_time($transaction->post_date_gmt); $expires->add($interval); } return Key::create($key, $transaction, $product, $customer, $max, $expires, $status); }
/** * Make the notification object. * * @since 1.0 * * @param Reminder $reminder * @param Key $key * @param Template_Manager $manager * * @return Notification */ protected function make_notification(Reminder $reminder, Key $key, Template_Manager $manager) { $template = $reminder->get_post(); $notification = new Notification($key->get_customer()->wp_user, $manager, $template->post_content, $template->post_title); $transaction = $key->get_transaction(); if (!empty($transaction->cart_details->is_guest_checkout)) { if (function_exists('it_exchange_guest_checkout_generate_guest_user_object')) { $notification = new Guest_Notification($notification, $transaction); } else { return null; } } $notification->add_data_source($key); $notification->add_data_source(new Discount($key)); return $notification; }