diff --git a/block_panopto.php b/block_panopto.php index 7e540a6..fc36ef0 100644 --- a/block_panopto.php +++ b/block_panopto.php @@ -78,7 +78,6 @@ public function instance_allow_config() { public function instance_config_save($data, $nolongerused = false) { if (!empty($data->course)) { - panopto_data::set_panopto_course_id($this->page->course->id, $data->course); // Add roles mapping. $publisherroles = (isset($data->publisher)) ? $data->publisher : array(); $creatorroles = (isset($data->creator)) ? $data->creator : array(); @@ -90,8 +89,16 @@ public function instance_config_save($data, $nolongerused = false) { ); $panoptodata = new panopto_data($this->page->course->id); + + // Manually overwrite the sessiongroupid on this Panopto_Data instance so we can test provision the attempted new mapping. If the provision fails do not allow it. + // Provision could fail if the user attempts to provision a personal folder. + $panoptodata->sessiongroupid = $data->course; + $provisioninginfo = $panoptodata->get_provisioning_info(); - $panoptodata->provision_course($provisioninginfo, false); + $provisioneddata = $panoptodata->provision_course($provisioninginfo, false); + if (isset($provisioneddata->Id) && !empty($provisioneddata->Id)) { + panopto_data::set_panopto_course_id($this->page->course->id, $data->course); + } } } diff --git a/db/upgrade.php b/db/upgrade.php index d749f25..7554f47 100644 --- a/db/upgrade.php +++ b/db/upgrade.php @@ -24,8 +24,6 @@ defined('MOODLE_INTERNAL') || die(); -require_once(dirname(__FILE__) . '/../lib/panopto_data.php'); - /** * Upgrades Panopto for xmldb * @@ -260,5 +258,16 @@ function xmldb_block_panopto_upgrade($oldversion = 0) { upgrade_block_savepoint(true, 2017110600, 'panopto'); } + if ($oldversion < 2018030200) { + + // Since this toggle got changed/removed for a select, get the old value and if it's set then set the new feature as appropriate. + if (get_config('block_panopto', 'prefix_new_folder_names')) { + set_config('folder_name_style', 'combination', 'block_panopto'); + } + + // Panopto savepoint reached. + upgrade_block_savepoint(true, 2018030200, 'panopto'); + } + return true; } diff --git a/lang/en/block_panopto.php b/lang/en/block_panopto.php index d5d3f24..e252098 100644 --- a/lang/en/block_panopto.php +++ b/lang/en/block_panopto.php @@ -31,6 +31,7 @@ $string['attempted_import_course_id'] = 'Moodle Id of the source import course'; $string['attempted_panopto_server'] = 'Attempted Panopto Server'; $string['attempt_provision_course'] = 'Attempting to provision a Panopto folder with an External Id of: {$a}.'; +$string['attempted_provisioning_personal_folder'] = 'Attempted to provision to a personal folder, this is not currently an action supported by Panopto. Please map the course to a different folder through the block instance config and try reprovisioning.'; $string['attempt_sync_user'] = 'Attempting to sync a user with and Id of {$a} to Panopto.'; $string['attempt_sync_user_server'] = 'Target server of the attempted sync is {$a}.'; $string['api_manager_unavailable'] = 'Unable to create the {$a} manager api client! (Is the Panopto server available, if so are the instance name and application key correct?)'; @@ -80,8 +81,12 @@ $string['block_panopto_auto_provision_desc'] = 'Enable this option to automatically provision a Panopto course folder when a course is created.'; $string['block_panopto_async_tasks'] = 'Asynchronous sync tasks'; $string['block_panopto_async_tasks_desc'] = 'Enable this option to allow the enrolment, unenrolment, and delete user tasks to happen asynchronously (may have a short delay before running)'; -$string['block_panopto_prefix_new_folder_shortnames'] = 'Prefix new Panopto folder display names with the Moodle course\'s shortname'; -$string['block_panopto_prefix_new_folder_shortnames_desc'] = 'Enable this option to add the provisioned course shortname to the beginning of newly made Panopto folder\'s display name.'; +$string['block_panopto_folder_name_style'] = 'Panopto folder name style'; +$string['block_panopto_folder_name_style_desc'] = 'Use this option to select which visual name style you wish to have for your new Panopto folders'; +$string['block_panopto_wsdl_proxy_host'] = 'WSDL proxy host'; +$string['block_panopto_wsdl_proxy_host_desc'] = 'The host address used as a proxy for any Panopto service WSDL. (Optional)'; +$string['block_panopto_wsdl_proxy_port'] = 'WSDL proxy port'; +$string['block_panopto_wsdl_proxy_port_desc'] = 'The port used as a proxy for any Panopto service WSDL. (Optional)'; $string['completed_recordings'] = 'Completed Recordings'; $string['course'] = 'Course'; $string['course_name'] = 'Course Name'; @@ -93,7 +98,7 @@ $string['download_recorder'] = 'Download Recorder'; $string['error_retrieving'] = 'Error retrieving Panopto course folder.'; $string['no_access'] = 'You do not have access to view this Panopto folder.'; -$string['existing_course'] = 'Select an existing Panopto folder:'; +$string['existing_course'] = 'Select an existing Panopto folder that is not currently mapped to another course:'; $string['fetching_content'] = 'Fetching Panopto Content...'; $string['folder_not_found_error'] = 'The folder currenty provisioned to the target Moodle course on the Panopto server could not be found, was it deleted? Provisioning will continue by linking to the default Moodle folder or creating one if it does not already exist.'; $string['get_provisioning_info'] = 'Attempting to get provisioning info for a course with the Moodle Id: {$a}.'; @@ -108,6 +113,9 @@ $string['live_sessions'] = 'Live Sessions'; $string['missing_required_version'] = 'API call failed to return a response, this could be because the Panopto server you attempted to use does not meet the minimum required version to support this version of the Moodle Panopto Block. This could also be caused by the server being unavailable.'; $string['moodle_course_not_exist'] = 'Moving row to old foldermap, course did not exist inside Moodle.'; +$string['name_style_shortname'] = '[short name]'; +$string['name_style_fullname'] = '[full name]'; +$string['name_style_combination'] = '[short name]: [full name]'; $string['no_completed_recordings'] = 'No Completed Recordings'; $string['no_course_selected'] = 'No Panopto course folder selected'; $string['no_creators'] = 'No creators.'; diff --git a/lib/AuthManagement/AuthManagementWsdlClass.php b/lib/AuthManagement/AuthManagementWsdlClass.php index c20dbe7..af804c0 100644 --- a/lib/AuthManagement/AuthManagementWsdlClass.php +++ b/lib/AuthManagement/AuthManagementWsdlClass.php @@ -25,7 +25,7 @@ class AuthManagementWsdlClass extends stdClass implements ArrayAccess,Iterator,C * Constant to define the default WSDL URI * @var string */ - const VALUE_WSDL_URL = 'https://demo.hosted.panopto.com/Panopto/PublicAPI/4.2/Auth.svc?wsdl'; + const VALUE_WSDL_URL = 'https://demo.hosted.panopto.com/Panopto/PublicAPI/4.2/Auth.svc?singlewsdl'; /** * Option key to define WSDL login * @var string diff --git a/lib/AuthManagement/sample-authmanagement.php b/lib/AuthManagement/sample-authmanagement.php index d4dd836..c17b1ae 100644 --- a/lib/AuthManagement/sample-authmanagement.php +++ b/lib/AuthManagement/sample-authmanagement.php @@ -1,6 +1,6 @@ * @version 20150429-01 @@ -24,7 +24,7 @@ * * Here is below an example of how you can set the array: * $wsdl = array(); - * $wsdl[AuthManagementWsdlClass::WSDL_URL] = 'https://demo.hosted.panopto.com/Panopto/PublicAPI/4.2/Auth.svc?wsdl'; + * $wsdl[AuthManagementWsdlClass::WSDL_URL] = 'https://demo.hosted.panopto.com/Panopto/PublicAPI/4.2/Auth.svc?singlewsdl'; * $wsdl[AuthManagementWsdlClass::WSDL_CACHE_WSDL] = WSDL_CACHE_NONE; * $wsdl[AuthManagementWsdlClass::WSDL_TRACE] = true; * $wsdl[AuthManagementWsdlClass::WSDL_LOGIN] = 'myLogin'; diff --git a/lib/SessionManagement/Session/Field/SessionManagementEnumSessionSortField.php b/lib/SessionManagement/Session/Field/SessionManagementEnumSessionSortField.php index 1e0ea8d..e689ee8 100644 --- a/lib/SessionManagement/Session/Field/SessionManagementEnumSessionSortField.php +++ b/lib/SessionManagement/Session/Field/SessionManagementEnumSessionSortField.php @@ -44,6 +44,11 @@ class SessionManagementEnumSessionSortField extends SessionManagementWsdlClass * @return string 'Relevance' */ const VALUE_RELEVANCE = 'Relevance'; + /** + * Constant for value 'Order' + * @return string 'Order' + */ + const VALUE_ORDER = 'Order'; /** * Return true if value is allowed * @uses SessionManagementEnumSessionSortField::VALUE_NAME @@ -51,12 +56,13 @@ class SessionManagementEnumSessionSortField extends SessionManagementWsdlClass * @uses SessionManagementEnumSessionSortField::VALUE_DURATION * @uses SessionManagementEnumSessionSortField::VALUE_STATE * @uses SessionManagementEnumSessionSortField::VALUE_RELEVANCE + * @uses SessionManagementEnumSessionSortField::VALUE_ORDER * @param mixed $_value value * @return bool true|false */ public static function valueIsValid($_value) { - return in_array($_value,array(SessionManagementEnumSessionSortField::VALUE_NAME,SessionManagementEnumSessionSortField::VALUE_DATE,SessionManagementEnumSessionSortField::VALUE_DURATION,SessionManagementEnumSessionSortField::VALUE_STATE,SessionManagementEnumSessionSortField::VALUE_RELEVANCE)); + return in_array($_value,array(SessionManagementEnumSessionSortField::VALUE_NAME,SessionManagementEnumSessionSortField::VALUE_DATE,SessionManagementEnumSessionSortField::VALUE_DURATION,SessionManagementEnumSessionSortField::VALUE_STATE,SessionManagementEnumSessionSortField::VALUE_RELEVANCE,SessionManagementEnumSessionSortField::VALUE_ORDER)); } /** * Method returning the class name diff --git a/lib/SessionManagement/SessionManagementWsdlClass.php b/lib/SessionManagement/SessionManagementWsdlClass.php index 884828f..1cd4086 100644 --- a/lib/SessionManagement/SessionManagementWsdlClass.php +++ b/lib/SessionManagement/SessionManagementWsdlClass.php @@ -25,7 +25,7 @@ class SessionManagementWsdlClass extends stdClass implements ArrayAccess,Iterato * Constant to define the default WSDL URI * @var string */ - const VALUE_WSDL_URL = 'https://demo.hosted.panopto.com/Panopto/PublicAPI/4.6/SessionManagement.svc?wsdl'; + const VALUE_WSDL_URL = 'https://demo.hosted.panopto.com/Panopto/PublicAPI/4.6/SessionManagement.svc?singlewsdl'; /** * Option key to define WSDL login * @var string diff --git a/lib/SessionManagement/sample-sessionmanagement.php b/lib/SessionManagement/sample-sessionmanagement.php index 04fba4b..6120cf7 100644 --- a/lib/SessionManagement/sample-sessionmanagement.php +++ b/lib/SessionManagement/sample-sessionmanagement.php @@ -1,6 +1,6 @@ * @version 20150429-01 @@ -24,7 +24,7 @@ * * Here is below an example of how you can set the array: * $wsdl = array(); - * $wsdl[SessionManagementWsdlClass::WSDL_URL] = 'https://demo.hosted.panopto.com/Panopto/PublicAPI/4.6/SessionManagement.svc?wsdl'; + * $wsdl[SessionManagementWsdlClass::WSDL_URL] = 'https://demo.hosted.panopto.com/Panopto/PublicAPI/4.6/SessionManagement.svc?singlewsdl'; * $wsdl[SessionManagementWsdlClass::WSDL_CACHE_WSDL] = WSDL_CACHE_NONE; * $wsdl[SessionManagementWsdlClass::WSDL_TRACE] = true; * $wsdl[SessionManagementWsdlClass::WSDL_LOGIN] = 'myLogin'; diff --git a/lib/UserManagement/sample-usermanagement.php b/lib/UserManagement/sample-usermanagement.php index 81d7865..6c8484f 100644 --- a/lib/UserManagement/sample-usermanagement.php +++ b/lib/UserManagement/sample-usermanagement.php @@ -1,6 +1,6 @@ * @version 20150429-01 @@ -24,7 +24,7 @@ * * Here is below an example of how you can set the array: * $wsdl = array(); - * $wsdl[UserManagementWsdlClass::WSDL_URL] = 'https://demo.hosted.panopto.com/Panopto/PublicAPI/4.6/UserManagement.svc?wsdl'; + * $wsdl[UserManagementWsdlClass::WSDL_URL] = 'https://demo.hosted.panopto.com/Panopto/PublicAPI/4.6/UserManagement.svc?singlewsdl'; * $wsdl[UserManagementWsdlClass::WSDL_CACHE_WSDL] = WSDL_CACHE_NONE; * $wsdl[UserManagementWsdlClass::WSDL_TRACE] = true; * $wsdl[UserManagementWsdlClass::WSDL_LOGIN] = 'myLogin'; diff --git a/lib/block_panopto_lib.php b/lib/block_panopto_lib.php index 91afccf..27469c9 100644 --- a/lib/block_panopto_lib.php +++ b/lib/block_panopto_lib.php @@ -24,6 +24,17 @@ // This can't be defined Moodle internal because it is called from Panopto to authorize login. +/** + * Send a Javascript alert to the window for the current user to see. + * + * @param string $alertmessage - the message the user is supposed to see. + */ +function panopto_alert_user($alertmessage) { + echo ''; +} + /** * Prepend the instance name to the Moodle course ID to create an external ID for Panopto Focus. * @@ -78,4 +89,27 @@ function panopto_validate_auth_code($payload, $authcode) { return (panopto_generate_auth_code($payload) == $authcode); } +/** + * takes an api url, then checks the Panopto config for proxy settings, and returns the relevant serviceparams object. + * + * @param string apiurl + */ +function generate_wsdl_service_params($apiurl) { + $serviceparams = array('wsdl_url' => $apiurl); + + // Check to see if the user set any proxy options + $proxyhost = get_config('block_panopto', 'wsdl_proxy_host'); + $proxyport = get_config('block_panopto', 'wsdl_proxy_port'); + + if (isset($proxyhost) && !empty($proxyhost)) { + $serviceparams['wsdl_proxy_host'] = $proxyhost; + } + + if (isset($proxyport) && !empty($proxyport)) { + $serviceparams['wsdl_proxy_port'] = $proxyport; + } + + return $serviceparams; +} + /* End of file block_panopto_lib.php */ diff --git a/lib/panopto_auth_soap_client.php b/lib/panopto_auth_soap_client.php index 16e9dba..de6c4c8 100644 --- a/lib/panopto_auth_soap_client.php +++ b/lib/panopto_auth_soap_client.php @@ -34,6 +34,7 @@ */ require_once(dirname(__FILE__) . '/AuthManagement/AuthManagementAutoload.php'); require_once(dirname(__FILE__) . '/panopto_data.php'); +require_once(dirname(__FILE__) . '/block_panopto_lib.php'); class panopto_auth_soap_client extends SoapClient { @@ -44,9 +45,19 @@ class panopto_auth_soap_client extends SoapClient { private $authparam; /** - * @var array $apiurl + * @var array $serviceparams the url used to get the service wsdl, as well as optional proxy options */ - private $apiurl; + private $serviceparams; + + /** + * @var AuthManagementServiceReport authmanagementservicereport object used to call the auth report service + */ + private $authmanagementservicereport; + + /** + * @var AuthManagementServiceGet authmanagementserviceget object used to call the auth get service + */ + private $authmanagementserviceget; /** * main constructor @@ -57,12 +68,15 @@ class panopto_auth_soap_client extends SoapClient { */ public function __construct($servername, $apiuseruserkey, $apiuserauthcode) { - // Instantiate SoapClient in WSDL mode. - // Set call timeout to 5 minutes. - $this->apiurl = 'https://'. $servername . '/Panopto/PublicAPI/4.2/Auth.svc?wsdl'; - // Cache web service credentials for all calls requiring authentication. - $this->authparam = new AuthManagementStructAuthenticationInfo($apiuserauthcode, null, $apiuseruserkey); + $this->authparam = new AuthManagementStructAuthenticationInfo( + $apiuserauthcode, + null, + $apiuseruserkey + ); + + $this->serviceparams = generate_wsdl_service_params('https://'. $servername . '/Panopto/PublicAPI/4.2/Auth.svc?singlewsdl'); + } /** @@ -70,11 +84,15 @@ public function __construct($servername, $apiuseruserkey, $apiuserauthcode) { */ public function get_server_version() { $returnvalue = false; - $authmanagementserviceget = new AuthManagementServiceGet(array('wsdl_url' => $this->apiurl)); - if ($authmanagementserviceget->GetServerVersion()) { - $returnvalue = $authmanagementserviceget->getResult()->GetServerVersionResult; + + if (!isset($this->authmanagementserviceget)) { + $this->authmanagementserviceget = new AuthManagementServiceGet($this->serviceparams); + } + + if ($this->authmanagementserviceget->GetServerVersion()) { + $returnvalue = $this->authmanagementserviceget->getResult()->GetServerVersionResult; } else { - panopto_data::print_log(print_r($authmanagementserviceget->getLastError(), true)); + panopto_data::print_log(print_r($this->authmanagementserviceget->getLastError(), true)); } return $returnvalue; } @@ -88,7 +106,10 @@ public function get_server_version() { public function report_integration_info($idprovidername, $moduleversion, $targetplatformversion) { $returnvalue = false; - $authmanagementservicereport = new AuthManagementServiceReport(array('wsdl_url' => $this->apiurl)); + if (!isset($this->authmanagementservicereport)) { + $this->authmanagementservicereport = new AuthManagementServiceReport($this->serviceparams); + } + $reportparams = new AuthManagementStructReportIntegrationInfo( $this->authparam, strval($idprovidername), @@ -96,10 +117,10 @@ public function report_integration_info($idprovidername, $moduleversion, $target strval($targetplatformversion) ); - if ($authmanagementservicereport->ReportIntegrationInfo($reportparams)) { + if ($this->authmanagementservicereport->ReportIntegrationInfo($reportparams)) { $returnvalue = true; } else { - $lasterror = $authmanagementservicereport->getLastError()['AuthManagementServiceReport::ReportIntegrationInfo']; + $lasterror = $this->authmanagementservicereport->getLastError()['AuthManagementServiceReport::ReportIntegrationInfo']; panopto_data::print_log(print_r($lasterror, true)); } diff --git a/lib/panopto_data.php b/lib/panopto_data.php index 1850276..105ca39 100644 --- a/lib/panopto_data.php +++ b/lib/panopto_data.php @@ -93,11 +93,6 @@ class panopto_data { */ public $uname; - /** - * @var int PAGE_SIZE size of the pages - */ - const PAGE_SIZE = 50; - /** * @var int $requireversion Panopto only supports versions of Moodle newer than v2.7(2014051200). */ @@ -108,6 +103,17 @@ class panopto_data { */ public static $requiredpanoptoversion = '5.4.0'; + /** + * @var string $requiredpanoptoversion Any block_panopto newer than 2017061000 will require a Panopto server to be at least this version to succeed. + */ + public static function getpossiblefoldernamestyles() { + return array( + 'fullname' => get_string('name_style_fullname', 'block_panopto'), + 'shortname' => get_string('name_style_shortname', 'block_panopto'), + 'combination' => get_string('name_style_combination', 'block_panopto') + ); + } + /** * main constructor * @@ -324,13 +330,22 @@ public function provision_course($provisioninginfo, $skipusersync) { } } } else { + + $provisionresponse = $courseinfo; // Give the user some basic info they can use to debug or send to AE. $courseinfo = new stdClass; $courseinfo->moodlecourseid = $this->moodlecourseid; $courseinfo->servername = $this->servername; $courseinfo->applicationkey = $this->applicationkey; - $courseinfo->missingrequiredversion = true; - $courseinfo->requiredpanoptoversion = self::$requiredpanoptoversion; + + // If the provisioning attempted to target a personal folder let the user know. + if ($provisionresponse === panopto_session_soap_client::PERSONAL_FOLDER_ERROR) { + $courseinfo->provisionedpersonalfolder = true; + } else { + // Currently the only other known failure from this state would be the Panopto server not being new enough. + $courseinfo->missingrequiredversion = true; + $courseinfo->requiredpanoptoversion = self::$requiredpanoptoversion; + } } } else { // Give the user some basic info they can use to debug or send to AE. @@ -411,10 +426,21 @@ public function get_provisioning_info() { } $provisioninginfo->fullname = ''; - if (get_config('block_panopto', 'prefix_new_folder_names')) { - $provisioninginfo->fullname .= $provisioninginfo->shortname . ': '; + + $selectednamestyle = get_config('block_panopto', 'folder_name_style'); + + switch ($selectednamestyle) { + case 'combination': + $provisioninginfo->fullname .= $provisioninginfo->shortname . ': ' . $provisioninginfo->longname; + break; + case 'shortname': + $provisioninginfo->fullname .= $provisioninginfo->shortname; + break; + case 'fullname': + default: + $provisioninginfo->fullname .= $provisioninginfo->longname; + break; } - $provisioninginfo->fullname .= $provisioninginfo->longname; } // Always set this, even in the case of an already existing folder we will overwrite the old Id with this one. @@ -538,11 +564,9 @@ public function get_folders_list() { // Update permissions so user can see everything they should. $this->sync_external_user($USER->id); - if (isset($this->sessiongroupid)) { - $this->ensure_session_manager(); + $this->ensure_session_manager(); - $ret = $this->sessionmanager->get_folders_list(); - } + $ret = $this->sessionmanager->get_folders_list(); return $ret; } @@ -689,13 +713,13 @@ public static function get_import_target_list($courseid) { /** * Get ongoing Panopto sessions for the currently mapped course. */ - public function get_session_list() { + public function get_session_list($sessionshavespecificorder) { $sessionlist = array(); if ($this->servername && $this->applicationkey && $this->sessiongroupid) { $this->ensure_session_manager(); } - $sessionlist = $this->sessionmanager->get_session_list($this->sessiongroupid); + $sessionlist = $this->sessionmanager->get_session_list($this->sessiongroupid, $sessionshavespecificorder); return $sessionlist; } @@ -1047,17 +1071,21 @@ public static function delete_panopto_relation($moodlecourseid, $movetoinactivet } /** - * Get list of available courses from db based on user's access level on course. + * Get list of available folders from db based on user's access level on course. Only get unmapped folders, and the current course folder */ public function get_course_options() { + global $DB; - $panoptocourses = $this->get_folders_list(); - if (!empty($panoptocourses)) { + $panoptofolders = $this->get_folders_list(); + if (!empty($panoptofolders)) { $options = array(); - foreach ($panoptocourses as $courseinfo) { - $options[$courseinfo->Id] = $courseinfo->Name; + foreach ($panoptofolders as $folderinfo) { + // Only add a folder to the course options if it is not already mapped to a course on moodle (unless its the current course) + if (!$DB->get_records('block_panopto_foldermap', array('panopto_id' => $folderinfo->Id)) || ($this->sessiongroupid === $folderinfo->Id)) { + $options[$folderinfo->Id] = $folderinfo->Name; + } } - } else if (isset($panoptocourses)) { + } else if (isset($panoptofolders)) { $options = array('Error' => array('-- No Courses Available --')); } else { $options = array('Error' => array('!! Unable to retrieve course list !!')); @@ -1145,7 +1173,8 @@ public static function build_and_assign_context_capability_to_roles($context, $r // Extract the existing capabilities that have been assigned for context, role and capability. foreach ($roles as $key => $roleid) { - if ($roleid & $DB->record_exists('role_capabilities', array('contextid'=>$context->id, 'roleid'=>$roleid, 'capability'=>$capability))) { + // Only query the DB if $roleid is not null + if ($roleid && $DB->record_exists('role_capabilities', array('contextid'=>$context->id, 'roleid'=>$roleid, 'capability'=>$capability))) { $existing[$roleid] = $capability; } } diff --git a/lib/panopto_session_soap_client.php b/lib/panopto_session_soap_client.php index 6fe2929..69899fb 100644 --- a/lib/panopto_session_soap_client.php +++ b/lib/panopto_session_soap_client.php @@ -33,6 +33,7 @@ require_once(dirname(__FILE__) . '/SessionManagement/SessionManagementAutoload.php'); require_once(dirname(__FILE__) . '/panopto_data.php'); +require_once(dirname(__FILE__) . '/block_panopto_lib.php'); class panopto_session_soap_client extends SoapClient { /** @@ -41,9 +42,9 @@ class panopto_session_soap_client extends SoapClient { private $authparam; /** - * @var array $apiurl url used by the soap wsdl. + * @var array $serviceparams the url used to get the service wsdl, as well as optional proxy options */ - private $apiurl; + private $serviceparams; /** * @var SessionManagementServiceAdd $sessionmanagementserviceadd soap service for add based calls @@ -65,6 +66,11 @@ class panopto_session_soap_client extends SoapClient { */ private $sessionmanagementserviceget; + /** + * @var string PERSONAL_FOLDER_ERROR const string to return when user attempted to provision/sync a personal folder. This action is not supported. + */ + const PERSONAL_FOLDER_ERROR = "TARGETED_PERSONAL_FOLDER"; + /** * main constructor * @@ -74,16 +80,14 @@ class panopto_session_soap_client extends SoapClient { */ public function __construct($servername, $apiuseruserkey, $apiuserauthcode) { - // Instantiate SoapClient in WSDL mode. - // Set call timeout to 5 minutes. - $this->apiurl = 'https://'. $servername . '/Panopto/PublicAPI/4.6/SessionManagement.svc?wsdl'; - // Cache web service credentials for all calls requiring authentication. $this->authparam = new SessionManagementStructAuthenticationInfo( $apiuserauthcode, null, $apiuseruserkey ); + + $this->serviceparams = generate_wsdl_service_params('https://'. $servername . '/Panopto/PublicAPI/4.6/SessionManagement.svc?singlewsdl'); } // Possibly unneeded since Moodle won't support multiple folders without behavior change. @@ -91,10 +95,9 @@ public function add_folder($foldername, $parentguids = null, $ispublic = false) $ret = false; if (!isset($this->sessionmanagementserviceadd)) { - $this->sessionmanagementserviceadd = new SessionManagementServiceAdd( - array('wsdl_url' => $this->apiurl) - ); + $this->sessionmanagementserviceadd = new SessionManagementServiceAdd($this->serviceparams); } + $folderparams = new SessionManagementStructAddFolder( $this->authparam, $foldername, @@ -115,9 +118,7 @@ public function provision_external_course_with_roles($fullname, $externalcoursei $ret = false; if (!isset($this->sessionmanagementserviceprovision)) { - $this->sessionmanagementserviceprovision = new SessionManagementServiceProvision( - array('wsdl_url' => $this->apiurl) - ); + $this->sessionmanagementserviceprovision = new SessionManagementServiceProvision($this->serviceparams); } $rolestoensure = array( @@ -138,7 +139,7 @@ public function provision_external_course_with_roles($fullname, $externalcoursei $retobj = $this->sessionmanagementserviceprovision->getResult(); $ret = $retobj->ProvisionExternalCourseWithRolesResult; } else { - panopto_data::print_log(print_r($this->sessionmanagementserviceprovision->getLastError(), true)); + $this->handle_provisioning_error('SessionManagementServiceProvision::ProvisionExternalCourseWithRoles'); } return $ret; @@ -148,9 +149,7 @@ public function set_external_course_access_for_roles($fullname, $externalcoursei $ret = false; if (!isset($this->sessionmanagementserviceset)) { - $this->sessionmanagementserviceset = new SessionManagementServiceSet( - array('wsdl_url' => $this->apiurl) - ); + $this->sessionmanagementserviceset = new SessionManagementServiceSet($this->serviceparams); } if (!is_array($folderids)) { @@ -179,7 +178,7 @@ public function set_external_course_access_for_roles($fullname, $externalcoursei // We do not support multiple folders per course in Moodle atm so we can assume 1 result. $ret = $retobj->SetExternalCourseAccessForRolesResult->Folder[0]; } else { - panopto_data::print_log(print_r($this->sessionmanagementserviceset->getLastError(), true)); + $this->handle_provisioning_error('SessionManagementServiceSet::SetExternalCourseAccessForRoles'); } return $ret; @@ -189,9 +188,7 @@ public function set_copied_external_course_access_for_roles($fullname, $external $ret = false; if (!isset($this->sessionmanagementserviceset)) { - $this->sessionmanagementserviceset = new SessionManagementServiceSet( - array('wsdl_url' => $this->apiurl) - ); + $this->sessionmanagementserviceset = new SessionManagementServiceSet($this->serviceparams); } if (!is_array($folderids)) { @@ -228,9 +225,7 @@ public function set_copied_external_course_access_for_roles($fullname, $external public function get_folders_by_id($folderids) { $ret = false; if (!isset($this->sessionmanagementserviceget)) { - $this->sessionmanagementserviceget = new SessionManagementServiceGet( - array('wsdl_url' => $this->apiurl) - ); + $this->sessionmanagementserviceget = new SessionManagementServiceGet($this->serviceparams); } if (!is_array($folderids)) { @@ -262,9 +257,7 @@ public function get_folders_by_external_id($folderids) { $ret = false; if (!isset($this->sessionmanagementserviceget)) { - $this->sessionmanagementserviceget = new SessionManagementServiceGet( - array('wsdl_url' => $this->apiurl) - ); + $this->sessionmanagementserviceget = new SessionManagementServiceGet($this->serviceparams); } if (!is_array($folderids)) { @@ -292,9 +285,7 @@ public function get_folders_list() { $result = false; if (!isset($this->sessionmanagementserviceget)) { - $this->sessionmanagementserviceget = new SessionManagementServiceGet( - array('wsdl_url' => $this->apiurl) - ); + $this->sessionmanagementserviceget = new SessionManagementServiceGet($this->serviceparams); } $resultsperpage = 1000; @@ -371,21 +362,20 @@ public function get_folders_list() { return $result; } - public function get_session_list($folderid) { + public function get_session_list($folderid, $sessionshavespecificorder) { $ret = false; if (!isset($this->sessionmanagementserviceget)) { - $this->sessionmanagementserviceget = new SessionManagementServiceGet( - array('wsdl_url' => $this->apiurl) - ); + $this->sessionmanagementserviceget = new SessionManagementServiceGet($this->serviceparams); } $startdate = null; $enddate = null; $pagination = new SessionManagementStructPagination(100, 0); $remoterecorderid = null; - $sortby = SessionManagementEnumSessionSortField::VALUE_DATE; - $sortincreasing = false; + + $sortby = $sessionshavespecificorder ? SessionManagementEnumSessionSortField::VALUE_ORDER : SessionManagementEnumSessionSortField::VALUE_DATE; + $sortincreasing = $sessionshavespecificorder; $states = new SessionManagementStructArrayOfSessionState( array( SessionManagementEnumSessionState::VALUE_BROADCASTING, @@ -425,9 +415,7 @@ public function get_recorder_download_urls() { $ret = false; if (!isset($this->sessionmanagementserviceget)) { - $this->sessionmanagementserviceget = new SessionManagementServiceGet( - array('wsdl_url' => $this->apiurl) - ); + $this->sessionmanagementserviceget = new SessionManagementServiceGet($this->serviceparams); } if ($this->sessionmanagementserviceget->GetRecorderDownloadUrls()) { @@ -438,6 +426,21 @@ public function get_recorder_download_urls() { return $ret; } + + private function handle_provisioning_error($functionkey) { + $lasterror = $this->sessionmanagementserviceset->getLastError()[$functionkey]; + + $lasterrormessage = $lasterror->getMessage(); + + // Parsing error message to see if the target was a personal. + if (strpos($lasterrormessage, 'provision personal folder') !== false) { + // Making ret a const since the folder was invalid. + $ret = self::PERSONAL_FOLDER_ERROR; + panopto_alert_user(get_string('attempted_provisioning_personal_folder', 'block_panopto')); + } + + panopto_data::print_log($lasterrormessage); + } } /* End of file panopto_user_soap_client.php */ diff --git a/lib/panopto_user_soap_client.php b/lib/panopto_user_soap_client.php index 03b82ea..18eb6a7 100644 --- a/lib/panopto_user_soap_client.php +++ b/lib/panopto_user_soap_client.php @@ -33,6 +33,7 @@ require_once(dirname(__FILE__) . '/UserManagement/UserManagementAutoload.php'); require_once(dirname(__FILE__) . '/panopto_data.php'); +require_once(dirname(__FILE__) . '/block_panopto_lib.php'); class panopto_user_soap_client extends SoapClient { /** @@ -41,9 +42,24 @@ class panopto_user_soap_client extends SoapClient { public $authparam; /** - * @var array $apiurl + * @var array $serviceparams the url used to get the service wsdl, as well as optional proxy options */ - private $apiurl; + private $serviceparams; + + /** + * @var UserManagementServiceSync object used to call the user sync service + */ + private $usermanagementservicesync; + + /** + * @var UserManagementServiceGet object used to call the user get service + */ + private $usermanagementserviceget; + + /** + * @var UserManagementServiceCreate object used to call the user create service + */ + private $usermanagementservicecreate; /** * main constructor @@ -54,12 +70,13 @@ class panopto_user_soap_client extends SoapClient { */ public function __construct($servername, $apiuseruserkey, $apiuserauthcode) { - // Instantiate SoapClient in WSDL mode. - // Set call timeout to 5 minutes. - $this->apiurl = 'https://'. $servername . '/Panopto/PublicAPI/4.6/UserManagement.svc?wsdl'; - // Cache web service credentials for all calls requiring authentication. - $this->authparam = new UserManagementStructAuthenticationInfo($apiuserauthcode, null, $apiuseruserkey); + $this->authparam = new UserManagementStructAuthenticationInfo( + $apiuserauthcode, + null, + $apiuseruserkey); + + $this->serviceparams = generate_wsdl_service_params('https://'. $servername . '/Panopto/PublicAPI/4.6/UserManagement.svc?singlewsdl'); } /** @@ -72,7 +89,12 @@ public function __construct($servername, $apiuseruserkey, $apiuserauthcode) { * @param boolean $sendemailnotifications whether user gets emails from Panopto updates */ public function sync_external_user($firstname, $lastname, $email, $externalgroupids, $sendemailnotifications = false) { - $usermanagementsync = new UserManagementServiceSync(array('wsdl_url' => $this->apiurl)); + + + if (!isset($this->usermanagementservicesync)) { + $this->usermanagementservicesync = new UserManagementServiceSync($this->serviceparams); + } + $syncparamsobject = new UserManagementStructSyncExternalUser( $this->authparam, $firstname, @@ -83,25 +105,29 @@ public function sync_external_user($firstname, $lastname, $email, $externalgroup ); // Returns false if the call failed. - if (!$usermanagementsync->SyncExternalUser($syncparamsobject)) { - panopto_data::print_log(print_r($usermanagementsync->getLastError(), true)); + if (!$this->usermanagementservicesync->SyncExternalUser($syncparamsobject)) { + panopto_data::print_log(print_r($this->usermanagementservicesync->getLastError(), true)); } } public function get_user_by_key($userkey) { $result = false; - $usermanagementserviceget = new UserManagementServiceGet(array('wsdl_url' => $this->apiurl)); + + if (!isset($this->usermanagementserviceget)) { + $this->usermanagementserviceget = new UserManagementServiceGet($this->serviceparams); + } + $getuserbykeyparams = new UserManagementStructGetUserByKey( $this->authparam, $userkey ); // Returns false if the call failed. - if ($usermanagementserviceget->GetUserByKey($getuserbykeyparams)) { - $result = $usermanagementserviceget->getResult(); + if ($this->usermanagementserviceget->GetUserByKey($getuserbykeyparams)) { + $result = $this->usermanagementserviceget->getResult(); panopto_data::print_log(print_r($result, true)); } else { - panopto_data::print_log(print_r($usermanagementserviceget->getLastError(), true)); + panopto_data::print_log(print_r($this->usermanagementserviceget->getLastError(), true)); } return $result; @@ -110,7 +136,11 @@ public function get_user_by_key($userkey) { public function create_user($email, $emailsessionnotifications, $firstname, $groupmemberships, $lastname, $systemrole, $userbio, $userid, $userkey, $usersettingsurl, $password) { $result = false; - $usermanagementcreate = new UserManagementServiceCreate(array('wsdl_url' => $this->apiurl)); + + if (!isset($this->usermanagementservicecreate)) { + $this->usermanagementservicecreate = new UserManagementServiceCreate($this->serviceparams); + } + $decoratedgroupmemberships = new UserManagementStructArrayOfguid($groupmemberships); $userparamobject = new UserManagementStructUser( $email, @@ -132,10 +162,10 @@ public function create_user($email, $emailsessionnotifications, $firstname, $gro ); // Returns false if the call failed. - if ($usermanagementcreate->CreateUser($createuserparams)) { - $result = $usermanagementcreate->getResult(); + if ($this->usermanagementservicecreate->CreateUser($createuserparams)) { + $result = $this->usermanagementservicecreate->getResult(); } else { - panopto_data::print_log(print_r($usermanagementcreate->getLastError(), true)); + panopto_data::print_log(print_r($this->usermanagementservicecreate->getLastError(), true)); } return $result; diff --git a/panopto_content.php b/panopto_content.php index 6ccea8a..cdeeafa 100644 --- a/panopto_content.php +++ b/panopto_content.php @@ -78,14 +78,16 @@ // Get all Completed. - $sessionlist = $panoptodata->get_session_list(); + $sessionlist = $panoptodata->get_session_list($courseinfo->DeliveriesHaveSpecifiedOrder); $livesessions = array(); if (is_array($sessionlist) && !empty($sessionlist)) { foreach ($sessionlist as $sessionobj) { - $sessionvars = get_object_vars($sessionobj); - if ($sessionobj->IsBroadcast && empty($sessionobj->Duration)) { + // If the session is a live broadcast from the Windows/Mac Recorder or Remote Recorder check if its live + $islivesession = $sessionobj->State === 'Broadcasting'; + + if ($islivesession) { $livesessions[] = $sessionobj; } else if (!empty($sessionobj->Duration)) { $completeddeliveries[] = $sessionobj; @@ -184,11 +186,10 @@ // This does not consider roles. $isteacheroradmin = has_capability('moodle/course:update', $context); - $hascreatoraccess = has_capability('block/panopto:provision_aspublisher', $context, $USER->id) || - has_capability('block/panopto:provision_asteacher', $context, $USER->id); + $hascreatoraccess = has_capability('block/panopto:provision_asteacher', $context, $USER->id); // Settings link can only be viewed by Teachers, Admins. If the proper setting is enabled, any creators can also view the link. - if ($isteacheroradmin || (get_config('block_panopto', 'any_creator_can_view_folder_settings') && $hascreatoraccess)) { + if ($hascreatoraccess && ($isteacheroradmin || get_config('block_panopto', 'any_creator_can_view_folder_settings'))) { $content->text .= "