From e41cf0161e9794e6e8b07835f8157064847504c9 Mon Sep 17 00:00:00 2001 From: Pierre HUBERT Date: Thu, 24 Jan 2019 09:22:50 +0100 Subject: [PATCH] Can create a call --- RestControllers/CallsController.php | 86 ++++++++++ classes/components/CallsComponent.php | 196 +++++++++++++++++++++++ classes/models/CallInformation.php | 55 +++++++ classes/models/CallMemberInformation.php | 67 ++++++++ db_struct.sql | 20 +++ 5 files changed, 424 insertions(+) create mode 100644 classes/models/CallInformation.php create mode 100644 classes/models/CallMemberInformation.php diff --git a/RestControllers/CallsController.php b/RestControllers/CallsController.php index 8207d85..9cdebb3 100644 --- a/RestControllers/CallsController.php +++ b/RestControllers/CallsController.php @@ -8,6 +8,15 @@ class CallsController { + /** + * Single user response to call + */ + const USER_RESPONSE_TO_CALL = array( + CallMemberInformation::USER_ACCEPTED => "accepted", + CallMemberInformation::USER_REJECTED => "rejected", + CallMemberInformation::USER_UNKNOWN => "unknown" + ); + /** * Get call configuration * @@ -18,6 +27,47 @@ class CallsController { return self::CallsConfigToAPI(components()->calls->getConfig()); } + /** + * Create a call for a conversation + * + * @url POST /calls/createForConversation + */ + public function createForConversation(){ + + user_login_required(); + + //Get conversation ID + $conversationID = getPostConversationID("conversationID"); + + //Check if the user belongs to the conversation + if(!components()->conversations->userBelongsTo(userID, $conversationID)) + Rest_fatal_error(401, "Specified user doesn't belongs to the conversation number ".$conversationID." !"); + + //First, check if a call alreay exists for this conversation + $call = components()->calls->getForConversation($conversationID, true); + + //If could not get a call, try to create a new one + if(!$call->isValid()){ + + //Try to create the call + if(!components()->calls->createForConversation($conversationID)) + Rest_fatal_error(500, "Could not create the call"); + + //Get the conversation again + $call = components()->calls->getForConversation($conversationID, true); + + if(!$call->isValid()) + Rest_fatal_error(500, "Could not get information about created call!"); + } + + //The user automatically accept the call + components()->calls->setMemberResponse($call->get_id(), userID, true); + + //Returns information about the call + return self::CallInformationToAPI($call); + + } + /** * Turn a CallsConfig object into an API entry @@ -43,4 +93,40 @@ class CallsController { return $data; } + + /** + * Turn a CallInformation object into an API entry + * + * @param $call The call to convert + * @return array Generated API entry + */ + private static function CallInformationToAPI(CallInformation $call) : array { + $data = array( + "id" => $call->get_id(), + "conversation_id" => $call->get_conversation_id(), + "last_active" => $call->get_last_active(), + "members" => array() + ); + + foreach($call->get_members() as $member) + $data["members"][] = self::CallMemberInformationToAPI($member); + + return $data; + } + + /** + * Turn a CallMemberInformation object into an API entry + * + * @param $member Member information + * @return array User information API entry + */ + private static function CallMemberInformationToAPI(CallMemberInformation $member) : array { + return array( + "id" => $member->get_id(), + "userID" => $member->get_userID(), + "call_id" => $member->get_call_id(), + "user_call_id" => $member->get_user_call_id(), + "accepted" => self::USER_RESPONSE_TO_CALL[$member->get_accepted()] + ); + } } \ No newline at end of file diff --git a/classes/components/CallsComponent.php b/classes/components/CallsComponent.php index 6ea9005..4a7f093 100644 --- a/classes/components/CallsComponent.php +++ b/classes/components/CallsComponent.php @@ -7,6 +7,12 @@ class CallsComponents { + /** + * Calls tables names + */ + private const CALLS_LIST_TABLE = "comunic_calls"; + private const CALLS_MEMBERS_TABLE = "comunic_calls_members"; + /** * Get and return calls configuration * @@ -33,6 +39,196 @@ class CallsComponents { return $config; } + /** + * Get the call for a conversation + * + * @param $conversation_id Target conversation ID + * @param $load_members Specify whether members information should + * be loaded too or not + * @return CallInformation Matching call information object / invalid object + * in case of failure + */ + public function getForConversation(int $conversation_id, bool $load_members) : CallInformation { + + $entry = db()->select( + self::CALLS_LIST_TABLE, + "WHERE conversation_id = ?", + array($conversation_id) + ); + + if(count($entry) == 0) + return new CallInformation(); + + $info = self::DBToCallInformation($entry[0]); + + //Load call members if required + if($load_members && !$this->getMembers($info)) + return new CallInformation(); + + + return $info; + } + + /** + * Create a call for a conversation + * + * @param $conversationID The ID of the target conversation + * @return bool TRUE for a success / FALSE else + */ + public function createForConversation(int $conversationID) : bool { + + //Generate call information + $info = new CallInformation(); + $info->set_conversation_id($conversationID); + $info->set_last_active(time()); + + //We need to get the list of members of the conversation to create members list + $conversation_members = components()->conversations->getConversationMembers($conversationID); + + //Check for errors + if(count($conversation_members) == 0) + return false; + + + //Insert the call in the database to get its ID + if(!db()->addLine( + self::CALLS_LIST_TABLE, + self::CallInformationToDB($info) + )) + return false; + $info->set_id(db()->getLastInsertedID()); + + foreach($conversation_members as $memberID){ + $member = new CallMemberInformation(); + $member->set_call_id($info->get_id()); + $member->set_userID($memberID); + $member->set_user_call_id(random_str(190)); + $member->set_accepted(CallMemberInformation::USER_UNKNOWN); + + //Try to add the member to the list + if(!$this->addMember($member)) + return false; + } + + //Success + return true; + } + + /** + * Add a new member to a call + * + * @param $member Information about the member to add + * @return bool TRUE for a success / FALSE else + */ + private function addMember(CallMemberInformation $member) : bool { + return db()->addLine( + self::CALLS_MEMBERS_TABLE, + self::CallMemberInformationToDB($member) + ); + } + + /** + * Load information about the members related to the call + * + * @param $info Information about the call to process + * @return bool TRUE in case of success / FALSE else + */ + private function getMembers(CallInformation $info) : bool { + + $entries = db()->select( + self::CALLS_MEMBERS_TABLE, + "WHERE call_id = ?", + array($info->get_id()) + ); + + foreach($entries as $entry) + $info->add_member(self::DBToCallMemberInformation($entry)); + + return count($entries) > 0; + } + + /** + * Set the response of a member to a call + * + * @param $callID The ID of the target call + * @param $userID The ID of the target member + * @param $accept TRUE to accept the call / FALSE else + * @return bool TRUE for a success / FALSE else + */ + public function setMemberResponse(int $callID, int $userID, bool $accept) : bool { + db()->updateDB( + self::CALLS_MEMBERS_TABLE, + "call_id = ? AND user_id = ?", + array( + "user_accepted" => + $accept ? CallMemberInformation::USER_ACCEPTED : CallMemberInformation::USER_REJECTED + ), + array( + $callID, + $userID + ) + ); + + return true; + } + + /** + * Turn a database entry into a CallInformation object + * + * @param $entry The entry to convert + * @return CallInformation Generated object + */ + private static function DBToCallInformation(array $entry) : CallInformation { + $info = new CallInformation(); + $info->set_id($entry["id"]); + $info->set_conversation_id($entry["conversation_id"]); + $info->set_last_active($entry["last_active"]); + return $info; + } + + /** + * Turn a CallInformation object into a database entry + * + * @param $call Call information object to convert + * @return array Generated array + */ + private static function CallInformationToDB(CallInformation $call) : array { + $data = array(); + $data["conversation_id"] = $call->get_conversation_id(); + $data["last_active"] = $call->get_last_active(); + return $data; + } + + /** + * Turn a database entry into a CallMemberInformation object + * + * @param $entry The entry to convert + * @return CallMemberInformation Generated object + */ + private static function DBToCallMemberInformation(array $entry) : CallMemberInformation { + $member = new CallMemberInformation(); + $member->set_id($entry["id"]); + $member->set_call_id($entry["call_id"]); + $member->set_userID($entry["user_id"]); + $member->set_user_call_id($entry["user_call_id"]); + $member->set_accepted($entry["user_accepted"]); + return $member; + } + + /** + * Turn a CallMemberInformation object into a database entry + * + * @param $member The member to convert + * @return array Generated database entry + */ + private static function CallMemberInformationToDB(CallMemberInformation $member) : array { + $data = array(); + $data["call_id"] = $member->get_call_id(); + $data["user_id"] = $member->get_userID(); + $data["user_call_id"] = $member->get_user_call_id(); + $data["user_accepted"] = $member->get_accepted(); + return $data; + } } //Register class diff --git a/classes/models/CallInformation.php b/classes/models/CallInformation.php new file mode 100644 index 0000000..22d72b5 --- /dev/null +++ b/classes/models/CallInformation.php @@ -0,0 +1,55 @@ +members = array(); + } + + //Conversations ID + public function set_conversation_id(int $conversation_id){ + $this->conversation_id = $conversation_id; + } + + public function has_conversation_id() : bool { + return $this->conversation_id > -1; + } + + public function get_conversation_id() : int { + return $this->conversation_id; + } + + + //Last activity + public function set_last_active(int $last_active){ + $this->last_active = $last_active; + } + + public function has_last_active() : bool { + return $this->last_active > -1; + } + + public function get_last_active() : int { + return $this->last_active; + } + + //Call members list + public function add_member(CallMemberInformation $member) { + $this->members[] = $member; + } + + public function get_members() : array { + return $this->members; + } +} \ No newline at end of file diff --git a/classes/models/CallMemberInformation.php b/classes/models/CallMemberInformation.php new file mode 100644 index 0000000..d71db87 --- /dev/null +++ b/classes/models/CallMemberInformation.php @@ -0,0 +1,67 @@ +call_id = $call_id; + } + + public function has_call_id() : bool { + return $this->call_id > -1; + } + + public function get_call_id() : int { + return $this->call_id; + } + + + //User Call ID + public function set_user_call_id(string $user_call_id){ + $this->user_call_id = $user_call_id == "" ? null : $user_call_id; + } + + public function has_user_call_id() : bool { + return $this->user_call_id != null; + } + + public function get_user_call_id() : string { + return $this->user_call_id != null ? $this->user_call_id : "null"; + } + + + //User response to call + public function set_accepted(int $accepted){ + $this->accepted = $accepted; + } + + public function has_accepted() : bool { + return $this->accepted > -1; + } + + public function get_accepted() : int { + return $this->accepted; + } + +} \ No newline at end of file diff --git a/db_struct.sql b/db_struct.sql index e0bc50d..d262b4e 100644 --- a/db_struct.sql +++ b/db_struct.sql @@ -103,6 +103,26 @@ CREATE TABLE `comunic_api_users_tokens` ( ) ENGINE=InnoDB DEFAULT CHARSET=latin1; +DROP TABLE IF EXISTS `comunic_calls`; +CREATE TABLE `comunic_calls` ( + `id` INT NOT NULL AUTO_INCREMENT, + `conversation_id` INT NULL, + `last_active` INT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + + +DROP TABLE IF EXISTS `comunic_calls_members`; +CREATE TABLE `comunic_calls_members` ( + `id` INT NOT NULL AUTO_INCREMENT, + `call_id` INT NOT NULL, + `user_id` INT NULL, + `user_call_id` VARCHAR(200) NULL, + `user_accepted` TINYINT DEFAULT NULL, + PRIMARY KEY (`id`) +) ENGINE=InnoDB DEFAULT CHARSET=latin1; + + DROP TABLE IF EXISTS `comunic_conversations_list`; CREATE TABLE `comunic_conversations_list` ( `id` int(11) NOT NULL AUTO_INCREMENT,