/**
  * 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));
 }
 /**
  * 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;
 }
 /**
  * Get an activation record by its key and location.
  *
  * ## Options
  *
  * <location>
  * : Location where the software is installed. URLs are normalized.
  *
  * <key>
  * : License key used for activating the software.
  *
  * [--fields=<fields>]
  * : Limit the output to specific object fields.
  *
  * [--format=<format>]
  * : Accepted values: table, json, csv. Default: table
  *
  * [--raw]
  * : Return raw values. IDs instead of human readable names.
  *
  * @param $args
  * @param $assoc_args
  *
  * @subcommand get-by-location
  * @alias      get-by-loc
  */
 public function get_by_location($args, $assoc_args)
 {
     list($location, $key) = $args;
     $key = itelic_get_key($key);
     if (!$key) {
         WP_CLI::error("Invalid license key.");
     }
     $activation = itelic_get_activation_by_location($location, $key);
     if (!$activation) {
         WP_CLI::error("Activation does not exist.");
     }
     $this->get(array($activation->get_pk()), $assoc_args);
 }