/** * 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)))); }
/** * Create an Upgrade record. * * @since 1.0 * * @param Activation $activation * @param Release $release * @param \DateTime $update_date * @param string $previous_version * * @return Update|null * @throws DB_Exception */ public static function create(Activation $activation, Release $release, \DateTime $update_date = null, $previous_version = '') { if ($update_date === null) { $update_date = make_date_time(); } if (empty($previous_version) && $activation->get_release()) { $previous_version = $activation->get_release()->get_version(); } $data = array('activation' => $activation->get_id(), 'release_id' => $release->get_ID(), 'update_date' => $update_date->format("Y-m-d H:i:s"), 'previous_version' => $previous_version); $db = Manager::make_simple_query_object('itelic-updates'); $ID = $db->insert($data); $update = self::get($ID); if ($update) { $activation->set_release($release); /** * Fires when an update record is created. * * @since 1.0 * * @param Update $update */ do_action('itelic_create_update', $update); Cache::add($update); } return $update; }
/** * Outputs a deactivation link. * * @since 1.0 * * @param array $options * * @return string */ public function deactivate_link($options = array()) { $defaults = array('format' => 'html', 'label' => __('Deactivate', ITELIC\Plugin::SLUG), 'working' => __("Deactivating", ITELIC\Plugin::SLUG)); if (!$this->activation) { return ''; } $options = ITUtility::merge_defaults($options, $defaults); $label = $options['label']; $id = $this->activation->get_id(); $nonce = wp_create_nonce("itelic-deactivate-{$id}"); $working = $options['working']; $link = "<a href=\"javascript:\" class=\"deactivate-location\" data-id=\"{$id}\" data-nonce=\"{$nonce}\" data-working=\"{$working}\">"; $link .= $label; $link .= "</a>"; return $link; }
public function test_statuses_exist() { $statuses = Activation::get_statuses(); $this->assertArrayHasKey('active', $statuses, 'Active status does not exist.'); $this->assertArrayHasKey('deactivated', $statuses, 'Deactivated status does not exist.'); $this->assertArrayHasKey('expired', $statuses, 'Expired status does not exist.'); }
/** * Parse the status query. * * @since 1.0 * * @return Where|null */ protected function parse_status() { if ($this->args['status'] === 'any') { return null; } else { $white_list = Activation::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('q.status', true, (array) $this->args['status']); } }
/** * Delete the activation. * * @param Activation $activation * @param string $nonce * * @return bool * * @throws \InvalidArgumentException */ public function do_delete(Activation $activation, $nonce) { if (!wp_verify_nonce($nonce, "itelic-remote-delete-{$activation->get_pk()}")) { 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)); } $activation->delete(); return true; }
/** * Create activation records for a license key. * * @param \ITELIC\Key $key */ protected function create_activations_for_key(ITELIC\Key $key) { if (in_array($key->get_status(), array(\ITELIC\Key::EXPIRED, \ITELIC\Key::DISABLED))) { return; } $limit = $key->get_max(); if (empty($limit)) { $limit = 20; } $limit = min($limit, $limit / 2 + 2); $created = $key->get_transaction()->post_date_gmt; $end = \ITELIC\make_date_time($created); $end->add(new DateInterval('P5D')); $creation_date = $this->faker->dateTimeBetween($created, $end); $release = $this->get_release_for_date($key, $creation_date); if (!$release) { WP_CLI::error("Release not created."); } \ITELIC\Activation::create($key, $this->faker->domainName, $creation_date, $release); $count = rand(0, $limit - 1); if (!$count) { return; } $now = new DateTime(); for ($i = 0; $i < $count; $i++) { $expires = $key->get_expires(); if ($expires > $now) { $max = $now; } else { $max = $expires; } $creation_date = $this->faker->dateTimeBetween($created, $max); $release = $this->get_release_for_date($key, $creation_date); try { $a = \ITELIC\Activation::create($key, $this->faker->domainName, $creation_date, $release); } catch (LogicException $e) { continue; } catch (IronBound\DB\Exception $e) { continue; } if (!rand(0, 3)) { $deactivate_date = $this->faker->dateTimeBetween($creation_date, $max); $a->deactivate($deactivate_date); } } }
/** * Create an activation record. * * @api * * @since 1.0 * * @param array $args * * @return \ITELIC\Activation|WP_Error */ function itelic_create_activation($args) { $defaults = array('key' => '', 'location' => '', 'activation' => '', 'release' => '', 'status' => '', 'track' => 'stable'); $args = ITUtility::merge_defaults($args, $defaults); $key = is_string($args['key']) ? itelic_get_key($args['key']) : $args['key']; if (!$key) { return new WP_Error('invalid_key', __("Invalid Key", \ITELIC\Plugin::SLUG)); } $location = $args['location']; if (!empty($args['activation'])) { if (is_string($args['activation'])) { $activation = \ITELIC\make_date_time($args['activation']); } else { $activation = $args['activation']; } if (!$activation instanceof DateTime) { return new WP_Error('invalid_activation', __("Invalid activation date.", \ITELIC\Plugin::SLUG)); } } else { $activation = null; } if (!empty($args['release'])) { if (is_string($args['release'])) { $release = itelic_get_release($args['release']); } else { $release = $args['release']; } if (!$release instanceof \ITELIC\Release) { return new WP_Error('invalid_release', __("Invalid release.", \ITELIC\Plugin::SLUG)); } } else { $release = null; } $status = $args['status']; try { $activation = \ITELIC\Activation::create($key, $location, $activation, $release, $status); $activation->add_meta('track', $args['track']); } catch (Exception $e) { return new WP_Error('exception', $e->getMessage()); } return $activation; }
/** * Clear a key's active count cache. * * @since 1.0 * * @param Activation $activation */ function clear_key_active_count_and_total_activation_count_cache(Activation $activation) { wp_cache_delete($activation->get_key()->get_key(), 'itelic-key-active-count'); $releases = itelic_get_releases(array('product' => $activation->get_key()->get_product()->ID, 'status' => array(Release::STATUS_ACTIVE, Release::STATUS_PAUSED))); foreach ($releases as $release) { wp_cache_delete($release->get_pk(), 'itelic-release-active-activations'); } }
/** * Get the activation row HTML. * * @since 1.0 * * @param Activation $activation * * @return string */ public function get_activation_row_html(Activation $activation) { $n_deactivate = wp_create_nonce('itelic-remote-deactivate-' . $activation->get_id()); $n_delete = wp_create_nonce('itelic-remote-delete-' . $activation->get_id()); ob_start(); ?> <tr> <td data-title="<?php _e("Location", Plugin::SLUG); ?> "> <?php echo $activation->get_location(); ?> </td> <td data-title="<?php _e("Status", Plugin::SLUG); ?> "> <?php echo $activation->get_status(true); ?> </td> <td data-title="<?php _e("Activation", Plugin::SLUG); ?> "> <?php echo \ITELIC\convert_gmt_to_local($activation->get_activation())->format($this->get_short_df()); ?> </td> <td data-title="<?php _e("Deactivation", Plugin::SLUG); ?> "> <?php if (null === ($d = $activation->get_deactivation())) { ?> <a href="javascript:" data-id="<?php echo esc_attr($activation->get_id()); ?> " data-nonce="<?php echo $n_deactivate; ?> " class="deactivate"> <?php _e("Deactivate", Plugin::SLUG); ?> </a> <?php } else { ?> <?php echo \ITELIC\convert_gmt_to_local($d)->format($this->get_short_df()); ?> <?php } ?> </td> <td data-title="<?php _e("Version", Plugin::SLUG); ?> "> <?php if (null === ($r = $activation->get_release())) { ?> <?php _e("Unknown", Plugin::SLUG); ?> <?php } else { ?> <?php printf('v%s', $r->get_version()); ?> <?php } ?> </td> <td data-title="<?php _e("Delete", Plugin::SLUG); ?> "> <button data-id="<?php echo esc_attr($activation->get_id()); ?> " class="remove-item" data-nonce="<?php echo $n_delete; ?> "> × </button> </td> </tr> <?php return ob_get_clean(); }
/** * Get all activations of this license key. * * @since 1.0 * * @param string $status * * @return Activation[] */ public function get_activations($status = '') { $args = array('key' => $this->get_key()); if ($status) { if (!array_key_exists($status, Activation::get_statuses())) { throw new \InvalidArgumentException("Invalid status"); } $args['status'] = $status; } return itelic_get_activations($args); }
/** * Generates query args to be appended to the download URL. * * @internal * * @since 1.0 * * @param Activation $activation * @param \DateTime $expires * * @return array */ function generate_download_query_args(Activation $activation, \DateTime $expires) { $args = array('activation' => (int) $activation->get_pk(), 'key' => $activation->get_key()->get_key(), 'expires' => (int) $expires->getTimestamp()); $token = hash_hmac('md5', serialize($args), wp_salt()); $args['token'] = $token; /** * Filters the query args generated for downloading a software update. * * @since 1.0 * * @param array $args Query args. * @param Activation $activation Activation record download is delivered to. * @param \DateTime $expires Expiration date for arguments. Link MUST function until time given. */ $args = apply_filters('itelic_generate_download_query_args', $args, $activation, $expires); return $args; }
/** * @depends test_expiring_license_expires_activations */ public function test_expiring_license_does_not_expire_deactivated_activations() { /** @var Key $key */ $key = $this->key_factory->create_and_get(array('product' => $this->product_factory->create(), 'customer' => 1)); $activation = $this->activation_factory->create(array('location' => 'a.com', 'key' => $key, 'status' => Activation::DEACTIVATED, 'deactivated' => \ITELIC\make_date_time())); $key->expire(); $activation = Activation::get($activation); $this->assertEquals(Activation::DEACTIVATED, $activation->get_status()); }
/** * Get data to display for a single key. * * @param \ITELIC\Activation $activation * @param bool $raw * * @return array */ protected function get_fields_for_object(\ITELIC\Activation $activation, $raw = false) { if ($activation->get_deactivation()) { $deactivated = $activation->get_deactivation()->format(DateTime::ISO8601); } else { $deactivated = '-'; } return array('id' => $activation->get_id(), 'key' => $activation->get_key()->get_key(), 'location' => $activation->get_location(), 'status' => $activation->get_status(!$raw), 'activated' => $activation->get_activation()->format(DateTime::ISO8601), 'deactivated' => $deactivated, 'version' => $activation->get_release() ? $activation->get_release()->get_version() : 'Unknown', 'track' => $activation->get_meta('track', true) ? $activation->get_meta('track', true) : 'stable'); }