| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765 |
- <?php
- class imConference extends model
- {
- /**
- * Generate number of a conference based on its id.
- * The first character represents the length of id (which is on the tail of the number).
- * A padding of date is inserted between the length of id and the id if the number is not long enough.
- *
- * @param object $conference
- * @access public
- * @return string
- */
- public function getNumber($conference)
- {
- if (!empty($conference->number)) return $conference->number;
- $idLength = strlen((string)$conference->id);
- if($idLength > 8)
- {
- $number = $idLength . $conference->id;
- }
- else
- {
- /* Pad the number to length of 9 with openedDate if id is not long enough. */
- $dateNum = str_replace('-', '', current(explode(' ', $conference->openedDate)));
- $number = $idLength . substr($dateNum, 0, 8 - $idLength) . $conference->id;
- }
- return $number;
- }
- /**
- * Set the number of a conference.
- *
- * @param int $id conference id
- * @param string $number conference number
- * @access public
- * @return bool
- */
- public function setNumber($id, $number)
- {
- $this->dao->update(TABLE_IM_CONFERENCE)->set('number')->eq($number)->where('id')->eq($id)->exec();
- return !dao::isError();
- }
- /**
- * Extract id from number.
- *
- * @param string $number
- * @access public
- * @return int
- */
- public function extractIdFromNumber($number)
- {
- $len = strlen($number);
- /* Use first chars as length of id. */
- if($len > 10)
- {
- $id = substr($number, 2);
- }
- else
- {
- $idLength = intval(substr($number, 0, 1));
- $id = substr($number, $len - $idLength, $idLength);
- }
- return intval($id);
- }
- /**
- * Get a conference by number.
- * The number is generated by the getNumber method.
- *
- * @param int $number
- * @access public
- * @return object
- */
- public function getByNumber($number)
- {
- $id = $this->extractIdFromNumber($number);
- return $this->getById($id);
- }
- /**
- * Get the old conference by the id of chat.
- * @deprecated
- * @param string $chatID
- * @access public
- * @return object
- */
- public function getByChatID($chatID)
- {
- return $this->dao->select('*')->from(TABLE_IM_CONFERENCE)
- ->where('number')->eq('')
- ->andWhere('cgid')->eq($chatID)
- ->orderBy('id_asc')
- ->fetch();
- }
- /**
- * Get the latest conference by the id of chat.
- *
- * @param string $cgid
- * @access public
- * @return object
- */
- public function getLatestByChatID($cgid)
- {
- return $this->dao->select('*')->from(TABLE_IM_CONFERENCE)
- ->where('cgid')->eq($cgid)
- ->andWhere('status')->eq('open')
- ->orderBy('id_desc')
- ->fetch();
- }
- /**
- * Get a conference by id.
- *
- * @param int $id
- * @access public
- * @return object
- */
- public function getById($id)
- {
- return $this->dao->select('*')->from(TABLE_IM_CONFERENCE)
- ->where('id')->eq($id)
- ->fetch();
- }
- /**
- * get not started scheduled conferences.
- * @return object
- */
- public function getNotStartedSchedule()
- {
- return $this->dao->select('*')->from(TABLE_IM_CONFERENCE)
- ->where('status')->eq('notStarted')
- ->andWhere('type')->eq('scheduled')
- /* notStarted conferences notify count will be 1 when create. */
- ->andWhere('sentNotify')->eq(1)
- ->fetchAll();
- }
- /**
- * get will start scheduled conferences.
- * @return object
- */
- public function getWillStartSchedule()
- {
- return $this->dao->select('*')->from(TABLE_IM_CONFERENCE)
- ->where('status')->eq('notStarted')
- ->andWhere('type')->eq('scheduled')
- /* will start conference notify count should be 2 */
- ->andWhere('sentNotify')->in(2)
- ->fetchAll();
- }
- /**
- * Get conference by condition.
- * @param string $condition
- * @param array $options
- * @param int $userID
- * @return array
- */
- public function getByCondition($condition, $options, $pager, $userID)
- {
- if(!is_object($options) && is_array($options)) $options = (object)$options;
- $isCreateByMe = property_exists($options, 'isCreateByMe') ? $options->isCreateByMe : false;
- $conferences = array();
- switch($condition)
- {
- case 'immediate':
- $chatList = $this->loadModel('im')->chatGetGidListByUserID($userID);
- $conferences = $this->dao->select('t1.*, t2.hide, t2.user')->from(TABLE_IM_CONFERENCE)->alias('t1')
- ->leftJoin(TABLE_IM_CONFERENCEUSER)->alias('t2')
- ->on('t2.conference=t1.id and t2.user')->eq($userID)
- ->where('(t2.user is null')
- ->orWhere('t2.user')->eq($userID)
- ->andWhere('t2.hide')->ne(1)
- ->markRight(1)
- ->andWhere('t1.number')->ne('')
- ->andWhere('t1.type')->eq('default')
- ->beginIF($isCreateByMe)->andWhere('t1.openedBy')->eq($userID)
- ->fi()
- ->andWhere('t1.participants', true)->like("%,$userID,%")
- ->orWhere('t1.invitee')->like("%,$userID,%")
- ->orWhere('t1.subscribers')->like("%,$userID,%")
- ->orWhere('t1.cgid')->in($chatList)
- ->markRight(1)
- ->orderBy('id_desc')
- ->page($pager)
- ->fetchAll();
- break;
- case 'scheduled':
- $conferences = $this->dao->select('t1.*, t2.hide, t2.user')->from(TABLE_IM_CONFERENCE)->alias('t1')
- ->leftJoin(TABLE_IM_CONFERENCEUSER)->alias('t2')
- ->on('t2.conference=t1.id and t2.user')->eq($userID)
- ->where('(t2.user is null')
- ->orWhere('t2.user')->eq($userID)
- ->andWhere('t2.hide')->ne(1)
- ->markRight(1)
- ->andWhere('t1.type')->eq('scheduled')
- ->beginIF($isCreateByMe)->andWhere('t1.openedBy')->eq($userID)
- ->fi()
- ->andWhere('t1.invitee', true)->like("%,$userID,%")
- ->orWhere('t1.subscribers')->like("%,$userID,%")
- ->markRight(1)
- ->orderBy('id_desc')
- ->page($pager)
- ->fetchAll();
- break;
- }
- $thisClass = $this;
- return array_map(function($conference) use ($thisClass) { return $thisClass->format($conference); }, $conferences);
- }
- /**
- * Format conference data.
- *
- * @param object $conference
- * @access public
- * @return object
- */
- public function format($conference)
- {
- if(empty($conference)) return $conference;
- foreach(array('openedDate', 'startTime', 'endTime') as $key) $conference->$key = empty($conference->$key) || $conference->$key == null ? 0 : strtotime($conference->$key);
- if(!empty($conference->number) && !empty($conference->rid) && empty($conference->room))
- {
- $conference->room = $conference->rid;
- unset($conference->rid);
- }
- return $conference;
- }
- // /**
- // * Generate room password.
- // *
- // * @access private
- // * @return string
- // */
- // private function generateRoomPassword()
- // {
- // return sprintf("%06d", mt_rand(0, 999999));
- // }
- /**
- * Create a detached conference.
- *
- * @param string $chatID
- * @param string $invitee
- * @param string $topic
- * @param string $type
- * @param string $password
- * @param string $startTime
- * @param string $endTime
- * @param int $reminderTime
- * @param string $note
- * @param int $userID
- * @param bool $isPrivate
- * @param bool $isInner
- * @access public
- * @return object|boolean
- */
- public function createDetached($chatID, $invitee, $type = 'default', $topic = '', $password = '', $startTime = null, $endTime = null, $reminderTime = 0, $note = '', $isPrivate = false, $isInner = true, $userID = 0)
- {
- $conferenceData = new stdClass();
- $conferenceData->openedDate = helper::now();
- $this->dao->insert(TABLE_IM_CONFERENCE)->data($conferenceData)->exec();
- if(dao::isError()) return false;
- $id = $this->dao->lastInsertID();
- if(empty($id)) return false;
- $conference = $this->getById($id);
- if(empty($conference)) return false;
- $number = $this->getNumber($conference);
- $this->setNumber($id, $number);
- $conferenceData = new stdClass();
- $conferenceData->cgid = $chatID;
- $conferenceData->rid = $number;
- $conferenceData->status = $type == 'default' ? 'open' : 'notStarted';
- $conferenceData->openedBy = (int)$userID;
- $conferenceData->openedDate = helper::now();
- $conferenceData->subscribers = ",$userID,";
- $conferenceData->participants = $type == 'default' ? ",$userID," : '' ;
- $conferenceData->invitee = empty($invitee) ? '' : ",$invitee,";
- $conferenceData->topic = $topic;
- $conferenceData->type = $type;
- // $conferenceData->password = empty($password) ? $this->generateRoomPassword() : $password;
- $conferenceData->password = '';
- if(!empty($startTime)) $conferenceData->startTime = $startTime;
- if(!empty($endTime)) $conferenceData->endTime = $endTime;
- $conferenceData->number = $number;
- $conferenceData->reminderTime = $reminderTime;
- $conferenceData->note = $note;
- $conferenceData->moderators = ",$userID,";
- $conferenceData->isPrivate = $isPrivate === true ? '1' : '0';
- $conferenceData->isInner = $isInner === true ? '1' : '0';
- $this->dao->update(TABLE_IM_CONFERENCE)->data($conferenceData)->where('id')->eq($id)->exec();
- $conference = $this->getById($id);
- if(dao::isError()) return false;
- return $conference;
- }
- /**
- * set the scheduled conference status to open, and return the conference.
- * @param $conference
- * @return object
- */
- public function startSchedule($conference)
- {
- $this->dao->update(TABLE_IM_CONFERENCE)
- ->set('status')->eq('open')
- ->where('number')->eq($conference->number)
- ->exec();
- if(dao::isError()) return false;
- return $this->dao->select('*')->from(TABLE_IM_CONFERENCE)
- ->where('number')->eq($conference->number)
- ->fetch();
- }
- /**
- * Close a conference.
- *
- * @param string $conferenceId
- * @access public
- * @return boolean
- */
- public function close($conferenceId)
- {
- $conference = $this->getById($conferenceId);
- if($conference->status == 'closed') return true;
- $this->dao->update(TABLE_IM_CONFERENCE)
- ->set('status')->eq('closed')
- ->set('participants')->eq('')
- ->where('id')->eq($conference->id)
- ->exec();
- $this->dao->update(TABLE_IM_CONFERENCEINVITE)
- ->set('status')->eq('rejected')
- ->where('conferenceID')->eq($conference->id)
- ->exec();
- return !dao::isError();
- }
- /**
- * cancel a conference.
- *
- * @param string $conferenceId
- * @access public
- * @return boolean
- */
- public function cancel($conferenceId)
- {
- $conference = $this->getById($conferenceId);
- if($conference->status == 'canceled') return true;
- $this->dao->update(TABLE_IM_CONFERENCE)
- ->set('status')->eq('canceled')
- ->set('participants')->eq('')
- ->where('id')->eq($conference->id)
- ->exec();
- return !dao::isError();
- }
- /**
- * hide a conference.
- *
- * @param string $conferenceNumber
- * @param int $userID
- * @access public
- * @return bool
- */
- public function hide($conferenceNumber, $userID)
- {
- $conferenceId = $this->extractIdFromNumber($conferenceNumber);
- $data = $this->dao->select('*')->from(TABLE_IM_CONFERENCEUSER)->where('conference')->eq($conferenceId)->andWhere('user')->eq($userID)->fetch();
- if(empty($data))
- {
- $this->dao->insert(TABLE_IM_CONFERENCEUSER)
- ->set('conference')->eq($conferenceId)
- ->set('user')->eq($userID)
- ->set('hide')->eq(1)
- ->exec();
- }
- else
- {
- $this->dao->update(TABLE_IM_CONFERENCEUSER)
- ->set('hide')->eq(1)
- ->where('conference')->eq($conferenceId)
- ->andWhere('user')->eq($userID)
- ->exec();
- }
- return !dao::isError();
- }
- /**
- * update a conference.
- *
- * @param object $conference
- * @return bool
- */
- public function update($conference)
- {
- $this->dao->update(TABLE_IM_CONFERENCE)
- ->data($conference)
- ->where('number')->eq($conference->number)
- ->exec();
- return !dao::isError();
- }
- /**
- * after sent notify, update the sentNotify field.
- * @param object $conference
- * @param int $times
- * @return void
- */
- public function updateSentNotifyTimes($conference, $times) {
- $this->dao->update(TABLE_IM_CONFERENCE)
- ->set('sentNotify')->eq($times)
- ->where('number')->eq($conference->number)
- ->exec();
- }
- /**
- * Add invitee into a conference.
- *
- * @param string $conferenceNumber
- * @param array $newInvitee
- * @access public
- * @return string|boolean
- */
- public function addInvitee($conferenceNumber, $newInvitee)
- {
- $conference = $this->getByNumber($conferenceNumber);
- foreach($newInvitee as $uid)
- {
- $hasInviteRecord = $this->dao->select('id')->from(TABLE_IM_CONFERENCEINVITE)
- ->where('conferenceID')->eq($conference->id)
- ->andWhere('inviteeID')->eq($uid)
- ->fetch();
- if(empty($hasInviteRecord))
- {
- $now = helper::now();
- $data = new stdClass();
- $data->conferenceID = $conference->id;
- $data->inviteeID = $uid;
- $data->status = 'pending';
- $data->createdDate = $now;
- $data->updatedDate = $now;
- $this->dao->insert(TABLE_IM_CONFERENCEINVITE)
- ->data($data)
- ->exec();
- }
- else
- {
- $this->dao->update(TABLE_IM_CONFERENCEINVITE)
- ->set('status')->eq('pending')
- ->set('updatedDate')->eq(helper::now())
- ->where('id')->eq($hasInviteRecord->id);
- }
- }
- $invitee = explode(',', $conference->invitee);
- $invitee = array_filter($invitee);
- $invitee = array_merge($invitee, $newInvitee);
- $invitee = array_unique($invitee);
- $invitee = implode(',', $invitee);
- $invitee = empty($invitee) ? '' : ",$invitee,";
- $this->dao->update(TABLE_IM_CONFERENCE)
- ->set('invitee')->eq($invitee)
- ->where('id')->eq($conference->id)
- ->exec();
- if(dao::isError()) return false;
- return $invitee;
- }
- /**
- * Add participant into a conference.
- *
- * @param string $conferenceNumber
- * @param int $userID
- * @access public
- * @return string|boolean
- */
- public function addParticipant($conferenceNumber, $userID)
- {
- $conference = $this->getByNumber($conferenceNumber);
- $participants = explode(',', $conference->participants);
- $participants = array_filter($participants);
- $participants[] = $userID;
- $participants = array_unique($participants);
- $participants = implode(',', $participants);
- $participants = empty($participants) ? '' : ",$participants,";
- $this->dao->update(TABLE_IM_CONFERENCE)
- ->set('participants')->eq($participants)
- ->where('id')->eq($conference->id)
- ->exec();
- if(dao::isError()) return false;
- return $participants;
- }
- /**
- * Remove participant from a conference.
- *
- * @param string $conferenceNumber
- * @param int $userID
- * @access public
- * @return string|false
- */
- public function removeParticipant($conferenceNumber, $userID)
- {
- $conference = $this->getByNumber($conferenceNumber);
- if($conference->participants == '') return false;
- $participants = explode(',', $conference->participants);
- $participants = array_filter($participants);
- $participants = array_diff($participants, array($userID));
- $participants = implode(',', $participants);
- $participants = empty($participants) ? '' : ",$participants,";
- $this->dao->update(TABLE_IM_CONFERENCE)
- ->set('participants')->eq($participants)
- ->where('id')->eq($conference->id)
- ->exec();
- if(dao::isError()) return false;
- return $participants;
- }
- public function addModerator($conferenceNumber, $userID)
- {
- $conference = $this->getByNumber($conferenceNumber);
- if(empty($conference)) return false;
- $moderators = explode(',', $conference->moderators);
- $moderators = array_filter($moderators);
- $moderators = array_unique(array_merge($moderators, array($userID)));
- $moderators = implode(',', $moderators);
- $moderators = empty($moderators) ? '' : ",$moderators,";
- $this->dao->update(TABLE_IM_CONFERENCE)
- ->set('moderators')->eq($moderators)
- ->where('id')->eq($conference->id)
- ->exec();
- return true;
- }
- public function addSubscriber($conferenceNumber, $userID)
- {
- $conference = $this->dao->select('subscribers')->from(TABLE_IM_CONFERENCE)
- ->where('number')->eq($conferenceNumber)
- ->fetch();
- if (!empty($conference))
- {
- $subscribers = explode(',', $conference->subscribers);
- $subscribers = array_filter($subscribers);
- $subscribers = array_unique(array_merge($subscribers, array($userID)));
- $subscribers = ',' . implode(',', $subscribers) . ',';
- $this->dao->update(TABLE_IM_CONFERENCE)
- ->set('subscribers')->eq($subscribers)
- ->where('number')->eq($conferenceNumber)
- ->exec();
- }
- }
- /**
- * Remove the user from all related conferences and close if necessary.
- *
- * @param int $userID
- * @access public
- * @return string[]
- */
- public function removeUserFromConferences($userID)
- {
- $conferences = $this->dao->select('*')->from(TABLE_IM_CONFERENCE)
- ->where('participants')->like("%,$userID,%")
- ->fetchAll();
- $closedConferences = [];
- foreach($conferences as $conference)
- {
- $participants = explode(',', $conference->participants);
- $participants = array_filter($participants);
- $participants = array_values($participants);
- $participants = array_map(function($v){
- return (int)$v;
- }, $participants);
- if(in_array($userID, $participants))
- {
- $leftParticipants = $this->removeParticipant($conference->number, $userID);
- if($leftParticipants == '') $closedConferences[] = $conference->number;
- }
- }
- return $closedConferences;
- }
- /**
- * Try to remove user from a conference of a chat.
- *
- * @deprecated
- * @param string $chatID
- * @param int $userID
- * @access public
- * @return object|boolean
- */
- public function removeUserFromChat($chatID, $userID)
- {
- /* Ignore conference number. */
- if(is_numeric($chatID)) return false;
- $conference = $this->getByChatID($chatID);
- if(empty($conference)) return false;
- $participants = explode(',', $conference->participants);
- $participants = array_filter($participants);
- $participants = array_diff($participants, array($userID));
- if(count($participants) == 0)
- {
- $this->close($conference->id, $userID);
- return false;
- }
- $participants = implode(',', $participants);
- $conference->participants = $participants;
- return $conference;
- }
- /**
- * Reset status of conferences.
- *
- * @access public
- * @return void
- */
- public function resetStatus()
- {
- $this->dao->update(TABLE_IM_CONFERENCE)
- ->set('status')->eq('closed')
- ->set('participants')->eq('')
- ->where('status')->eq('open')
- ->exec();
- }
- /**
- * Check if there is a participant limit in license.
- * If there is no limit, return 'unlimited'.
- * Otherwise, return the limit number.
- *
- * @access public
- * @return int
- */
- public function getConferenceLimit()
- {
- $limit = extCommonModel::getLicensePropertyValue('unlimitedParticipants');
- // fallback for older value.
- if($limit === '1') $limit = null;
- if($limit === '0') $limit = 3;
- return $limit;
- }
- /**
- * accept a conference invite.
- *
- * @param int $conferenceID
- * @param int $invitee
- * @return bool
- */
- public function acceptInvite($conferenceID, $invitee)
- {
- $this->dao->update(TABLE_IM_CONFERENCEINVITE)
- ->set('status')->eq('accepted')
- ->set('updatedDate')->eq(helper::now())
- ->where('conferenceID')->eq($conferenceID)
- ->andWhere('inviteeID')->eq($invitee)
- ->exec();
- return !dao::isError();
- }
- /**
- * reject a conference invite.
- *
- * @param int $conferenceID
- * @param int $invitee
- * @return bool
- */
- public function rejectInvite($conferenceID, $invitee)
- {
- $this->dao->update(TABLE_IM_CONFERENCEINVITE)
- ->set('status')->eq('rejected')
- ->set('updatedDate')->eq(helper::now())
- ->where('conferenceID')->eq($conferenceID)
- ->andWhere('inviteeID')->eq($invitee)
- ->exec();
- return !dao::isError();
- }
- /**
- * get pending invites.
- *
- * @param int $userID
- * @return array
- */
- public function getPendingInvites($userID)
- {
- return $this->dao->select('t1.*, t2.*')->from(TABLE_IM_CONFERENCEINVITE)->alias('t1')
- ->leftJoin(TABLE_IM_CONFERENCE)->alias('t2')->on('t1.conferenceID = t2.id')
- ->where('t1.inviteeID')->eq($userID)
- ->andWhere('t1.status')->eq('pending')
- ->andWhere('t2.status')->eq('open')
- ->fetchAll();
- }
- /**
- * get the jwt secret for jitsi meet authentication.
- *
- * @return string
- */
- public function getJwtSecret()
- {
- return $this->dao->select('value')->from(TABLE_CONFIG)
- ->where('owner')->eq('system')
- ->andWhere('module')->eq('jitsi')
- ->andWhere('section')->eq('jwt')
- ->andWhere('`key`')->eq('secret')
- ->fetch('value');
- }
- }
|