예제 #1
0
파일: api.php 프로젝트: pritcham/XenAPI
 /**
  * Processes the REST request.
  */
 public function processRequest()
 {
     // Check if the action is an user action.
     if ($this->isUserAction()) {
         if ($this->hasRequest('value')) {
             if (!$this->getRequest('value')) {
                 // Throw error if the 'value' argument is set but empty.
                 $this->throwError(1, 'value');
                 break;
             }
             // Create a user variable with the 'value' argument.
             $user = $this->xenAPI->getUser($this->getRequest('value'));
             if (!$user->isRegistered()) {
                 // Throw error if the 'value' user is not registered.
                 $this->throwError(4, 'user', $this->getRequest('value'));
                 break;
             }
         } else {
             if ($this->hasRequest('hash')) {
                 // The 'value' argument was not set, check if hash is an API key.
                 if ($this->hasAPIKey() && !isset($this->grab_as)) {
                     /**
                      * The 'hash' argument is an API key, and the 'value' argument
                      * is required but not set, throw error.
                      */
                     $this->throwError(3, 'value');
                 }
                 // Get the user from the hash.
                 $user = $this->getUser();
             } else {
                 // Nor the 'value' argument or the 'hash' argument has been set, throw error.
                 $this->throwError(3, 'value');
                 break;
             }
         }
     }
     switch (strtolower($this->getAction())) {
         case 'authenticate':
             /**
              * Authenticates the user and returns the hash that the user has to use for future requests.
              *
              * EXAMPLE:
              *   - api.php?action=authenticate&username=USERNAME&password=PASSWORD
              */
             if (!$this->hasRequest('username')) {
                 // The 'username' argument has not been set, throw error.
                 $this->throwError(3, 'username');
                 break;
             } else {
                 if (!$this->getRequest('username')) {
                     // Throw error if the 'username' argument is set but empty.
                     $this->throwError(1, 'username');
                     break;
                 } else {
                     if (!$this->hasRequest('password')) {
                         // The 'password' argument has not been set, throw error.
                         $this->throwError(3, 'password');
                         break;
                     } else {
                         if (!$this->getRequest('password')) {
                             // Throw error if the 'password' argument is set but empty.
                             $this->throwError(1, 'password');
                             break;
                         }
                     }
                 }
             }
             // Get the user object.
             $user = $this->xenAPI->getUser($this->getRequest('username'));
             if (!$user->isRegistered()) {
                 // Requested user was not registered, throw error.
                 $this->throwError(4, 'user', $this->getRequest('username'));
             } else {
                 // Requested user was registered, check authentication.
                 if ($user->validateAuthentication($this->getRequest('password'))) {
                     // Authentication was valid, grab the user's authentication record.
                     $record = $user->getAuthenticationRecord();
                     $ddata = unserialize($record['data']);
                     // Send the hash in responsel.
                     $this->sendResponse(array('hash' => base64_encode($ddata['hash'])));
                 } else {
                     // The username or password was wrong, throw error.
                     $this->throwError(5, 'Invalid username or password!');
                 }
             }
             break;
         case 'createalert':
             if (!$this->hasRequest('user')) {
                 // The 'user' argument has not been set, throw error.
                 $this->throwError(3, 'user');
                 break;
             } else {
                 if (!$this->getRequest('user')) {
                     // Throw error if the 'user' argument is set but empty.
                     $this->throwError(1, 'user');
                     break;
                 } else {
                     if (!$this->hasRequest('cause_user')) {
                         // The 'cause_user' argument has not been set, throw error.
                         $this->throwError(3, 'cause_user');
                         break;
                     } else {
                         if (!$this->getRequest('cause_user')) {
                             // Throw error if the 'cause_user' argument is set but empty.
                             $this->throwError(1, 'cause_user');
                             break;
                         } else {
                             if (!$this->hasRequest('content_type')) {
                                 // The 'content_type' argument has not been set, throw error.
                                 $this->throwError(3, 'content_type');
                                 break;
                             } else {
                                 if (!$this->getRequest('content_type')) {
                                     // Throw error if the 'content_type' argument is set but empty.
                                     $this->throwError(1, 'content_type');
                                     break;
                                 } else {
                                     if (!$this->hasRequest('content_id')) {
                                         // The 'content_id' argument has not been set, throw error.
                                         $this->throwError(3, 'content_id');
                                         break;
                                     } else {
                                         if (!$this->getRequest('content_id')) {
                                             // Throw error if the 'content_id' argument is set but empty.
                                             $this->throwError(1, 'content_id');
                                             break;
                                         } else {
                                             if (!$this->hasRequest('alert_action')) {
                                                 // The 'alert_action' argument has not been set, throw error.
                                                 $this->throwError(3, 'alert_action');
                                                 break;
                                             } else {
                                                 if (!$this->getRequest('alert_action')) {
                                                     // Throw error if the 'alert_action' argument is set but empty.
                                                     $this->throwError(1, 'alert_action');
                                                     break;
                                                 }
                                             }
                                         }
                                     }
                                 }
                             }
                         }
                     }
                 }
             }
             $alert_user = $this->getXenAPI()->getUser($this->getRequest('user'));
             if (!$alert_user->isRegistered()) {
                 // Requested user was not registered, throw error.
                 $this->throwError(4, 'user', $this->getRequest('user'));
             }
             $cause_user = $this->getXenAPI()->getUser($this->getRequest('cause_user'));
             if (!$cause_user->isRegistered()) {
                 // Requested user was not registered, throw error.
                 $this->throwError(4, 'cause_user', $this->getRequest('cause_user'));
             }
             $alert_data = array('content_type' => $this->getRequest('content_type'), 'content_id' => $this->getRequest('content_id'), 'action' => $this->getRequest('alert_action'));
             // Create the thread object.
             $alert_results = $this->xenAPI->createAlert($alert_user, $cause_user, $alert_data);
             // Alert was successful, return results.
             $this->sendResponse($alert_results);
         case 'createconversation':
             /**
              * TODO
              *
              * EXAMPLE:
              *   - api.php
              */
             if ($this->hasAPIKey() && !$this->hasRequest('grab_as')) {
                 // The 'grab_as' argument has not been set, throw error.
                 $this->throwError(3, 'grab_as');
             } else {
                 if ($this->hasAPIKey() && !$this->getRequest('grab_as')) {
                     // Throw error if the 'grab_as' argument is set but empty.
                     $this->throwError(1, 'grab_as');
                 }
             }
             $conversation_data = array();
             // Array of required parameters.
             $required_parameters = array('recipients', 'title', 'message');
             // Array of additional parameters.
             $additional_parameters = array('open_invite', 'conversation_locked');
             foreach ($required_parameters as $required_parameter) {
                 // Check if the required parameter is set and not empty.
                 $this->checkRequestParameter($required_parameter);
                 // Set the request value.
                 $conversation_data[$required_parameter] = $this->getRequest($required_parameter);
             }
             if (strpos($this->getRequest('recipients'), ',') !== FALSE) {
                 $recipient_array = explode(',', $this->getRequest('recipients'));
                 foreach ($recipient_array as $recipient) {
                     $user = $this->getXenAPI()->getUser($recipient);
                     if (!$user->isRegistered()) {
                         // Requested user was not registered, throw error.
                         $this->throwError(4, 'user', $recipient);
                     }
                 }
             } else {
                 $user = $this->getXenAPI()->getUser($this->getRequest('recipients'));
                 if (!$user->isRegistered()) {
                     // Requested user was not registered, throw error.
                     $this->throwError(4, 'user', $this->getRequest('recipients'));
                 }
             }
             foreach ($additional_parameters as $additional_parameter) {
                 if ($this->hasRequest($additional_parameter)) {
                     // Set the request value.
                     $conversation_data[$additional_parameter] = TRUE;
                 }
             }
             // Create the conversation object.
             $conversation_results = $this->xenAPI->createConversation($this->getUser(), $conversation_data);
             $this->handleUserError($conversation_results, 'conversation_creation_error', 'creating a new conversation');
         case 'createconversationreply':
             /**
              * TODO
              *
              * EXAMPLE:
              *   - api.php
              */
             if ($this->hasAPIKey() && !$this->hasRequest('grab_as')) {
                 // The 'grab_as' argument has not been set, throw error.
                 $this->throwError(3, 'grab_as');
             } else {
                 if ($this->hasAPIKey() && !$this->getRequest('grab_as')) {
                     // Throw error if the 'grab_as' argument is set but empty.
                     $this->throwError(1, 'grab_as');
                 }
             }
             $conversation_reply_data = array();
             // Array of required parameters.
             $required_parameters = array('conversation_id', 'message');
             foreach ($required_parameters as $required_parameter) {
                 // Check if the required parameter is set and not empty.
                 $this->checkRequestParameter($required_parameter);
                 // Set the request value.
                 $conversation_reply_data[$required_parameter] = $this->getRequest($required_parameter);
             }
             // Try to grab the thread from XenForo.
             $conversation = $this->getXenAPI()->getConversation($this->getRequest('conversation_id'), $this->getUser());
             if ($conversation == NULL) {
                 // Could not find the conversation, throw error.
                 $this->throwError(19, 'conversation', $this->getRequest('conversation_id'));
             }
             // Create the conversation reply object.
             $conversation_reply_results = $this->xenAPI->createConversationReply($this->getUser(), $conversation_reply_data);
             $this->handleUserError($conversation_reply_results, 'conversation_reply_creation_error', 'creating a new conversation reply');
         case 'createpost':
             /**
              * TODO
              *
              * EXAMPLE:
              *   - api.php
              */
             if ($this->hasAPIKey() && !$this->hasRequest('grab_as')) {
                 // The 'grab_as' argument has not been set, throw error.
                 $this->throwError(3, 'grab_as');
                 break;
             } else {
                 if ($this->hasAPIKey() && !$this->getRequest('grab_as')) {
                     // Throw error if the 'grab_as' argument is set but empty.
                     $this->throwError(1, 'grab_as');
                     break;
                 }
             }
             if (!$this->hasRequest('thread_id')) {
                 // The 'thread_id' argument has not been set, throw error.
                 $this->throwError(3, 'thread_id');
                 break;
             } else {
                 if (!$this->getRequest('thread_id')) {
                     // Throw error if the 'thread_id' argument is set but empty.
                     $this->throwError(1, 'thread_id');
                     break;
                 }
             }
             // Try to grab the thread from XenForo.
             $thread = $this->getXenAPI()->getThread($this->getRequest('thread_id'), array(), $this->getUser());
             if ($thread === NULL) {
                 // Could not find the thread, throw error.
                 $this->throwError(19, 'thread', $this->getRequest('thread_id'));
             }
             if (!$this->hasRequest('message')) {
                 // The 'message' argument has not been set, throw error.
                 $this->throwError(3, 'message');
                 break;
             } else {
                 if (!$this->getRequest('message')) {
                     // Throw error if the 'message' argument is set but empty.
                     $this->throwError(1, 'message');
                     break;
                 }
             }
             $post_data = array('thread_id' => $thread['thread_id'], 'message' => $this->getRequest('message'));
             // Create the post object.
             $post_results = $this->xenAPI->createPost($this->getUser(), $post_data);
             $this->handleUserError($post_results, 'post_creation_error', 'creating a new post');
         case 'createprofilepost':
             /**
              * TODO
              *
              * EXAMPLE:
              *   - api.php
              */
             // Array of required parameters.
             $required_parameters = array('message');
             foreach ($required_parameters as $required_parameter) {
                 // Check if the required parameter is set and not empty.
                 $this->checkRequestParameter($required_parameter);
             }
             if ($this->hasRequest('user')) {
                 if (!$this->getRequest('user')) {
                     // Throw error if the 'user' argument is set but empty.
                     $this->throwError(1, 'user');
                     break;
                 }
                 $profile_user = $this->getXenAPI()->getUser($this->getRequest('user'));
                 if (!$user->isRegistered()) {
                     // Requested user was not registered, throw error.
                     $this->throwError(4, 'user', $this->getRequest('user'));
                 }
             } else {
                 $profile_user = $user;
             }
             $profile_post_data = array('user_id' => $profile_user->data['user_id'], 'message' => $this->getRequest('message'));
             // Create the post object.
             $profile_post_results = $this->xenAPI->createProfilePost($user, $profile_post_data);
             $this->handleUserError($profile_post_results, 'profile_post_creation_error', 'creating a new profile post');
         case 'createprofilepostcomment':
             /**
              * TODO
              *
              * EXAMPLE:
              *   - api.php
              */
             if ($this->hasAPIKey() && !$this->hasRequest('grab_as')) {
                 // The 'grab_as' argument has not been set, throw error.
                 $this->throwError(3, 'grab_as');
             } else {
                 if ($this->hasAPIKey() && !$this->getRequest('grab_as')) {
                     // Throw error if the 'grab_as' argument is set but empty.
                     $this->throwError(1, 'grab_as');
                 }
             }
             // Array of required parameters.
             $required_parameters = array('profile_post_id', 'message');
             foreach ($required_parameters as $required_parameter) {
                 // Check if the required parameter is set and not empty.
                 $this->checkRequestParameter($required_parameter);
             }
             // Try to grab the node from XenForo.
             $profile_post = $this->getXenAPI()->getProfilePost($this->getRequest('profile_post_id'), array(), $this->getUser());
             if ($profile_post == NULL) {
                 // Could not find the node, throw error.
                 $this->throwError(19, 'profile post', $this->getRequest('profile_post_id'));
             }
             $profile_post_comment_data = array('profile_post_id' => $profile_post['profile_post_id'], 'profile_user_id' => $profile_post['profile_user_id'], 'message' => $this->getRequest('message'));
             // Create the post object.
             $profile_post_comment_results = $this->xenAPI->createProfilePostComment($this->getUser(), $profile_post_comment_data);
             $this->handleUserError($profile_post_comment_results, 'profile_post_comment_creation_error', 'creating a new profile post comment');
         case 'createthread':
             /**
              * TODO
              *
              * EXAMPLE:
              *   - api.php
              */
             if ($this->hasAPIKey() && !$this->hasRequest('grab_as')) {
                 // The 'grab_as' argument has not been set, throw error.
                 $this->throwError(3, 'grab_as');
                 break;
             } else {
                 if ($this->hasAPIKey() && !$this->getRequest('grab_as')) {
                     // Throw error if the 'grab_as' argument is set but empty.
                     $this->throwError(1, 'grab_as');
                     break;
                 }
             }
             if (!$this->hasRequest('node_id')) {
                 // The 'node_id' argument has not been set, throw error.
                 $this->throwError(3, 'node_id');
                 break;
             } else {
                 if (!$this->getRequest('node_id')) {
                     // Throw error if the 'node_id' argument is set but empty.
                     $this->throwError(1, 'node_id');
                     break;
                 }
             }
             // Try to grab the node from XenForo.
             $node = $this->getXenAPI()->getNode($this->getRequest('node_id'), array(), $this->getUser());
             if ($node == NULL) {
                 // Could not find the node, throw error.
                 $this->throwError(19, 'node', $this->getRequest('node_id'));
             }
             if (!$this->hasRequest('title')) {
                 // The 'title' argument has not been set, throw error.
                 $this->throwError(3, 'title');
                 break;
             } else {
                 if (!$this->getRequest('title')) {
                     // Throw error if the 'title' argument is set but empty.
                     $this->throwError(1, 'title');
                     break;
                 }
             }
             if (!$this->hasRequest('message')) {
                 // The 'message' argument has not been set, throw error.
                 $this->throwError(3, 'message');
                 break;
             } else {
                 if (!$this->getRequest('message')) {
                     // Throw error if the 'message' argument is set but empty.
                     $this->throwError(1, 'message');
                     break;
                 }
             }
             $thread_data = array();
             // Array of additional parameters.
             $additional_parameters = array('prefix_id', 'discussion_open', 'sticky');
             foreach ($additional_parameters as $additional_parameter) {
                 // Check if the additional parameter is set and not empty.
                 $this->checkRequestParameter($additional_parameter, FALSE);
                 if ($this->getRequest($additional_parameter)) {
                     // Set the request value.
                     $thread_data[$additional_parameter] = $this->getRequest($additional_parameter);
                 }
             }
             $thread_data += array('node_id' => $node['node_id'], 'title' => $this->getRequest('title'), 'message' => $this->getRequest('message'));
             // Create the thread object.
             $thread_results = $this->xenAPI->createThread($this->getUser(), $thread_data);
             $this->handleUserError($thread_results, 'thread_creation_error', 'creating a new thread');
         case 'deletepost':
             /**
              * TODO
              *
              * EXAMPLE:
              *   - api.php
              */
             if (!$this->hasRequest('post_id')) {
                 // The 'post_id' argument has not been set, throw error.
                 $this->throwError(3, 'post_id');
                 break;
             } else {
                 if (!$this->getRequest('post_id')) {
                     // Throw error if the 'post_id' argument is set but empty.
                     $this->throwError(1, 'post_id');
                     break;
                 }
             }
             if ($this->hasRequest('reason')) {
                 if (!$this->getRequest('reason')) {
                     // Throw error if the 'reason' argument is set but empty.
                     $this->throwError(1, 'reason');
                     break;
                 }
                 $reason = $this->getRequest('reason');
             } else {
                 $reason = NULL;
             }
             // Try to grab the post from XenForo.
             $post = $this->getXenAPI()->getPost($this->getRequest('post_id'), array(), $this->getUser());
             if ($post == NULL) {
                 // Could not find the post, throw error.
                 $this->throwError(19, 'post', $this->getRequest('post_id'));
             }
             $delete_results = $this->xenAPI->deletePost($this->getRequest('post_id'), $reason, $this->hasRequest('hard_delete'), $this->getUser());
             $this->handleUserError($delete_results, 'post_deletion_error', 'deleting post');
         case 'deleteuser':
             /**
              * TODO
              *
              * EXAMPLE:
              *   - api.php
              */
             if ($this->hasRequest('value')) {
                 if (!$this->getRequest('value')) {
                     // Throw error if the 'value' argument is set but empty.
                     $this->throwError(1, 'value');
                     break;
                 }
                 $user = $this->getRequest('value');
             } else {
                 if ($this->hasAPIKey()) {
                     if (!$this->hasRequest('value')) {
                         // The 'value' argument has not been set, throw error.
                         $this->throwError(3, 'value');
                         break;
                     } else {
                         if (!$this->getRequest('value')) {
                             // Throw error if the 'value' argument is set but empty.
                             $this->throwError(1, 'value');
                             break;
                         }
                     }
                     $user = $this->getRequest('value');
                 } else {
                     $user = NULL;
                 }
             }
             //if ($this->hasAPIKey() || $this->getUser()->isAdmin()) {
             if ($this->hasRequest('reason')) {
                 if (!$this->getRequest('reason')) {
                     // Throw error if the 'reason' argument is set but empty.
                     $this->throwError(1, 'reason');
                     break;
                 }
                 $reason = $this->getRequest('reason');
             } else {
                 $reason = NULL;
             }
             // Try to grab the user from XenForo.
             $user = $this->getXenAPI()->getUser($user);
             if (!$user->isRegistered()) {
                 // Requested user was not registered, throw error.
                 $this->throwError(4, 'user', $this->getRequest('value'));
             }
             $delete_results = $this->getXenAPI()->deleteUser($user);
             $this->handleUserError($delete_results, 'user_deletion_error', 'deleting user');
         case 'editpost':
             if ($this->hasAPIKey() && !$this->hasRequest('grab_as')) {
                 // The 'grab_as' argument has not been set, throw error.
                 $this->throwError(3, 'grab_as');
             } else {
                 if ($this->hasAPIKey() && !$this->getRequest('grab_as')) {
                     // Throw error if the 'grab_as' argument is set but empty.
                     $this->throwError(1, 'grab_as');
                 }
             }
             if (!$this->hasRequest('post_id')) {
                 // The 'post_id' argument has not been set, throw error.
                 $this->throwError(3, 'post_id');
                 break;
             } else {
                 if (!$this->getRequest('post_id')) {
                     // Throw error if the 'post_id' argument is set but empty.
                     $this->throwError(1, 'post_id');
                     break;
                 }
             }
             $post = $this->getXenAPI()->getPost($this->getRequest('post_id'), array(), $this->getUser());
             if ($post === NULL) {
                 // Could not find the post, throw error.
                 $this->throwError(19, 'post', $this->getRequest('post_id'));
             } else {
                 if (!$this->hasAPIKey() && !$this->getXenAPI()->canViewPost($this->getUser(), $post)) {
                     if (isset($this->grab_as)) {
                         // Post was found but the 'grab_as' user is not permitted to view the post.
                         $this->throwError(20, $this->getUser()->getUsername() . ' does', 'this post');
                     } else {
                         // Post was found but the user is not permitted to view the post.
                         $this->throwError(20, 'You do', 'this post');
                     }
                 } else {
                     if ($this->hasAPIKey() && isset($this->grab_as) && !$this->getXenAPI()->canViewPost($this->getUser(), $post)) {
                         // Post was found but the 'grab_as' user is not permitted to view the thread.
                         $this->throwError(20, $this->getUser()->getUsername() . ' does', 'this post');
                     }
                 }
             }
             // List of fields that are accepted to be edited.
             $edit_fields = array('thread_id', 'message');
             // List of fields that the request should ignore.
             $ignore_fields = array('hash', 'action', 'grab_as');
             // Let's check which fields are set.
             foreach ($this->data as $data_key => $data_item) {
                 if (!in_array($data_key, $ignore_fields) && in_array($data_key, $edit_fields) && $this->checkRequestParameter($data_key, FALSE)) {
                     $edit_data[$data_key] = $data_item;
                 }
             }
             if (count($edit_data) == 0) {
                 // There are no fields set, throw error.
                 $this->throwError(8, $edit_fields);
             } else {
                 if (array_key_exists('thread_id', $edit_data)) {
                     $thread = $this->getXenAPI()->getThread($edit_data['thread_id'], array(), $this->getUser());
                     if ($thread == NULL) {
                         // Could not find the thread, throw error.
                         $this->throwError(19, 'thread', $edit_data['thread_id']);
                     }
                 }
             }
             // Get edit results.
             $edit_results = $this->getXenAPI()->editPost($post, $this->getUser(), $edit_data);
             if (empty($edit_results['error'])) {
                 // Edit was successful, return results.
                 $this->sendResponse($edit_results);
             } else {
                 // The registration failed, process errors.
                 if (is_array($edit_results['errors'])) {
                     // The error message was an array, loop through the messages.
                     $error_keys = array();
                     foreach ($edit_results['errors'] as $error_field => $error) {
                         if (!$error instanceof XenForo_Phrase) {
                             $edit_error = array('error_id' => 1, 'error_key' => 'field_not_recognised', 'error_field' => $error_field, 'error_phrase' => $error);
                             // Throw error message.
                             $this->throwError(self::POST_ERROR, $edit_error, 'editing a post');
                         }
                         // Let's init the edit error array.
                         $edit_error = array('error_id' => $this->getUserErrorID($error->getPhraseName()), 'error_key' => $error->getPhraseName(), 'error_field' => $error_field, 'error_phrase' => $error->render());
                         // Throw error message.
                         $this->throwError(self::POST_ERROR, $edit_error, 'editing a post');
                     }
                 } else {
                     $edit_error = array('error_id' => $edit_results['error'], 'error_key' => 'general_post_edit_error', 'error_phrase' => $edit_results['errors']);
                     // Throw error message.
                     $this->throwError(self::POST_ERROR, $edit_error, 'editing a post');
                 }
             }
         case 'editthread':
             if ($this->hasAPIKey() && !$this->hasRequest('grab_as')) {
                 // The 'grab_as' argument has not been set, throw error.
                 $this->throwError(3, 'grab_as');
             } else {
                 if ($this->hasAPIKey() && !$this->getRequest('grab_as')) {
                     // Throw error if the 'grab_as' argument is set but empty.
                     $this->throwError(1, 'grab_as');
                 }
             }
             if (!$this->hasRequest('thread_id')) {
                 // The 'thread_id' argument has not been set, throw error.
                 $this->throwError(3, 'thread_id');
                 break;
             } else {
                 if (!$this->getRequest('thread_id')) {
                     // Throw error if the 'thread_id' argument is set but empty.
                     $this->throwError(1, 'thread_id');
                     break;
                 }
             }
             $thread = $this->getXenAPI()->getThread($this->getRequest('thread_id'), array(), $this->getUser());
             if ($thread === NULL) {
                 // Could not find the thread, throw error.
                 $this->throwError(19, 'thread', $this->getRequest('thread_id'));
             } else {
                 if (!$this->hasAPIKey() && !$this->getXenAPI()->canViewThread($this->getUser(), $thread)) {
                     if (isset($this->grab_as)) {
                         // Thread was found but the 'grab_as' user is not permitted to view the thread.
                         $this->throwError(20, $this->getUser()->getUsername() . ' does', 'this thread');
                     } else {
                         // Thread was found but the user is not permitted to view the thread.
                         $this->throwError(20, 'You do', 'this thread');
                     }
                 } else {
                     if ($this->hasAPIKey() && isset($this->grab_as) && !$this->getXenAPI()->canViewThread($this->getUser(), $thread)) {
                         // Thread was found but the 'grab_as' user is not permitted to view the thread.
                         $this->throwError(20, $this->getUser()->getUsername() . ' does', 'this thread');
                     }
                 }
             }
             // List of fields that are accepted to be edited.
             $edit_fields = array('node_id', 'title', 'prefix_id', 'discussion_open', 'sticky');
             // TODO: add support for message editing
             // List of fields that the request should ignore.
             $ignore_fields = array('hash', 'action', 'grab_as');
             // Let's check which fields are set.
             foreach ($this->data as $data_key => $data_item) {
                 if (!in_array($data_key, $ignore_fields) && in_array($data_key, $edit_fields) && $this->checkRequestParameter($data_key, FALSE)) {
                     $edit_data[$data_key] = $data_item;
                 }
             }
             if (count($edit_data) == 0) {
                 // There are no fields set, throw error.
                 $this->throwError(8, $edit_fields);
             } else {
                 if (array_key_exists('node_id', $edit_data)) {
                     $node = $this->getXenAPI()->getNode($edit_data['node_id'], array(), $this->getUser());
                     if ($node == NULL) {
                         // Could not find the node, throw error.
                         $this->throwError(19, 'node', $edit_data['node_id']);
                     }
                 }
             }
             // Get edit results.
             $edit_results = $this->getXenAPI()->editThread($thread, $this->getUser(), $edit_data);
             if (empty($edit_results['error'])) {
                 // Edit was successful, return results.
                 $this->sendResponse($edit_results);
             } else {
                 // The registration failed, process errors.
                 if (is_array($edit_results['errors'])) {
                     // The error message was an array, loop through the messages.
                     $error_keys = array();
                     foreach ($edit_results['errors'] as $error_field => $error) {
                         if (!$error instanceof XenForo_Phrase) {
                             $edit_error = array('error_id' => 1, 'error_key' => 'field_not_recognised', 'error_field' => $error_field, 'error_phrase' => $error);
                             // Throw error message.
                             $this->throwError(self::THREAD_ERROR, $edit_error, 'editing a thread');
                         }
                         // Let's init the edit error array.
                         $edit_error = array('error_id' => $this->getUserErrorID($error->getPhraseName()), 'error_key' => $error->getPhraseName(), 'error_field' => $error_field, 'error_phrase' => $error->render());
                         // Throw error message.
                         $this->throwError(self::THREAD_ERROR, $edit_error, 'editing a thread');
                     }
                 } else {
                     $edit_error = array('error_id' => $edit_results['error'], 'error_key' => 'general_thread_edit_error', 'error_phrase' => $edit_results['errors']);
                     // Throw error message.
                     $this->throwError(self::THREAD_ERROR, $edit_error, 'editing a thread');
                 }
             }
         case 'edituser':
             /**
              * Edits the user.
              */
             if (!$this->hasRequest('user')) {
                 // The 'user' argument has not been set, throw error.
                 $this->throwError(3, 'user');
                 break;
             } else {
                 if (!$this->getRequest('user')) {
                     // Throw error if the 'user' argument is set but empty.
                     $this->throwError(1, 'user');
                     break;
                 }
             }
             if ($this->hasRequest('custom_field_identifier')) {
                 if (!$this->getRequest('custom_field_identifier')) {
                     // Throw error if the 'custom_field_identifier' argument is set but empty.
                     $this->throwError(1, 'custom_field_identifier');
                     break;
                 }
                 $user = $this->getXenAPI()->getUser($this->getRequest('user'), array('custom_field' => $this->getRequest('custom_field_identifier')));
             } else {
                 // Get the user object.
                 $user = $this->getXenAPI()->getUser($this->getRequest('user'));
             }
             if (!$user->isRegistered()) {
                 // Requested user was not registered, throw error.
                 $this->throwError(4, 'user', $this->getRequest('user'));
             }
             // Init the edit array.
             $edit_data = array();
             if ($this->hasRequest('group')) {
                 // Request has value.
                 if (!$this->getRequest('group')) {
                     // Throw error if the 'group' argument is set but empty.
                     $this->throwError(1, 'group');
                     break;
                 }
                 $group = $this->getXenAPI()->getGroup($this->getRequest('group'));
                 if (!$group) {
                     $edit_error = array('error_id' => 2, 'error_key' => 'group_not_found', 'error_field' => 'group', 'error_phrase' => 'Could not find group with parameter "' . $this->getRequest('group') . '"');
                     $this->throwError(self::USER_ERROR, $edit_error, 'editing an user');
                 }
                 // Set the group id of the edit.
                 $edit_data['group_id'] = $group['user_group_id'];
             }
             $group_fields = array('add_groups', 'remove_groups');
             foreach ($group_fields as $group_field) {
                 if (!$this->hasRequest($group_field)) {
                     continue;
                 }
                 // Request has value.
                 if (!$this->getRequest($group_field)) {
                     // Throw error if the $group_field argument is set but empty.
                     $this->throwError(1, $group_field);
                 }
                 // Initialize the array.
                 $edit_data[$group_field] = array();
                 // Check if value is an array.
                 if (strpos($this->getRequest($group_field), ',') !== FALSE) {
                     // Value is an array, explode it.
                     $groups = explode(',', $this->getRequest($group_field));
                     // Loop through the group values.
                     foreach ($groups as $group_value) {
                         // Grab the group from the group value.
                         $group = $this->getXenAPI()->getGroup($group_value);
                         // Check if group was found.
                         if (!$group) {
                             // Group was not found, throw error.
                             $edit_error = array('error_id' => 2, 'error_key' => 'group_not_found', 'error_field' => $group_field, 'error_phrase' => 'Could not find group with parameter "' . $group_value . '" in array "' . $this->getRequest('add_group') . '"');
                             $this->throwError(self::USER_ERROR, $edit_error, 'editing an user');
                         }
                         // Add the group_id to the the add_group array.
                         $edit_data[$group_field][] = $group['user_group_id'];
                     }
                 } else {
                     // Grab the group from the group value.
                     $group = $this->getXenAPI()->getGroup($this->getRequest($group_field));
                     // Check if group was found.
                     if (!$group) {
                         // Group was not found, throw error.
                         $edit_error = array('error_id' => 2, 'error_key' => 'group_not_found', 'error_field' => $group_field, 'error_phrase' => 'Could not find group with parameter "' . $this->getRequest($group_field) . '"');
                         $this->throwError(self::USER_ERROR, $edit_error, 'editing an user');
                     }
                     // Add the group_id to the the add_groups array.
                     $edit_data[$group_field][] = $group['user_group_id'];
                 }
             }
             if ($this->hasRequest('custom_fields')) {
                 // Request has value.
                 if (!$this->getRequest('custom_fields')) {
                     // Throw error if the 'custom_fields' argument is set but empty.
                     $this->throwError(1, 'custom_fields');
                     break;
                 }
                 $custom_fields = $this->getCustomArray($this->getRequest('custom_fields'));
                 // Check if we found any valid custom fields, throw error if not.
                 if (count($custom_fields) == 0) {
                     // The custom fields array was empty, throw error.
                     $edit_error = array('error_id' => 5, 'error_key' => 'invalid_custom_fields', 'error_field' => 'custom_fields', 'error_phrase' => 'The custom fields values were invalid, valid values are: ' . 'custom_fields=custom_field1=custom_value1,custom_field2=custom_value2 ' . 'but got: "' . $this->getRequest('custom_fields') . '" instead');
                     $this->throwError(self::USER_ERROR, $edit_error, 'editing an user');
                 }
                 $edit_data['custom_fields'] = $custom_fields;
             }
             // List of fields that are accepted to be edited.
             $edit_fields = array('username', 'password', 'email', 'gender', 'custom_title', 'style_id', 'timezone', 'visible', 'dob_day', 'dob_month', 'dob_year', 'user_state', 'trophy_points');
             // List of fields that the request should ignore.
             $ignore_fields = array('hash', 'action', 'user');
             // Let's check which fields are set.
             foreach ($this->data as $data_key => $data_item) {
                 if (!in_array($data_key, $ignore_fields) && in_array($data_key, $edit_fields) && $this->checkRequestParameter($data_key, FALSE)) {
                     $edit_data[$data_key] = $data_item;
                 }
             }
             if (count($edit_data) == 0) {
                 // There are no fields set, throw error.
                 $this->throwError(8, $edit_fields);
             }
             // Get edit results.
             $edit_results = $this->getXenAPI()->editUser($user, $edit_data);
             if (!empty($edit_results['error'])) {
                 // The registration failed, process errors.
                 if (is_array($edit_results['errors'])) {
                     // The error message was an array, loop through the messages.
                     $error_keys = array();
                     foreach ($edit_results['errors'] as $error_field => $error) {
                         if (!$error instanceof XenForo_Phrase) {
                             $edit_error = array('error_id' => 1, 'error_key' => 'field_not_recognised', 'error_field' => $error_field, 'error_phrase' => $error);
                             $this->throwError(self::USER_ERROR, $edit_error, 'editing an user');
                         }
                         // Let's init the edit error array.
                         $edit_error = array('error_id' => $this->getUserErrorID($error->getPhraseName()), 'error_key' => $error->getPhraseName(), 'error_field' => $error_field, 'error_phrase' => $error->render());
                         $this->throwError(self::USER_ERROR, $edit_error, 'editing an user');
                     }
                 } else {
                     $edit_error = array('error_id' => $edit_results['error'], 'error_key' => 'general_user_edit_error', 'error_phrase' => $edit_results['errors']);
                     $this->throwError(self::USER_ERROR, $edit_error, 'editing an user');
                     // Throw error message.
                 }
             } else {
                 // Edit was successful, return results.
                 $this->sendResponse($edit_results);
             }
             break;
         case 'getactions':
             /**
              * Returns the actions and their permission levels.
              *
              * EXAMPLE:
              *   - api.php?action=getActions
              */
             /*
             
             // TODO: Only show actions depending on what permission level the user is.
             $temp = array();
             foreach ($this->actions as $action => $permission) {
                 $temp[$action] = $permission;
             }
             */
             // Send the response.
             $this->sendResponse($this->actions);
             break;
         case 'getaddon':
             /**
              * Returns the addon information depending on the 'value' argument.
              *
              * NOTE: Only addon ID's can be used for the 'value' parameter.
              *       Addon ID's can be found by using the 'getAddons' action.
              *
              * EXAMPLE:
              *   - api.php?action=getAddon&value=PostRating&hash=USERNAME:HASH
              *   - api.php?action=getAddon&value=PostRating&hash=API_KEY
              */
             if (!$this->hasRequest('value')) {
                 // The 'value' argument has not been set, throw error.
                 $this->throwError(3, 'value');
                 break;
             } else {
                 if (!$this->getRequest('value')) {
                     // Throw error if the 'value' argument is set but empty.
                     $this->throwError(1, 'value');
                     break;
                 }
             }
             $string = $this->getRequest('value');
             // Try to grab the addon from XenForo.
             $addon = $this->getXenAPI()->getAddon($string);
             if (!$addon->isInstalled()) {
                 // Could not find the addon, throw error.
                 $this->throwError(13, $string);
             } else {
                 // Addon was found, send response.
                 $this->sendResponse(Addon::getLimitedData($addon));
             }
             break;
         case 'getaddons':
             /**
              * Returns a list of addons, if a type is not specified or not supported, 
              * default (all) is used instead.
              *
              * Options for the 'type' argument are:
              *   - all:      This is default, and will return all the addons, ignoring if they are installed or not.
              *   - enabled:  Fetches all the addons that are enabled, ignoring the disabled ones.
              *   - disabled: Fetches all the addons that are disabled, ignoring the enabled ones.
              *
              * For more information, see /library/XenForo/Model/Alert.php.
              *
              * EXAMPLES: 
              *   - api.php?action=getAddons&hash=USERNAME:HASH
              *   - api.php?action=getAddons&hash=API_KEY
              *   - api.php?action=getAddons&type=enabled&hash=USERNAME:HASH
              *   - api.php?action=getAddons&type=enabled&hash=API_KEY
              */
             /* 
              * Check if the request has the 'type' argument set, 
              * if it doesn't it uses the default (all).
              */
             if ($this->hasRequest('type')) {
                 if (!$this->getRequest('type')) {
                     // Throw error if the 'type' argument is set but empty.
                     $this->throwError(1, 'type');
                     break;
                 }
                 // Use the value from the 'type' argument to get the alerts.
                 $installed_addons = $this->xenAPI->getAddons($this->getRequest('type'));
             } else {
                 // Use the default type to get the alerts.
                 $installed_addons = $this->xenAPI->getAddons();
             }
             // Create an array for the addons.
             $addons = array();
             // Loop through all the addons and strip out any information that we don't need.
             foreach ($installed_addons as $addon) {
                 $addons[] = Addon::getLimitedData($addon);
             }
             // Send the response.
             $this->sendResponse(array('count' => count($addons), 'addons' => $addons));
             break;
         case 'getalerts':
             /**
              * Grabs the alerts from the specified user, if type is not specified, 
              * default (recent alerts) is used instead.
              * 
              * NOTE: The 'value' argument will only work for the user itself and
              *       not on others users unless the permission argument for the 
              *       'getalerts' action is changed (default permission: private).
              *
              * Options for the 'type' argument are:
              *     - fetchPopupItems: Fetch alerts viewed in the last options:alertsPopupExpiryHours hours.
              *     - fetchRecent:     Fetch alerts viewed in the last options:alertExpiryDays days.
              *     - fetchAll:        Fetch alerts regardless of their view_date.
              *
              * For more information, see /library/XenForo/Model/Alert.php.
              *
              * EXAMPLES: 
              *   - api.php?action=getAlerts&hash=USERNAME:HASH
              *   - api.php?action=getAlerts&type=fetchAll&hash=USERNAME:HASH
              *   - api.php?action=getAlerts&value=USERNAME&hash=USERNAME:HASH
              *   - api.php?action=getAlerts&value=USERNAME&type=fetchAll&hash=USERNAME:HASH
              *   - api.php?action=getAlerts&value=USERNAME&hash=API_KEY
              *   - api.php?action=getAlerts&value=USERNAME&type=fetchAll&hash=API_KEY
              */
             /* 
              * Check if the request has the 'type' argument set, 
              * if it doesn't it uses the default (fetchRecent).
              */
             if ($this->hasRequest('type')) {
                 if (!$this->getRequest('type')) {
                     // Throw error if the 'type' argument is set but empty.
                     $this->throwError(1, 'type');
                     break;
                 }
                 // Use the value from the 'type' argument to get the alerts.
                 $data = $user->getAlerts($this->getRequest('type'));
             } else {
                 // Use the default type to get the alerts.
                 $data = $user->getAlerts();
             }
             // Send the response.
             $this->sendResponse($data);
             break;
         case 'getavatar':
             /**
              * Returns the avatar of the requested user.
              *
              * Options for the 'size' argument are:
              *   - s (Small)
              *   - m (Medium)
              *   - l (Large)
              *
              * NOTE: The default avatar size is 'Medium'.
              * 
              * EXAMPLES: 
              *   - api.php?action=getAvatar&hash=USERNAME:HASH
              *   - api.php?action=getAvatar&size=M&hash=USERNAME:HASH
              *   - api.php?action=getAvatar&value=USERNAME&hash=USERNAME:HASH
              *   - api.php?action=getAvatar&value=USERNAME&size=M&hash=USERNAME:HASH
              *   - api.php?action=getAvatar&value=USERNAME&hash=API_KEY
              *   - api.php?action=getAvatar&value=USERNAME&size=M&hash=API_KEY
              */
             if ($this->hasRequest('size')) {
                 if (!$this->getRequest('size')) {
                     // Throw error if the 'size' argument is set but empty.
                     $this->throwError(1, 'size');
                     break;
                 }
                 // Use the value from the 'size' argument.
                 $size = strtolower($this->getRequest('size'));
                 if (!in_array($size, array('s', 'm', 'l'))) {
                     /**
                      * The value from the 'size' argument was not valid,
                      * use default size (medium) instead.
                      */
                     $size = 'm';
                 }
             } else {
                 // No specific size was requested, use default size (medium):
                 $size = 'm';
             }
             // Send the response.
             $this->sendResponse(array('avatar' => $user->getAvatar($size)));
             break;
         case 'getconversation':
             if (!$this->hasRequest('conversation_id')) {
                 // The 'conversation_id' argument has not been set, throw error.
                 $this->throwError(3, 'conversation_id');
                 break;
             } else {
                 if (!$this->getRequest('conversation_id')) {
                     // Throw error if the 'conversation_id' argument is set but empty.
                     $this->throwError(1, 'conversation_id');
                     break;
                 }
             }
             // Try to grab the thread from XenForo.
             $conversation = $this->getXenAPI()->getConversation($this->getRequest('conversation_id'), $user, array('join' => XenForo_Model_Conversation::FETCH_FIRST_MESSAGE));
             if ($conversation == NULL) {
                 // Could not find the conversation, throw error.
                 $this->throwError(19, 'conversation', $this->getRequest('conversation_id'));
             }
             // Send the response.
             $this->sendResponse($conversation);
         case 'getgroup':
             /**
              * Returns the group information depending on the 'value' argument.
              *
              * NOTE: Only group titles, user titles and group ID's can be used for the 'value' parameter.
              *
              * EXAMPLE:
              *   - api.php?action=getGroup&value=1
              *   - api.php?action=getGroup&value=Guest
              */
             if (!$this->hasRequest('value')) {
                 // The 'value' argument has not been set, throw error.
                 $this->throwError(3, 'value');
                 break;
             } else {
                 if (!$this->getRequest('value')) {
                     // Throw error if the 'value' argument is set but empty.
                     $this->throwError(1, 'value');
                     break;
                 }
             }
             $string = $this->getRequest('value');
             // Get the group from XenForo.
             $group = $this->getXenAPI()->getGroup($string);
             if (!$group) {
                 // Could not find any groups, throw error.
                 $this->throwError(4, 'group', $string);
             } else {
                 // Group was found, send response.
                 $this->sendResponse($group);
             }
             break;
         case 'getconversations':
             /**
              * Grabs the conversations from the specified user.
              * 
              * NOTE: The 'value' argument will only work for the user itself and
              *       not on others users unless the permission argument for the 
              *       'getconversations' action is changed (default permission: private).
              *
              * EXAMPLES: 
              *   - api.php?action=getConversations&hash=USERNAME:HASH
              *   - api.php?action=getConversations&value=USERNAME&hash=USERNAME:HASH
              *   - api.php?action=getConversations&value=USERNAME&hash=API_KEY
              */
             // Init variables.
             $conditions = array();
             $this->setLimit(10);
             $fetch_options = array('limit' => $this->limit, 'join' => XenForo_Model_Conversation::FETCH_FIRST_MESSAGE);
             // Grab the conversations.
             $conversations = $this->getXenAPI()->getConversations($user, $conditions, $fetch_options);
             // Send the response.
             $this->sendResponse(array('count' => count($conversations), 'conversations' => $conversations));
             break;
         case 'getgroup':
             /**
              * Returns the group information depending on the 'value' argument.
              *
              * NOTE: Only group titles, user titles and group ID's can be used for the 'value' parameter.
              *
              * EXAMPLE:
              *   - api.php?action=getGroup&value=1
              *   - api.php?action=getGroup&value=Guest
              */
             if (!$this->hasRequest('value')) {
                 // The 'value' argument has not been set, throw error.
                 $this->throwError(3, 'value');
                 break;
             } else {
                 if (!$this->getRequest('value')) {
                     // Throw error if the 'value' argument is set but empty.
                     $this->throwError(1, 'value');
                     break;
                 }
             }
             $string = $this->getRequest('value');
             // Get the group from XenForo.
             $group = $this->getXenAPI()->getGroup($string);
             if (!$group) {
                 // Could not find any groups, throw error.
                 $this->throwError(4, 'group', $string);
             } else {
                 // Group was found, send response.
                 $this->sendResponse($group);
             }
             break;
         case 'getnode':
             /**
              * Returns the node information depending on the 'value' argument.
              *
              * NOTE: Only node ID's can be used for the 'value' parameter.
              *       Node ID's can be found by using the 'getNodes' action.
              *
              *       The user needs permission to see the thread if the request is
              *       using a user hash and not an API key.
              *
              * EXAMPLE:
              *   - api.php?action=getNode&value=4&hash=USERNAME:HASH
              *   - api.php?action=getNode&value=4&hash=API_KEY
              */
             if (!$this->hasRequest('value')) {
                 // The 'value' argument has not been set, throw error.
                 $this->throwError(3, 'value');
                 break;
             } else {
                 if (!$this->getRequest('value')) {
                     // Throw error if the 'value' argument is set but empty.
                     $this->throwError(1, 'value');
                     break;
                 }
             }
             $string = $this->getRequest('value');
             // Try to grab the node from XenForo.
             $node = $this->getXenAPI()->getNode($string);
             if ($node == NULL) {
                 // Could not find the node, throw error.
                 $this->throwError(19, 'node', $string);
             } else {
                 if (!$this->hasAPIKey() && !$this->getXenAPI()->canViewNode($this->getUser(), $node)) {
                     if (isset($this->grab_as)) {
                         // Thread was found but the 'grab_as' user is not permitted to view the node.
                         $this->throwError(20, $this->getUser()->getUsername() . ' does', 'this node');
                     } else {
                         // Thread was found but the user is not permitted to view the node.
                         $this->throwError(20, 'You do', 'this node');
                     }
                 } else {
                     if ($this->hasAPIKey() && isset($this->grab_as) && !$this->getXenAPI()->canViewNode($this->getUser(), $node)) {
                         // Thread was found but the 'grab_as' user is not permitted to view the node.
                         $this->throwError(20, $this->getUser()->getUsername() . ' does', 'this node');
                     } else {
                         // Thread was found, and the request was permitted.
                         $this->sendResponse($node);
                     }
                 }
             }
             break;
         case 'getnodes':
             /**
              * Returns a list of nodes.
              *
              * EXAMPLES: 
              *   - api.php?action=getNodes&hash=USERNAME:HASH
              *   - api.php?action=getNodes&hash=API_KEY
              */
             // Init variables.
             $this->setLimit(10);
             $fetch_options = array('limit' => $this->limit);
             // Check if request has node_type.
             if ($this->hasRequest('node_type')) {
                 if (!$this->getRequest('node_type')) {
                     // Throw error if the 'node_type' argument is set but empty.
                     $this->throwError(1, 'node_type');
                 }
                 // Set the node_type.
                 $node_type = strtolower($this->getRequest('node_type'));
                 // Check if the node type that is set exists.
                 if (!in_array($node_type, $this->getXenAPI()->getNodeTypes()) && $node_type != 'all') {
                     // Node type could not be found in the node type list, throw error.
                     $this->throwError(23, $this->getRequest('node_type'), implode(', ', $this->getXenAPI()->getNodeTypes()));
                 }
             } else {
                 $node_type = 'all';
             }
             // Get the nodes.
             $nodes = $this->getXenAPI()->getNodes($node_type, $fetch_options, $this->getUser());
             // Send the response.
             $this->sendResponse(array('count' => count($nodes), 'nodes' => $nodes));
         case 'getpost':
             /**
              * Returns the post information depending on the 'value' argument.
              *
              * NOTE: Only post ID's can be used for the 'value' parameter.
              *       Post ID's can be found by using the 'getPosts' action.
              *
              *       The user needs permission to see the thread if the request is
              *       using a user hash and not an API key.
              *
              * EXAMPLE:
              *   - api.php?action=getPost&value=820&hash=USERNAME:HASH
              *   - api.php?action=getPost&value=820&hash=API_KEY
              */
             if (!$this->hasRequest('value')) {
                 // The 'value' argument has not been set, throw error.
                 $this->throwError(3, 'value');
                 break;
             } else {
                 if (!$this->getRequest('value')) {
                     // Throw error if the 'value' argument is set but empty.
                     $this->throwError(1, 'value');
                     break;
                 }
             }
             $string = $this->getRequest('value');
             // Try to grab the post from XenForo.
             $post = $this->getXenAPI()->getPost($string, array('join' => XenForo_Model_Post::FETCH_FORUM));
             if ($post == NULL) {
                 // Could not find the post, throw error.
                 $this->throwError(19, 'post', $string);
             } else {
                 if (!$this->hasAPIKey() && !$this->getXenAPI()->canViewPost($this->getUser(), $post)) {
                     if (isset($this->grab_as)) {
                         // Post was found but the 'grab_as' user is not permitted to view the post.
                         $this->throwError(20, $this->getUser()->getUsername() . ' does', 'this post');
                     } else {
                         // Post was found but the user is not permitted to view the post.
                         $this->throwError(20, 'You do', 'this post');
                     }
                 } else {
                     if ($this->hasAPIKey() && isset($this->grab_as) && !$this->getXenAPI()->canViewPost($this->getUser(), $post)) {
                         // Post was found but the 'grab_as' user is not permitted to view the post.
                         $this->throwError(20, $this->getUser()->getUsername() . ' does', 'this post');
                     } else {
                         // Post was found, and the request was permitted.
                         $this->sendResponse($post);
                     }
                 }
             }
             break;
         case 'getposts':
             /**
              * Returns a list of posts.
              *
              * NOTE: Only usernames and user ID's can be used for the 'author' parameter.
              *
              * EXAMPLES: 
              *   - api.php?action=getPosts&hash=USERNAME:HASH
              *   - api.php?action=getPosts&hash=API_KEY
              *   - api.php?action=getPosts&author=Contex&hash=USERNAME:HASH
              *   - api.php?action=getPosts&author=1&hash=API_KEY
              */
             // Init variables.
             $conditions = array();
             $this->setLimit(10);
             $fetch_options = array('limit' => $this->limit);
             // Check if request has author.
             if ($this->hasRequest('author')) {
                 if (!$this->getRequest('author')) {
                     // Throw error if the 'author' argument is set but empty.
                     $this->throwError(1, 'author');
                     break;
                 }
                 // Grab the user object of the author.
                 $user = $this->xenAPI->getUser($this->getRequest('author'));
                 if (!$user->isRegistered()) {
                     // Throw error if the 'author' user is not registered.
                     $this->throwError(4, 'user', $this->getRequest('author'));
                     break;
                 }
                 // Add the user ID to the query conditions.
                 $conditions['user_id'] = $user->getID();
                 unset($user);
             }
             // Check if request has node id.
             if ($this->hasRequest('node_id')) {
                 if (!$this->getRequest('node_id') && (is_numeric($this->getRequest('node_id')) && $this->getRequest('node_id') != 0)) {
                     // Throw error if the 'node_id' argument is set but empty.
                     $this->throwError(1, 'node_id');
                 } else {
                     if (!is_numeric($this->getRequest('node_id'))) {
                         // Throw error if the 'node_id' argument is set but not a number.
                         $this->throwError(21, 'node_id');
                     }
                 }
                 if (!$this->xenAPI->getNode($this->getRequest('node_id'))) {
                     // Could not find any nodes, throw error.
                     $this->throwError(4, 'node', $this->getRequest('node_id'));
                 }
                 // Add the node ID to the query conditions.
                 $conditions['node_id'] = $this->getRequest('node_id');
             }
             // Check if request has thread id.
             if ($this->hasRequest('thread_id')) {
                 if (!$this->getRequest('thread_id') && (is_numeric($this->getRequest('thread_id')) && $this->getRequest('thread_id') != 0)) {
                     // Throw error if the 'thread_id' argument is set but empty.
                     $this->throwError(1, 'thread_id');
                 } else {
                     if (!is_numeric($this->getRequest('thread_id'))) {
                         // Throw error if the 'thread_id' argument is set but not a number.
                         $this->throwError(21, 'thread_id');
                     }
                 }
                 if (!$this->xenAPI->getThread($this->getRequest('thread_id'))) {
                     // Could not find any threads, throw error.
                     $this->throwError(4, 'thread_id', $this->getRequest('thread_id'));
                 }
                 // Add the node ID to the query conditions.
                 $conditions['thread_id'] = $this->getRequest('thread_id');
             }
             // Check if the order by argument is set.
             $order_by_field = $this->checkOrderBy(array('post_id', 'thread_id', 'user_id', 'username', 'post_date', 'attach_count', 'likes', 'node_id'));
             // Add the order by options to the fetch options.
             if ($this->hasRequest('order_by')) {
                 $fetch_options['order'] = $order_by_field;
                 $fetch_options['orderDirection'] = $this->order;
             }
             // Get the posts.
             $posts = $this->getXenAPI()->getPosts($conditions, $fetch_options, $this->getUser());
             // Send the response.
             $this->sendResponse(array('count' => count($posts), 'posts' => $posts));
         case 'getprofilepost':
             /**
              * Returns the profile post information depending on the 'value' argument.
              *
              * NOTE: Only profile post ID's can be used for the 'value' parameter.
              *       Profile post ID's can be found by using the 'getProfilePosts' action.
              *
              *       The user needs permission to see the profile post if the request is
              *       using a user hash and not an API key.
              *
              * EXAMPLE:
              *   - api.php?action=getProfilePost&value=820&hash=USERNAME:HASH
              *   - api.php?action=getProfilePost&value=820&hash=API_KEY
              */
             if (!$this->hasRequest('value')) {
                 // The 'value' argument has not been set, throw error.
                 $this->throwError(3, 'value');
                 break;
             } else {
                 if (!$this->getRequest('value')) {
                     // Throw error if the 'value' argument is set but empty.
                     $this->throwError(1, 'value');
                     break;
                 }
             }
             $string = $this->getRequest('value');
             // Try to grab the profile post from XenForo.
             $profile_post = $this->getXenAPI()->getProfilePost($string);
             if ($profile_post == NULL) {
                 // Could not find the profile post, throw error.
                 $this->throwError(19, 'profile post', $string);
             } else {
                 if (!$this->hasAPIKey() && !$this->getXenAPI()->canViewProfilePost($this->getUser(), $profile_post)) {
                     if (isset($this->grab_as)) {
                         // Thread was found but the 'grab_as' user is not permitted to view the thread.
                         $this->throwError(20, $this->getUser()->getUsername() . ' does', 'this profile post');
                     } else {
                         // Thread was found but the user is not permitted to view the profile post.
                         $this->throwError(20, 'You do', 'this profile post');
                     }
                 } else {
                     if ($this->hasAPIKey() && isset($this->grab_as) && !$this->getXenAPI()->canViewProfilePost($this->getUser(), $profile_post)) {
                         // Thread was found but the 'grab_as' user is not permitted to view the profile post.
                         $this->throwError(20, $this->getUser()->getUsername() . ' does', 'this profile post');
                     } else {
                         // Post was found, and the request was permitted.
                         $this->sendResponse($profile_post);
                     }
                 }
             }
             break;
         case 'getprofileposts':
             /**
              * Returns a list of profile posts.
              *
              * NOTE: Only usernames and user ID's can be used for the 'author' parameter.
              *
              * EXAMPLES: 
              *   - api.php?action=getProfilePosts&hash=USERNAME:HASH
              *   - api.php?action=getProfilePosts&hash=API_KEY
              *   - api.php?action=getProfilePosts&author=Contex&hash=USERNAME:HASH
              *   - api.php?action=getProfilePosts&author=1&hash=API_KEY
              */
             // Init variables.
             $conditions = array();
             $this->setLimit(10);
             $fetch_options = array('limit' => $this->limit);
             // Check if request has author.
             if ($this->hasRequest('author')) {
                 if (!$this->getRequest('author')) {
                     // Throw error if the 'author' argument is set but empty.
                     $this->throwError(1, 'author');
                     break;
                 }
                 // Grab the user object of the author.
                 $user = $this->xenAPI->getUser($this->getRequest('author'));
                 if (!$user->isRegistered()) {
                     // Throw error if the 'author' user is not registered.
                     $this->throwError(4, 'user', $this->getRequest('author'));
                     break;
                 }
                 // Add the user ID to the query conditions.
                 $conditions['author_id'] = $user->getID();
                 unset($user);
             }
             // Check if request has profile user.
             if ($this->hasRequest('profile')) {
                 if (!$this->getRequest('profile')) {
                     // Throw error if the 'profile' argument is set but empty.
                     $this->throwError(1, 'profile');
                     break;
                 }
                 // Grab the user object of the profile.
                 $user = $this->xenAPI->getUser($this->getRequest('profile'));
                 if (!$user->isRegistered()) {
                     // Throw error if the 'author' user is not registered.
                     $this->throwError(4, 'user', $this->getRequest('profile'));
                     break;
                 }
                 // Add the user ID to the query conditions.
                 $conditions['profile_id'] = $user->getID();
                 unset($user);
             }
             // Check if the order by argument is set.
             $order_by_field = $this->checkOrderBy(array('profile_post_id', 'profile_user_id', 'user_id', 'username', 'post_date', 'attach_count', 'likes', 'comment_count', 'first_comment_date', 'last_comment_date'));
             // Add the order by options to the fetch options.
             if ($this->hasRequest('order_by')) {
                 $fetch_options['order'] = $order_by_field;
                 $fetch_options['orderDirection'] = $this->order;
             }
             // Get the profile posts.
             $profile_posts = $this->getXenAPI()->getProfilePosts($conditions, $fetch_options, $this->getUser());
             // Send the response.
             $this->sendResponse(array('count' => count($profile_posts), 'profile_posts' => $profile_posts));
         case 'getresource':
             /**
              * Returns the resource information depending on the 'value' argument.
              *
              * NOTE: Only resource ID's can be used for the 'value' parameter.
              *       Resource ID's can be found by using the 'getResources' action.
              *
              * EXAMPLE:
              *   - api.php?action=getResource&value=1&hash=USERNAME:HASH
              *   - api.php?action=getResource&value=1&hash=API_KEY
              */
             /* 
              * Check the resource addon is installed
              */
             if (!$this->getXenAPI()->getModels()->hasModel('resource')) {
                 $this->throwError(16, 'resource');
                 break;
             }
             $fetchOptions = array();
             /* 
              * Check if the request has the 'grab_description' argument set.
              */
             if ($this->hasRequest('grab_description')) {
                 // Grab resources with description
                 $fetchOptions['join'] = XenResource_Model_Resource::FETCH_DESCRIPTION;
             }
             if (!$this->hasRequest('value')) {
                 // The 'value' argument has not been set, throw error.
                 $this->throwError(3, 'value');
                 break;
             } else {
                 if (!$this->getRequest('value')) {
                     // Throw error if the 'value' argument is set but empty.
                     $this->throwError(1, 'value');
                     break;
                 }
             }
             $string = $this->getRequest('value');
             // Try to grab the addon from XenForo.
             $resource = $this->getXenAPI()->getResource($string, $fetchOptions);
             if (!$resource->isValid()) {
                 // Could not find the resource, throw error.
                 $this->throwError(15, $string);
             } else {
                 // Resource was found, send response.
                 $this->sendResponse(Resource::getLimitedData($resource));
             }
             break;
         case 'getresources':
             /**
              * Returns a list of resources, either all the resources, 
              * or just the resources created by an author.
              *
              * NOTE: Only usernames and user ID's can be used for the 'author' parameter.
              * NOTE: Only resource category ID's can be used for the 'category_id' parameter.
              *
              * EXAMPLES: 
              *   - api.php?action=getResources&hash=USERNAME:HASH
              *   - api.php?action=getResources&hash=API_KEY
              *   - api.php?action=getResources&author=Contex&hash=USERNAME:HASH
              *   - api.php?action=getResources&author=1&hash=API_KEY
              *   - api.php?action=getResources&author=Contex&category_id=1&hash=USERNAME:HASH
              *   - api.php?action=getResources&author=1&category_id=2&hash=API_KEY
              */
             /* 
              * Check the resource addon is installed
              */
             if (!$this->getXenAPI()->getModels()->hasModel('resource')) {
                 $this->throwError(16, 'resource');
                 break;
             }
             $conditions = array();
             $fetchOptions = array();
             /* 
              * Check if the request has the 'grab_description' argument set.
              */
             if ($this->hasRequest('grab_description')) {
                 // Grab resources with description
                 $fetchOptions['join'] = XenResource_Model_Resource::FETCH_DESCRIPTION;
             }
             /* 
              * Check if the request has the 'category_id' argument set.
              */
             if ($this->hasRequest('category_id')) {
                 if (!$this->getRequest('category_id')) {
                     // Throw error if the 'category_id' argument is set but empty.
                     $this->throwError(1, 'category_id');
                     break;
                 }
                 // Use the value from the 'category_id' argument to set the variables.
                 $conditions['resource_category_id'] = $this->getRequest('category_id');
             }
             /* 
              * Check if the request has the 'author' argument set, 
              * if it doesn't it uses the default (all).
              */
             if ($this->hasRequest('author')) {
                 if (!$this->getRequest('author')) {
                     // Throw error if the 'author' argument is set but empty.
                     $this->throwError(1, 'author');
                     break;
                 }
                 // Create a user variable with the 'author' argument.
                 $user = $this->xenAPI->getUser($this->getRequest('author'));
                 if (!$user->isRegistered()) {
                     // Throw error if the 'author' user is not registered.
                     $this->throwError(4, 'user', $this->getRequest('author'));
                     break;
                 }
                 // Use the value from the 'author' argument to set the variables.
                 $conditions['user_id'] = $user->getID();
             }
             $resources_list = $this->getXenAPI()->getResources($conditions, $fetchOptions);
             // Create an array for the resources.
             $resources = array();
             // Loop through all the resources and strip out any information that we don't need.
             foreach ($resources_list as $resource) {
                 $resources[] = Resource::getLimitedData($resource);
             }
             // Send the response.
             $this->sendResponse(array('count' => count($resources), 'resources' => $resources));
         case 'getresourcecategories':
             /**
              * Returns a list of resource categories
              *
              * EXAMPLES: 
              *   - api.php?action=getResourceCategories&hash=USERNAME:HASH
              *   - api.php?action=getResourceCategories&hash=API_KEY
              */
             /* 
              * Check the resource addon is installed
              */
             if (!$this->getXenAPI()->getModels()->hasModel('resource')) {
                 $this->throwError(16, 'resource');
                 break;
             }
             // Grab the resource categories.
             $resource_categories = $this->getXenAPI()->getResourceCategories();
             // Send the response.
             $this->sendResponse(array('count' => count($resource_categories), 'categories' => $resource_categories));
         case 'getstats':
             /**
              * Returns a summary of stats.
              *
              * NOTE: "include_deleted" will count the deleted posts/threads as well
              *
              * EXAMPLE:
              *   - api.php?action=getStats
              *   - api.php?action=getStats&include_deleted
              */
             $latest_user = $this->xenAPI->getLatestUser();
             if (!$this->hasRequest('include_deleted')) {
                 $include_deleted = TRUE;
             } else {
                 $include_deleted = FALSE;
             }
             $this->sendResponse(array('threads' => $this->xenAPI->getStatsItem('threads', $include_deleted), 'posts' => $this->xenAPI->getStatsItem('posts', $include_deleted), 'conversations' => $this->xenAPI->getStatsItem('conversations', $include_deleted), 'conversations_messages' => $this->xenAPI->getStatsItem('conversations_messages', $include_deleted), 'members' => $this->xenAPI->getStatsItem('users', $include_deleted), 'latest_member' => array('user_id' => $latest_user->getID(), 'username' => $latest_user->getUsername()), 'registrations_today' => $this->xenAPI->getStatsItem('registrations_today', $include_deleted), 'threads_today' => $this->xenAPI->getStatsItem('threads_today', $include_deleted), 'posts_today' => $this->xenAPI->getStatsItem('posts_today', $include_deleted), 'users_online' => $this->xenAPI->getUsersOnlineCount($this->getUser())));
             break;
         case 'getthread':
             /**
              * Returns the thread information depending on the 'value' argument.
              *
              * NOTE: Only thread ID's can be used for the 'value' parameter.
              *       Thread ID's can be found by using the 'getThreads' action.
              *
              *       The user needs permission to see the thread if the request is
              *       using a user hash and not an API key.
              *
              * EXAMPLE:
              *   - api.php?action=getThread&value=820&hash=USERNAME:HASH
              *   - api.php?action=getThread&value=820&hash=API_KEY
              */
             $fetchOptions = array();
             if (!$this->hasRequest('value')) {
                 // The 'value' argument has not been set, throw error.
                 $this->throwError(3, 'value');
                 break;
             } else {
                 if (!$this->getRequest('value')) {
                     // Throw error if the 'value' argument is set but empty.
                     $this->throwError(1, 'value');
                     break;
                 }
             }
             $string = $this->getRequest('value');
             // Check if request has grab_content.
             if ($this->hasRequest('grab_content')) {
                 $fetchOptions['grab_content'] = TRUE;
                 // Check if request has content_limit.
                 if ($this->hasRequest('content_limit')) {
                     if (!$this->getRequest('content_limit') && (is_numeric($this->getRequest('content_limit')) && $this->getRequest('content_limit') != 0)) {
                         // Throw error if the 'content_limit' argument is set but empty.
                         $this->throwError(1, 'content_limit');
                         break;
                     } else {
                         if (!is_numeric($this->getRequest('content_limit'))) {
                             // Throw error if the 'content_limit' argument is set but not a number.
                             $this->throwError(21, 'content_limit');
                         }
                     }
                     $fetchOptions['content_limit'] = $this->getRequest('content_limit');
                 }
             }
             // Try to grab the thread from XenForo.
             $thread = $this->getXenAPI()->getThread($string, $fetchOptions, $this->getUser());
             if ($thread === NULL) {
                 // Could not find the thread, throw error.
                 $this->throwError(19, 'thread', $string);
             } else {
                 if (!$this->hasAPIKey() && !$this->getXenAPI()->canViewThread($this->getUser(), $thread)) {
                     if (isset($this->grab_as)) {
                         // Thread was found but the 'grab_as' user is not permitted to view the thread.
                         $this->throwError(20, $this->getUser()->getUsername() . ' does', 'this thread');
                     } else {
                         // Thread was found but the user is not permitted to view the thread.
                         $this->throwError(20, 'You do', 'this thread');
                     }
                 } else {
                     if ($this->hasAPIKey() && isset($this->grab_as) && !$this->getXenAPI()->canViewThread($this->getUser(), $thread)) {
                         // Thread was found but the 'grab_as' user is not permitted to view the thread.
                         $this->throwError(20, $this->getUser()->getUsername() . ' does', 'this thread');
                     } else {
                         // Thread was found, and the request was permitted.
                         $this->sendResponse($thread);
                     }
                 }
             }
             break;
         case 'getthreads':
             /**
              * Returns a list of threads.
              *
              * NOTE: Only usernames and user ID's can be used for the 'author' parameter.
              *
              * EXAMPLES: 
              *   - api.php?action=getThreads&hash=USERNAME:HASH
              *   - api.php?action=getThreads&hash=API_KEY
              *   - api.php?action=getThreads&author=Contex&hash=USERNAME:HASH
              *   - api.php?action=getThreads&author=1&hash=API_KEY
              */
             // Init variables.
             $conditions = array();
             $this->setLimit(10);
             $fetch_options = array('limit' => $this->limit);
             // Check if request has author.
             if ($this->hasRequest('author')) {
                 if (!$this->getRequest('author')) {
                     // Throw error if the 'author' argument is set but empty.
                     $this->throwError(1, 'author');
                     break;
                 }
                 // Grab the user object of the author.
                 $user = $this->xenAPI->getUser($this->getRequest('author'));
                 if (!$user->isRegistered()) {
                     // Throw error if the 'author' user is not registered.
                     $this->throwError(4, 'user', $this->getRequest('author'));
                     break;
                 }
                 // Add the user ID to the query conditions.
                 $conditions['user_id'] = $user->getID();
                 unset($user);
             }
             // Check if request has author.
             if ($this->hasRequest('node_id')) {
                 if (!$this->getRequest('node_id') && (is_numeric($this->getRequest('node_id')) && $this->getRequest('node_id') != 0)) {
                     // Throw error if the 'node_id' argument is set but empty.
                     $this->throwError(1, 'node_id');
                 } else {
                     if (!is_numeric($this->getRequest('node_id'))) {
                         // Throw error if the 'limit' argument is set but not a number.
                         $this->throwError(21, 'node_id');
                     }
                 }
                 if (!$this->xenAPI->getNode($this->getRequest('node_id'))) {
                     // Could not find any nodes, throw error.
                     $this->throwError(4, 'node', $this->getRequest('node_id'));
                 }
                 // Add the node ID to the query conditions.
                 $conditions['node_id'] = $this->getRequest('node_id');
             }
             // Check if request has grab_content.
             if ($this->hasRequest('grab_content')) {
                 $fetch_options['grab_content'] = TRUE;
                 // Check if request has content_limit.
                 if ($this->hasRequest('content_limit')) {
                     if (!$this->getRequest('content_limit') && (is_numeric($this->getRequest('content_limit')) && $this->getRequest('content_limit') != 0)) {
                         // Throw error if the 'content_limit' argument is set but empty.
                         $this->throwError(1, 'content_limit');
                         break;
                     } else {
                         if (!is_numeric($this->getRequest('content_limit'))) {
                             // Throw error if the 'content_limit' argument is set but not a number.
                             $this->throwError(21, 'content_limit');
                         }
                     }
                     $fetch_options['content_limit'] = $this->getRequest('content_limit');
                 }
             }
             // Check if the order by argument is set.
             $order_by_field = $this->checkOrderBy(array('title', 'post_date', 'view_count', 'reply_count', 'first_post_likes', 'last_post_date'));
             // Add the order by options to the fetch options.
             if ($this->hasRequest('order_by')) {
                 $fetch_options['order'] = $order_by_field;
                 $fetch_options['orderDirection'] = $this->order;
             }
             // Get the threads.
             $threads = $this->getXenAPI()->getThreads($conditions, $fetch_options, $this->getUser());
             // Send the response.
             $this->sendResponse(array('count' => count($threads), 'threads' => $threads));
         case 'getuser':
             /**
              * Grabs and returns an user object.
              * 
              * EXAMPLES: 
              *   - api.php?action=getUser&hash=USERNAME:HASH
              *   - api.php?action=getUser&value=USERNAME&hash=USERNAME:HASH
              *   - api.php?action=getUser&value=USERNAME&hash=API_KEY
              */
             $data = $user->getData();
             /*
              * Run through an additional permission check if the request is
              * not using an API key, unset some variables depending on the 
              * user level.
              */
             if (!$this->hasAPIKey()) {
                 // Unset variables since the API key isn't used.
                 if (isset($data['style_id'])) {
                     unset($data['style_id']);
                 }
                 if (isset($data['display_style_group_id'])) {
                     unset($data['display_style_group_id']);
                 }
                 if (isset($data['permission_combination_id'])) {
                     unset($data['permission_combination_id']);
                 }
                 if (!$this->getUser()->isAdmin()) {
                     // Unset variables if user is not an admin.
                     if (isset($data['is_banned'])) {
                         unset($data['is_banned']);
                     }
                 }
                 if (!$this->getUser()->isModerator() && $this->getUser()->getID() != $user->getID()) {
                     // Unset variables if user is not a moderator.
                     if (isset($data['user_state'])) {
                         unset($data['user_state']);
                     }
                     if (isset($data['visible'])) {
                         unset($data['visible']);
                     }
                     if (isset($data['email'])) {
                         unset($data['email']);
                     }
                     if (isset($data['custom_fields'])) {
                         unset($data['custom_fields']);
                     }
                 }
                 if ($this->getUser()->getID() != $user->getID()) {
                     // Unset variables if user does not equal the requested user by the 'value' argument.
                     if (isset($data['language_id'])) {
                         unset($data['language_id']);
                     }
                     if (isset($data['message_count'])) {
                         unset($data['message_count']);
                     }
                     if (isset($data['conversations_unread'])) {
                         unset($data['conversations_unread']);
                     }
                     if (isset($data['alerts_unread'])) {
                         unset($data['alerts_unread']);
                     }
                 }
             }
             // Send the response.
             $this->sendResponse($data);
             break;
         case 'getusers':
             /**
              * Searches through the usernames depending on the input.
              *
              * NOTE: Asterisk (*) can be used as a wildcard.
              *
              * EXAMPLE:
              *   - api.php?action=getUsers&value=Contex
              *   - api.php?action=getUsers&value=Cont*
              *   - api.php?action=getUsers&value=C*
              */
             if ($this->hasRequest('value')) {
                 // Request has value.
                 if (!$this->getRequest('value')) {
                     // Throw error if the 'value' argument is set but empty.
                     $this->throwError(1, 'value');
                     break;
                 }
                 // Replace the wildcard with '%' for the SQL query.
                 $string = str_replace('*', '%', $this->getRequest('value'));
             } else {
                 if (!$this->hasRequest('order_by')) {
                     // Nor the 'value' argument or the 'order_by' argument has been set, throw error.
                     $this->throwError(3, 'value');
                     break;
                 }
             }
             // Check if the order by argument is set.
             $order_by_field = $this->checkOrderBy(array('user_id', 'message_count', 'conversations_unread', 'register_date', 'last_activity', 'trophy_points', 'alerts_unread', 'like_count'));
             // Perform the SQL query and grab all the usernames and user id's.
             $results = $this->xenAPI->getDatabase()->fetchAll("SELECT `user_id`, `username`" . ($this->hasRequest('order_by') ? ", `{$order_by_field}`" : '') . " FROM `xf_user`" . ($this->hasRequest('value') ? " WHERE `username` LIKE '{$string}'" : '') . ($this->hasRequest('order_by') ? " ORDER BY `{$order_by_field}` " . $this->order : '') . ($this->limit > 0 ? ' LIMIT ' . $this->limit : ''));
             // Send the response.
             $this->sendResponse($results);
             break;
         case 'getuserupgrade':
             /**
              * TODO
              * 
              * EXAMPLES: 
              */
             if (!$this->hasRequest('id')) {
                 // The 'id' argument has not been set, throw error.
                 $this->throwError(3, 'id');
                 break;
             } else {
                 if (!$this->getRequest('id')) {
                     // Throw error if the 'id' argument is set but empty.
                     $this->throwError(1, 'id');
                     break;
                 }
             }
             $user_upgrade = $this->getXenAPI()->getUserUpgrade($this->getRequest('id'));
             if (!$user_upgrade) {
                 $this->throwError(4, 'user upgrade', $this->getRequest('id'));
                 break;
             }
             // Send the response.
             $this->sendResponse($user_upgrade);
         case 'getuserupgrades':
             /**
              * TODO
              * 
              * EXAMPLES: 
              */
             $user = NULL;
             if ($this->hasRequest('user')) {
                 if (!$this->getRequest('user')) {
                     // Throw error if the 'user' argument is set but empty.
                     $this->throwError(1, 'user');
                 }
                 $user = $this->getXenAPI()->getUser($this->getRequest('user'));
                 if (!$user->isRegistered()) {
                     // Requested user was not registered, throw error.
                     $this->throwError(4, 'user', $this->getRequest('user'));
                 }
             }
             $user_upgrades = $this->getXenAPI()->getUserUpgrades($user);
             if (!$user_upgrades && $this->hasRequest('user')) {
                 $this->throwError(4, 'user upgrades', $this->getRequest('user'));
             }
             // Send the response.
             $this->sendResponse($user_upgrades);
         case 'downgradeuser':
             if (!$this->hasRequest('user')) {
                 // The 'user' argument has not been set, throw error.
                 $this->throwError(3, 'user');
             } else {
                 if (!$this->getRequest('user')) {
                     // Throw error if the 'user' argument is set but empty.
                     $this->throwError(1, 'user');
                 }
             }
             $user = $this->getXenAPI()->getUser($this->getRequest('user'));
             if (!$user->isRegistered()) {
                 // Requested user was not registered, throw error.
                 $this->throwError(4, 'user', $this->getRequest('user'));
             }
             if (!$this->hasRequest('upgrade_id')) {
                 // The 'upgrade_id' argument has not been set, throw error.
                 $this->throwError(3, 'upgrade_id');
             } else {
                 if (!$this->getRequest('upgrade_id')) {
                     // Throw error if the 'upgrade_id' argument is set but empty.
                     $this->throwError(1, 'upgrade_id');
                 }
             }
             $user_upgrades = $this->getXenAPI()->getUserUpgrades($user);
             if (!$user_upgrades && $this->hasRequest('user')) {
                 $this->throwError(4, 'user upgrades', $this->getRequest('user'));
             }
             $user_upgrade_object = NULL;
             foreach ($user_upgrades as $user_upgrade) {
                 if ($user_upgrade['user_upgrade_id'] == $this->getRequest('upgrade_id')) {
                     $user_upgrade_object = $user_upgrade;
                 }
             }
             if ($user_upgrade_object === NULL) {
                 $this->throwError(4, 'user upgrade', $this->getRequest('upgrade_id'));
             }
             $record = $this->getXenAPI()->getUserUpgradeRecord($user_upgrade_object['user_upgrade_record_id']);
             $this->getXenAPI()->downgradeUserUpgrade($record);
             // Recheck upgrades to see if the user was downgraded.
             $user_upgrades = $this->getXenAPI()->getUserUpgrades($user);
             $user_upgrade_object = NULL;
             foreach ($user_upgrades as $user_upgrade) {
                 if ($user_upgrade['user_upgrade_id'] == $this->getRequest('upgrade_id')) {
                     $user_upgrade_object = $user_upgrade;
                 }
             }
             if ($user_upgrade_object === NULL) {
                 $this->sendResponse(array('success' => TRUE));
             } else {
                 $this->sendResponse(array('success' => FALSE));
             }
         case 'upgradeuser':
             if (!$this->hasRequest('user')) {
                 // The 'user' argument has not been set, throw error.
                 $this->throwError(3, 'user');
             } else {
                 if (!$this->getRequest('user')) {
                     // Throw error if the 'user' argument is set but empty.
                     $this->throwError(1, 'user');
                 }
             }
             $user = $this->getXenAPI()->getUser($this->getRequest('user'));
             if (!$user->isRegistered()) {
                 // Requested user was not registered, throw error.
                 $this->throwError(4, 'user', $this->getRequest('user'));
             }
             if (!$this->hasRequest('id')) {
                 // The 'id' argument has not been set, throw error.
                 $this->throwError(3, 'id');
             } else {
                 if (!$this->getRequest('id')) {
                     // Throw error if the 'id' argument is set but empty.
                     $this->throwError(1, 'id');
                 }
             }
             $upgrade = $this->getXenAPI()->getUserUpgrade($this->getRequest('id'));
             if (!$upgrade) {
                 $this->throwError(4, 'user upgrade', $this->getRequest('id'));
             }
             $end_date = NULL;
             if ($this->hasRequest('end_date')) {
                 // Request has end_date.
                 if (!$this->getRequest('end_date')) {
                     // Throw error if the 'end_date' argument is set but empty.
                     $this->throwError(1, 'end_date');
                 }
                 // Set the language id of the registration.
                 $end_date = $this->getRequest('end_date');
                 if (!((string) (int) $this->getRequest('end_date') === $this->getRequest('end_date') && $this->getRequest('end_date') <= PHP_INT_MAX && $this->getRequest('end_date') >= ~PHP_INT_MAX)) {
                     $this->throwError(6, $this->getRequest('end_date'), 'unix timestamp');
                 }
             }
             $record_id = $this->getXenAPI()->upgradeUser($user, $upgrade, TRUE, $end_date);
             $record = $this->getXenAPI()->getUserUpgradeRecord($record_id);
             $return = array();
             if (is_int($record_id)) {
                 $return['result'] = 'exists';
             } else {
                 $return['result'] = 'new';
             }
             $return['record'] = $record;
             $this->sendResponse($return);
         case 'login':
             /**
              * Logins the user.
              *
              * EXAMPLE:
              *   - api.php?action=login&username=USERNAME&password=PASSWORD
              */
             if (!$this->hasRequest('username')) {
                 // The 'username' argument has not been set, throw error.
                 $this->throwError(3, 'username');
                 break;
             } else {
                 if (!$this->getRequest('username')) {
                     // Throw error if the 'username' argument is set but empty.
                     $this->throwError(1, 'username');
                     break;
                 } else {
                     if (!$this->hasRequest('password')) {
                         // The 'password' argument has not been set, throw error.
                         $this->throwError(3, 'password');
                         break;
                     } else {
                         if (!$this->getRequest('password')) {
                             // Throw error if the 'password' argument is set but empty.
                             $this->throwError(1, 'password');
                             break;
                         } else {
                             if (!$this->hasRequest('ip_address')) {
                                 // The 'ip_address' argument has not been set, throw error.
                                 $this->throwError(3, 'ip_address');
                                 break;
                             } else {
                                 if (!$this->getRequest('ip_address')) {
                                     // Throw error if the 'ip_address' argument is set but empty.
                                     $this->throwError(1, 'ip_address');
                                     break;
                                 }
                             }
                         }
                     }
                 }
             }
             // Get the user object.
             $user = $this->xenAPI->getUser($this->getRequest('username'));
             if (!$user->isRegistered()) {
                 // Requested user was not registered, throw error.
                 $this->throwError(4, 'user', $this->getRequest('username'));
             } else {
                 // Requested user was registered, check authentication.
                 if ($user->validateAuthentication($this->getRequest('password'))) {
                     // Authentication was valid, grab the user's authentication record.
                     $record = $user->getAuthenticationRecord();
                     $ddata = unserialize($record['data']);
                     // Start session and saves the session to the database
                     $session = $this->getXenAPI()->login($user->getID(), $user->getUsername(), XenForo_Helper_Ip::convertIpStringToBinary($this->getRequest('ip_address')));
                     $cookie_domain = XenForo_Application::get('config')->cookie->domain;
                     // Check if cookie domain is empty, grab board url and use its domain if it is empty
                     if (empty($cookie_domain)) {
                         $url = XenForo_Application::getOptions()->boardUrl;
                         $parse = parse_url($url);
                         $cookie_domain = $parse['host'];
                     }
                     // Return data required for creating cookie
                     $this->sendResponse(array('hash' => base64_encode($ddata['hash']), 'cookie_name' => XenForo_Application::get('config')->cookie->prefix . 'session', 'cookie_id' => $session->getSessionId(), 'cookie_path' => XenForo_Application::get('config')->cookie->path, 'cookie_domain' => $cookie_domain, 'cookie_expiration' => 0, 'cookie_secure' => XenForo_Application::$secure));
                 } else {
                     // The username or password was wrong, throw error.
                     $this->throwError(5, 'Invalid username or password!');
                 }
             }
             break;
         case 'register':
             /**
              * Registers a user.
              */
             // Init user array.
             $user_data = array();
             // Array of required parameters.
             $required_parameters = array('username', 'password', 'email');
             // Array of additional parameters.
             $additional_parameters = array('timezone', 'gender', 'dob_day', 'dob_month', 'dob_year', 'ip_address');
             foreach ($required_parameters as $required_parameter) {
                 // Check if the required parameter is set and not empty.
                 $this->checkRequestParameter($required_parameter);
                 // Set the request value.
                 $user_data[$required_parameter] = $this->getRequest($required_parameter);
             }
             foreach ($additional_parameters as $additional_parameter) {
                 // Check if the additional parameter is set and not empty.
                 $this->checkRequestParameter($additional_parameter, FALSE);
                 if ($this->getRequest($additional_parameter)) {
                     // Set the request value.
                     $user_data[$additional_parameter] = $this->getRequest($additional_parameter);
                 }
             }
             if ($this->hasRequest('group')) {
                 // Request has value.
                 if (!$this->getRequest('group')) {
                     // Throw error if the 'group' argument is set but empty.
                     $this->throwError(1, 'group');
                     break;
                 }
                 $group = $this->getXenAPI()->getGroup($this->getRequest('group'));
                 if (!$group) {
                     $registration_error = array('error_id' => 2, 'error_key' => 'group_not_found', 'error_field' => 'group', 'error_phrase' => 'Could not find group with parameter "' . $this->getRequest('group') . '"');
                     $this->throwError(self::USER_ERROR, $registration_error, 'registering a new user');
                 }
                 // Set the group id of the registration.
                 $user_data['group_id'] = $group['user_group_id'];
             }
             if ($this->hasRequest('custom_fields')) {
                 // Request has value.
                 if (!$this->getRequest('custom_fields')) {
                     // Throw error if the 'custom_fields' argument is set but empty.
                     $this->throwError(1, 'custom_fields');
                     break;
                 }
                 $custom_fields = $this->getCustomArray($this->getRequest('custom_fields'));
                 // Check if we found any valid custom fields, throw error if not.
                 if (count($custom_fields) == 0) {
                     // The custom fields array was empty, throw error.
                     $registration_error = array('error_id' => 5, 'error_key' => 'invalid_custom_fields', 'error_field' => 'custom_fields', 'error_phrase' => 'The custom fields values were invalid, valid values are: ' . 'custom_fields=custom_field1=custom_value1,custom_field2=custom_value2 ' . 'but got: "' . $this->getRequest('custom_fields') . '" instead');
                     $this->throwError(self::USER_ERROR, $registration_error, 'registering a new user');
                 }
                 $user_data['custom_fields'] = $custom_fields;
             }
             // Check if add groups is set.
             if ($this->hasRequest('add_groups')) {
                 // Request has value.
                 if (!$this->getRequest('add_groups')) {
                     // Throw error if the 'add_groups' argument is set but empty.
                     $this->throwError(1, 'add_groups');
                 }
                 // Initialize the array.
                 $user_data['add_groups'] = array();
                 // Check if value is an array.
                 if (strpos($this->getRequest('add_groups'), ',') !== FALSE) {
                     // Value is an array, explode it.
                     $groups = explode(',', $this->getRequest('add_groups'));
                     // Loop through the group values.
                     foreach ($groups as $group_value) {
                         // Grab the group from the group value.
                         $group = $this->getXenAPI()->getGroup($group_value);
                         // Check if group was found.
                         if (!$group) {
                             // Group was not found, throw error.
                             $registration_error = array('error_id' => 2, 'error_key' => 'group_not_found', 'error_field' => 'add_groups', 'error_phrase' => 'Could not find group with parameter "' . $group_value . '" in array "' . $this->getRequest('add_group') . '"');
                             $this->throwError(self::USER_ERROR, $registration_error, 'registering a new user');
                         }
                         // Add the group_id to the the add_group array.
                         $user_data['add_groups'][] = $group['user_group_id'];
                     }
                 } else {
                     // Grab the group from the group value.
                     $group = $this->getXenAPI()->getGroup($this->getRequest('add_groups'));
                     // Check if group was found.
                     if (!$group) {
                         // Group was not found, throw error.
                         $registration_error = array('error_id' => 2, 'error_key' => 'group_not_found', 'error_field' => 'add_groups', 'error_phrase' => 'Could not find group with parameter "' . $this->getRequest('add_groups') . '"');
                         $this->throwError(self::USER_ERROR, $registration_error, 'registering a new user');
                     }
                     // Add the group_id to the the add_groups array.
                     $user_data['add_groups'][] = $group['user_group_id'];
                 }
             }
             if ($this->hasRequest('user_state')) {
                 // Request has user_state.
                 if (!$this->getRequest('user_state')) {
                     // Throw error if the 'user_state' argument is set but empty.
                     $this->throwError(1, 'user_state');
                     break;
                 }
                 // Set the user state of the registration.
                 $user_data['user_state'] = $this->getRequest('user_state');
             }
             if ($this->hasRequest('language_id')) {
                 // Request has language_id.
                 if (!$this->getRequest('language_id')) {
                     // Throw error if the 'language_id' argument is set but empty.
                     $this->throwError(1, 'language_id');
                     break;
                 }
                 // Set the language id of the registration.
                 $user_data['language_id'] = $this->getRequest('language_id');
             }
             $registration_results = $this->getXenAPI()->register($user_data);
             if (!empty($registration_results['error'])) {
                 // The registration failed, process errors.
                 if (is_array($registration_results['errors'])) {
                     // The error message was an array, loop through the messages.
                     $error_keys = array();
                     foreach ($registration_results['errors'] as $error_field => $error) {
                         if (!$error instanceof XenForo_Phrase) {
                             $registration_error = array('error_id' => 1, 'error_key' => 'field_not_recognised', 'error_field' => $error_field, 'error_phrase' => $error);
                             $this->throwError(self::USER_ERROR, $registration_error, 'registering a new user');
                         }
                         // Let's init the registration error array.
                         $registration_error = array('error_id' => $this->getUserErrorID($error->getPhraseName()), 'error_key' => $error->getPhraseName(), 'error_field' => $error_field, 'error_phrase' => $error->render());
                         $this->throwError(self::USER_ERROR, $registration_error, 'registering a new user');
                     }
                 } else {
                     $registration_error = array('error_id' => $registration_results['error'], 'error_key' => 'general_user_registration_error', 'error_phrase' => $registration_results['errors']);
                     $this->throwError(self::USER_ERROR, $registration_error, 'registering a new user');
                 }
             } else {
                 // Registration was successful, return results.
                 $this->sendResponse($registration_results);
             }
             break;
         case 'search':
             if (!$this->hasRequest('value')) {
                 // The 'value' argument has not been set, throw error.
                 $this->throwError(3, 'value');
                 break;
             } else {
                 if (!$this->getRequest('value')) {
                     // Throw error if the 'value' argument is set but empty.
                     $this->throwError(1, 'value');
                     break;
                 }
             }
             $order = 'asc';
             $type = NULL;
             if ($this->hasRequest('order')) {
                 // Request has order.
                 if (!$this->getRequest('order')) {
                     // Throw error if the 'order' argument is set but empty.
                     $this->throwError(1, 'order');
                     break;
                 }
                 // Set the language id of the registration.
                 $order = $this->getRequest('order');
             }
             if ($this->hasRequest('type')) {
                 // Request has type.
                 if (!$this->getRequest('type')) {
                     // Throw error if the 'type' argument is set but empty.
                     $this->throwError(1, 'type');
                     break;
                 }
                 // Set the language id of the registration.
                 $type = $this->getRequest('type');
             }
             $this->sendResponse($this->getXenAPI()->search($this->getRequest('value'), $order, $type));
             break;
         default:
             // Action was supported but has not yet been added to the switch statement, throw error.
             $this->throwError(11, $this->getAction());
     }
     $this->throwError(7, 'executing action', $this->getAction());
 }