public function asJSON()
 {
     $this->params['payload_length'] = count($this->params['payload']);
     if (PHP_MINOR_VERSION < 4) {
         JSONAPIHelpers::warn("PHP 5.4 and above recommended for the API.");
         $text = json_encode($this->params);
     } else {
         $text = json_encode($this->params, JSON_PRETTY_PRINT);
     }
     $jsonp = false;
     if (isset($this->params['callback'])) {
         $jsonp = $this->params['callback'];
     }
     if (isset($this->params['jsonp'])) {
         $jsonp = $this->params['jsonp'];
     }
     if ($jsonp) {
         return "{$jsonp}({$text});";
     } else {
         return $text;
     }
 }
 /**
  * We want to avoid directly accessing Array keys, because
  * a) people have weird debug settings and 
  * b) Some idiot thought it was a good idea to add in warnings when you access a null array key.
  *    Whoever that person is, they should be shot. Out of a cannon. Into the Sun.
  *    
  * @param array to look in
  * @param string key
  * @param default value if not found (Default is i18n xlated to UnNamed
  */
 function orEq($array, $key, $default = null, $valid_values_list = null)
 {
     if ($default === null) {
         $default = __('UnNamed', $this->getPluginName()) . ' - ' . $key;
     }
     if (isset($array[$key])) {
         $value = $array[$key];
     } else {
         $value = $default;
     }
     if ($valid_values_list) {
         foreach ($valid_values_list as $val) {
             if ($value == $val) {
                 return $value;
             }
         }
         JSONAPIHelpers::warn("orEq was passed a valid_values_list, but inputs did not match, so returning default");
         return $default;
     } else {
         return $value;
     }
 }
 /**
  *  This function is the single entry point into the API.
  *  
  *  The order of operations goes like this:
  *  
  *  1) A new result object is created.
  *  2) Check to see if it's a valid API User, if not, do stuff and quit
  *  3) Check to see if the method requested has been implemented
  *  4) If it's implemented, call and turn over control to the method
  *  
  *  This function takes a single hash,  usually $_REQUEST
  *  
  *  WHY? 
  *  
  *  Well, as you will notice with WooCommerce, there is an irritatingly large
  *  dependence on _defined_ and $_GET/$_POST variables, throughout their plugin,
  *  each function "depends" on request state, which is fine, except this
  *  violates 'dependency injection'. We don't know where data might come from
  *  in the future, what if another plugin wants to call this one inside of PHP
  *  within a request, multiple times? 
  *  
  *  No module should ever 'depend' on objects outside of itself, they should be
  *  provided with operating data, or 'injected' with it.
  *  
  *  There is nothing 'wrong' with the way WooCommerce does things, only it leads
  *  to a certain inflexibility in what you can do with it.
  */
 public function route($params)
 {
     global $wpdb;
     $method = $this->orEq($params, 'method', false);
     $proc = $this->orEq($params, 'proc', false);
     if ($method && $proc && !strpos('get_') == 0 && !strpos('set_') == 0 && !strpos('delete_') == 0) {
         switch (strtolower($method)) {
             case 'get':
                 $proc = 'get_' . $proc;
                 break;
             case 'put':
                 $proc = 'set_' . $proc;
                 break;
             case 'delete':
                 $proc = 'delete_' . $proc;
                 break;
         }
     }
     /*
      * The idea behind the provider is that there will be
      * several versions of the API in the future, and the
      * user can choose which one they are writing against.
      * This simplifies the provider files a bit and makes
      * the code more modular.
      */
     $version = intval($this->orEq($params, 'version', 1));
     if (!is_numeric($version)) {
         $version = 1;
     }
     if (file_exists(dirname(__FILE__) . '/API_VERSIONS/version' . $version . '.php')) {
         require_once dirname(__FILE__) . '/API_VERSIONS/version' . $version . '.php';
         $klass = "WC_JSON_API_Provider_v{$version}";
         $klass = str_replace('.', '_', $klass);
         $this->provider = new $klass($this);
     }
     // Reorganize any uploaded files and put them in
     // the params
     $files = array();
     $params['uploads'] = $files;
     $this->createNewResult($params);
     // Now we need to allow for people to add dynamic
     // filters to the models.
     if (isset($params['model_filters']) && is_array($params['model_filters'])) {
         JSONAPIHelpers::debug("Model Filters are Present");
         JSONAPIHelpers::debug(var_export($params['model_filters'], true));
         foreach ($params['model_filters'] as $filter_text => $filter) {
             foreach ($filter as $key => &$value) {
                 $value['name'] = substr($wpdb->prepare("%s", $value['name']), 1, strlen($value['name']));
             }
             $callback = function ($table) use($filter) {
                 return array_merge($table, $filter);
             };
             JSONAPIHelpers::debug("Adding filter: " . $filter_text);
             add_filter($filter_text, $callback);
         }
     } else {
         JSONAPIHelpers::debug("No Model Filters Present");
     }
     if (isset($params['image_sizes']) && is_array($params['image_sizes'])) {
         JSONAPIHelpers::debug("Image Sizes Are Defined");
         foreach ($params['image_sizes'] as $size) {
             foreach (array('name', 'width', 'height', 'crop') as $key) {
                 if (!isset($size[$key])) {
                     throw new \Exception(sprintf(__('%s is required when adding image sizes', $this->td), ucwords($key)));
                 }
             }
             add_image_size($size['name'], $size['width'], $size['height'], $size['crop']);
         }
     }
     JSONAPIHelpers::debug("Beggining request");
     JSONAPIHelpers::debug(var_export($params, true));
     if (!$this->isValidAPIUser($params)) {
         $this->result->addError(__('Not a valid API User', 'woocommerce_json_api'), JSONAPI_INVALID_CREDENTIALS);
         return $this->done();
     }
     if (isset($params['arguments']['password'])) {
         // We shouldn't pass back the password.
         $params['arguments']['password'] = '******';
     }
     if ($this->provider->isImplemented($proc)) {
         try {
             // The arguments are passed by reference here
             $this->validateParameters($params['arguments'], $this->result);
             if ($this->result->status() == false) {
                 JSONAPIHelpers::warn("Arguments did not pass validation");
                 return $this->done();
             } else {
                 JSONAPIHelpers::debug("Arguments have passed validation");
             }
             return $this->provider->{$proc}($params);
         } catch (Exception $e) {
             JSONAPIHelpers::error($e->getMessage());
             $this->unexpectedError($params, $e);
         }
     } else {
         JSONAPIHelpers::warn("{$proc} is not implemented...");
         $this->notImplemented($params);
     }
 }