/**
  * 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 &gt;= 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() : '&infin;', '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'));
                ?>
								&nbsp;&mdash;&nbsp;

								<?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;
 }