PageRenderTime 68ms CodeModel.GetById 37ms RepoModel.GetById 0ms app.codeStats 0ms

/tine20/Webconference/Controller/BigBlueButton.php

https://gitlab.com/rsilveira1987/Expresso
PHP | 268 lines | 166 code | 25 blank | 77 comment | 31 complexity | fdb09cd36499183788b6e3159bf9fac4 MD5 | raw file
  1. <?php
  2. /**
  3. * Controller for webconference
  4. * @package Webconference
  5. * @subpackage Controller
  6. * @license http://www.gnu.org/licenses/agpl.html AGPL Version 3
  7. * @author Edgar de Lucca <edgar.lucca@serpro.gov.br>, Marcelo Teixeira <marcelo.teixeira@serpro.gov.br>
  8. * @copyright Copyright (c) 2012 Metaways Infosystems GmbH (http://www.metaways.de)
  9. *
  10. */
  11. define('MODERATOR_PW', 'moderatorpw');
  12. define('ATTENDEE_PW', 'attendeepw');
  13. class Webconference_Controller_BigBlueButton extends Tinebase_Controller_Abstract {
  14. protected $_backend;
  15. /**
  16. * the constructor
  17. *
  18. * don't use the constructor. use the singleton
  19. */
  20. private function __construct() {
  21. $this->_backend = Webconference_Backend::factory(Webconference_Backend::BIGBLUEBUTTONAPI);
  22. }
  23. /**
  24. * holds the instance of the singleton
  25. *
  26. * @var Webconference_Controller_BigBlueButton
  27. */
  28. private static $_instance = NULL;
  29. /**
  30. * the singleton pattern
  31. *
  32. * @return Webconference_Controller_BigBlueButton
  33. */
  34. public static function getInstance() {
  35. if (self::$_instance === NULL) {
  36. self::$_instance = new Webconference_Controller_BigBlueButton();
  37. }
  38. return self::$_instance;
  39. }
  40. private function _getAccountId($_email){
  41. try{
  42. return Tinebase_User::getInstance()->getUserByProperty('accountEmailAddress', $_email)->accountId;
  43. } catch (Exception $e){
  44. return null;
  45. }
  46. }
  47. /**
  48. * generates a randomstrings of given length
  49. *
  50. * @param int $_length
  51. */
  52. public static function getRandomString($_length) {
  53. $chars = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
  54. $randomString = '';
  55. for ($i = 0; $i < (int) $_length; $i++) {
  56. $randomString .= $chars[mt_rand(1, strlen($chars)) - 1];
  57. }
  58. return $randomString;
  59. }
  60. /**
  61. * Checks if the url is online or not.
  62. * Used to check the webconference link before show the page to the user.
  63. *
  64. * @param string $url
  65. * @return array
  66. * @todo Improve the way of checking the url
  67. */
  68. public function checkUrl($url) {
  69. $online = false;
  70. ini_set("default_socket_timeout", "05");
  71. set_time_limit(5);
  72. $f = fopen($url, "r");
  73. $r = fread($f, 1000);
  74. fclose($f);
  75. if (strlen($r) > 1){
  76. $online = true;
  77. }
  78. return $online;
  79. }
  80. public function getLogoutUrl($protocol) {
  81. $host = $_SERVER['HTTP_HOST'];
  82. $base = substr($_SERVER['REQUEST_URI'], 0, strrpos($_SERVER['REQUEST_URI'], '/'));
  83. return $protocol.'//'.$host.$base.'/Webconference/views/logoutPage.html';
  84. }
  85. private function _getLogoutUrl($protocol) {
  86. $host = $_SERVER['HTTP_HOST'];
  87. $base = substr($_SERVER['REQUEST_URI'], 0, strrpos($_SERVER['REQUEST_URI'], '/'));
  88. return $protocol.'//'.$host.$base.'/Webconference/views/logoutPage.html';
  89. }
  90. private function _getBigBlueButtonConfigBalance() {
  91. $data = Webconference_Controller_Config::getInstance()->getAll();
  92. $quant = 1;
  93. $bbb = null;
  94. foreach ($data as $conf){
  95. $meetings = $this->_backend->getMeetings($conf->url, $conf->salt);
  96. if ($meetings->returncode == 'SUCCESS' && $meetings->messageKey == 'noMeetings'){
  97. return $conf;
  98. }
  99. $meetingsId = array();
  100. if ($meetings) {
  101. foreach ($meetings as $meeting){
  102. $meetingId = (String)$meeting["meetingID"];
  103. $hasBeenForciblyEnded = (String)$meeting["hasBeenForciblyEnded"];
  104. if ($hasBeenForciblyEnded == "true"){
  105. continue;
  106. }
  107. array_push($meetingsId, $meetingId);
  108. }
  109. }
  110. $perc = ( count($meetingsId) / $conf->limit_room);
  111. if ($perc < 1 && $perc < $quant){
  112. $quant = $perc;
  113. $bbb = $conf;
  114. }
  115. }
  116. return $bbb;
  117. }
  118. /**
  119. * This method creates a new meeting
  120. *
  121. * @return String -- URL of the meeting
  122. */
  123. public function createMeeting($userName, $meetingID, $title, $protocol){
  124. $translation = Tinebase_Translation::getTranslation('Webconference');
  125. $logoutURL = $this->_getLogoutUrl($protocol);
  126. $config = $this->_getBigBlueButtonConfigBalance();
  127. if ($config == null){
  128. throw new Tinebase_Exception_NotFound($translation->_('ERROR (no webconference server available or the room limit has been reached)'));
  129. }
  130. if ((!isset($title)) || (trim($title) == ""))
  131. {
  132. $title = $userName . date(" H:i:s d/m/Y");
  133. }
  134. $welcomeString = sprintf($translation->_("Welcome to the Webconference %s by %s"), $title, $userName);
  135. $result = $this->_backend->createMeeting($title, $meetingID, $welcomeString, MODERATOR_PW, ATTENDEE_PW, $config->salt, $config->url, $logoutURL);
  136. if (!$result) {
  137. throw new Tinebase_Exception_NotFound($translation->_('ERROR (the webconference server is unreachable)'));
  138. }
  139. if ($result->returncode == 'FAILED') {
  140. throw new Tinebase_Exception_NotFound(sprintf($translation->_("ERROR (%s): %s"), $result->messageKey, $result->message));
  141. }
  142. //retornar o config_id e o meetingID
  143. return $config->id;
  144. }
  145. public function joinURL($meetingID, $userName, $userEmail, $role, $configId){
  146. $config = Webconference_Controller_Config::getInstance()->get($configId);
  147. switch ($role){
  148. case "MODERATOR":
  149. $PW = MODERATOR_PW;
  150. break;
  151. case "ATTENDEE":
  152. $PW = ATTENDEE_PW;
  153. break;
  154. }
  155. $configTokenXML = NULL;
  156. if (Tinebase_Core::getUser()->hasRight('Webconference', Webconference_Acl_Rights::SHARED_DESKTOP)){
  157. $result = $this->setShareDesktop($config->salt, $config->url, $meetingID);
  158. if ($result != NULL & $result->returncode == 'SUCCESS'){
  159. $configTokenXML = $result->configToken;
  160. }
  161. }
  162. $roomURL = $this->_backend->joinURL($meetingID, $userName, $PW, $config->salt, $config->url, $configTokenXML);
  163. return $roomURL;
  164. }
  165. private function setShareDesktop($salt, $url, $meetingID) {
  166. $result = NULL;
  167. $xml = $this->_backend->getDefaultConfigXML($salt, $url);
  168. $isShareDesktop = false;
  169. if ($xml != NULL){
  170. foreach ($xml->modules->module as $module){
  171. if ($module->attributes()->name == 'DeskShareModule'){
  172. $isShareDesktop = $module['showButton'] == 'true';
  173. $module['showButton'] = 'true';
  174. }
  175. }
  176. if (!$isShareDesktop){
  177. $result = $this->_backend->setConfigXML($meetingID, $salt, $url, $xml);
  178. }
  179. }
  180. return $result;
  181. }
  182. /*This method check the BigBlueButton server to see if the meeting is running (i.e. there is someone in the meeting)
  183. *
  184. *@param roomName -- the unique meeting identifier used to store the meeting in the bigbluebutton server
  185. *
  186. *@return A boolean of true if the meeting is running and false if it is not running
  187. */
  188. public function isMeetingActive($_meetingID, $_configId)
  189. {
  190. $config = Webconference_Controller_Config::getInstance()->get($_configId);
  191. return $this->_backend->getMeetingIsActive($_meetingID, MODERATOR_PW, $config->url, $config->salt);
  192. }
  193. /**
  194. * This method calls end meeting on the specified meeting in the bigbluebutton server.
  195. *
  196. * @param roomName -- the unique meeting identifier used to store the meeting in the bigbluebutton server
  197. * @param moderatorPassword -- the moderator password of the meeting
  198. * @return
  199. * - Null if the server is unreachable
  200. * - An array containing a returncode, messageKey, message.
  201. */
  202. public function endMeeting($roomID) {
  203. $room = Webconference_Controller_Room::getInstance()->get($roomID);
  204. $config = Webconference_Controller_Config::getInstance()->get($room->wconf_config_id);
  205. return $this->_backend->endMeeting($room->room_name, MODERATOR_PW, $config->url, $config->salt);
  206. }
  207. /**
  208. * This method calls getMeetings on the bigbluebutton server, then calls getMeetingInfo for each meeting and concatenates the result.
  209. *
  210. * @return
  211. * - Null if the server is unreachable
  212. * - If FAILED then returns an array containing a returncode, messageKey, message.
  213. * - If SUCCESS then returns an array of all the meetings. Each element in the array is an array containing a meetingID,
  214. moderatorPW, attendeePW, hasBeenForciblyEnded, running.
  215. */
  216. public function getMeetings() {
  217. $servers = Webconference_Controller_Config::getInstance()->getAll();
  218. $data = array();
  219. foreach ($servers as $server){
  220. try {
  221. $dataTemp = $this->_backend->getMeetingsArray($server->url, $server->salt);
  222. } catch (Exception $exc) {
  223. $dataTemp = array("ERROR"=>$exc->getMessage());
  224. }
  225. array_push($data, array($server->url=>$dataTemp));
  226. }
  227. return $data;
  228. }
  229. /**
  230. * This method returns an array of the attendees in the specified meeting.
  231. *
  232. * @param roomName -- the unique meeting identifier used to store the meeting in the bigbluebutton server
  233. * @param moderatorPassword -- the moderator password of the meeting
  234. * @return
  235. * - Null if the server is unreachable.
  236. * - If FAILED, returns an array containing a returncode, messageKey, message.
  237. * - If SUCCESS, returns an array of array containing the userID, fullName, role of each attendee
  238. */
  239. public function getRoomUsers($_meetingID, $_configId) {
  240. $config = Webconference_Controller_Config::getInstance()->get($_configId);
  241. return $this->_backend->getUsers($_meetingID, MODERATOR_PW, $config->url, $config->salt);
  242. }
  243. }